cursor+deepseek实现完整的俄罗斯方块小游戏

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>俄罗斯方块</title><style>body {margin: 0;display: flex;justify-content: center;align-items: center;height: 100vh;background: #333;color: white;font-family: Arial, sans-serif;}.game-container {display: flex;gap: 20px;}canvas {border: 2px solid #fff;}.info-panel {width: 150px;}.controls {margin-top: 20px;}.controls button {padding: 10px 20px;margin: 5px;font-size: 16px;cursor: pointer;}</style>
</head>
<body><div class="game-container"><canvas id="tetris" width="300" height="600"></canvas><div class="info-panel"><h2>俄罗斯方块</h2><p>分数: <span id="score">0</span></p><p>等级: <span id="level">1</span></p><p>下一个:</p><canvas id="nextPiece" width="120" height="120"></canvas><div class="controls"><button id="startBtn">开始游戏</button><button id="pauseBtn" disabled>暂停</button><button id="restartBtn" disabled>重新开始</button></div></div></div><script>const canvas = document.getElementById('tetris');const ctx = canvas.getContext('2d');const nextCanvas = document.getElementById('nextPiece');const nextCtx = nextCanvas.getContext('2d');const scoreElement = document.getElementById('score');const levelElement = document.getElementById('level');const ROW = 20;const COL = 10;const SQ = 30;const VACANT = 'black';const SPEED = 500;const LINES_PER_LEVEL = 10;// 方块形状const Z = [[[1,1,0],[0,1,1],[0,0,0]],[[0,0,1],[0,1,1],[0,1,0]]];const S = [[[0,1,1],[1,1,0],[0,0,0]],[[1,0,0],[1,1,0],[0,1,0]]];const T = [[[1,1,1],[0,1,0],[0,0,0]]],O = [[[1,1],[1,1]]],L = [[[1,0,0],[1,1,1],[0,0,0]]],I = [[[1,1,1,1]]],J = [[[0,0,1],[1,1,1],[0,0,0]]];const PIECES = [[Z, 'red'],[S, 'green'],[T, 'yellow'],[O, 'blue'],[L, 'purple'],[I, 'cyan'],[J, 'orange']];let board = [];let score = 0;let level = 1;let lines = 0;let dropStart = Date.now();let piece;let nextPiece;let isPaused = false;let isRunning = false;let rAF;// 初始化游戏板function initBoard() {for(let r = 0; r < ROW; r++) {board[r] = [];for(let c = 0; c < COL; c++) {board[r][c] = VACANT;}}}// 绘制方块function drawSquare(x, y, color) {ctx.fillStyle = color;ctx.fillRect(x*SQ, y*SQ, SQ, SQ);ctx.strokeStyle = '#333';ctx.strokeRect(x*SQ, y*SQ, SQ, SQ);}// 绘制游戏板function drawBoard() {for(let r = 0; r < ROW; r++) {for(let c = 0; c < COL; c++) {drawSquare(c, r, board[r][c]);}}}// 方块类class Piece {constructor(tetromino, color) {this.tetromino = tetromino;this.color = color;this.tetrominoN = 0;this.activeTetromino = this.tetromino[this.tetrominoN];this.x = 3;this.y = -2;}draw() {for(let r = 0; r < this.activeTetromino.length; r++) {for(let c = 0; c < this.activeTetromino.length; c++) {if(this.activeTetromino[r][c]) {drawSquare(this.x + c, this.y + r, this.color);}}}}unDraw() {for(let r = 0; r < this.activeTetromino.length; r++) {for(let c = 0; c < this.activeTetromino.length; c++) {if(this.activeTetromino[r][c]) {drawSquare(this.x + c, this.y + r, VACANT);}}}}moveDown() {if(!this.collision(0, 1, this.activeTetromino)) {this.unDraw();this.y++;this.draw();} else {if(this.y < 0) {gameOver();return;}this.lock();piece = nextPiece;nextPiece = randomPiece();drawNextPiece();}}moveLeft() {if(!this.collision(-1, 0, this.activeTetromino)) {this.unDraw();this.x--;this.draw();}}moveRight() {if(!this.collision(1, 0, this.activeTetromino)) {this.unDraw();this.x++;this.draw();}}rotate() {if(this.y < 0) {return;}let nextPattern = this.tetromino[(this.tetrominoN + 1) % this.tetromino.length];let kick = 0;if(this.collision(0, 0, nextPattern)) {if(this.x > COL/2) {kick = -1;} else {kick = 1;}if(!this.collision(kick, 0, nextPattern)) {this.x += kick;} else {return;}}this.unDraw();this.tetrominoN = (this.tetrominoN + 1) % this.tetromino.length;this.activeTetromino = this.tetromino[this.tetrominoN];this.draw();}collision(x, y, piece) {for(let r = 0; r < piece.length; r++) {for(let c = 0; c < piece.length; c++) {if(!piece[r][c]) continue;let newX = this.x + c + x;let newY = this.y + r + y;if(newX < 0 || newX >= COL || newY >= ROW) {return true;}if(newY >= 0 && board[newY][newX] !== VACANT) {return true;}}}return false;}lock() {for(let r = 0; r < this.activeTetromino.length; r++) {for(let c = 0; c < this.activeTetromino.length; c++) {if(!this.activeTetromino[r][c]) continue;if(this.y + r < 0) {gameOver();return;}board[this.y + r][this.x + c] = this.color;}}clearLines();}}// 随机生成方块function randomPiece() {let r = Math.floor(Math.random() * PIECES.length);return new Piece(PIECES[r][0], PIECES[r][1]);}// 消除满行function clearLines() {let linesCleared = 0;for(let r = ROW - 1; r >= 0; r--) {if(board[r].every(cell => cell !== VACANT)) {board.splice(r, 1);board.unshift(new Array(COL).fill(VACANT));linesCleared++;r++;}}if(linesCleared > 0) {updateScore(linesCleared);}}// 更新分数function updateScore(linesCleared) {const points = [0, 40, 100, 300, 1200][linesCleared] * level;score += points;lines += linesCleared;if(lines >= LINES_PER_LEVEL) {level++;lines -= LINES_PER_LEVEL;}scoreElement.textContent = score;levelElement.textContent = level;}// 绘制下一个方块function drawNextPiece() {nextCtx.clearRect(0, 0, nextCanvas.width, nextCanvas.height);for(let r = 0; r < nextPiece.tetromino[0].length; r++) {for(let c = 0; c < nextPiece.tetromino[0].length; c++) {if(nextPiece.tetromino[0][r][c]) {nextCtx.fillStyle = nextPiece.color;nextCtx.fillRect(c*30, r*30, 30, 30);nextCtx.strokeStyle = '#333';nextCtx.strokeRect(c*30, r*30, 30, 30);}}}}// 游戏结束function gameOver() {cancelAnimationFrame(rAF);isRunning = false;document.getElementById('startBtn').disabled = false;document.getElementById('pauseBtn').disabled = true;document.getElementById('restartBtn').disabled = false;ctx.fillStyle = 'rgba(0,0,0,0.75)';ctx.fillRect(0, 0, canvas.width, canvas.height);ctx.fillStyle = 'white';ctx.font = '40px Arial';ctx.fillText('游戏结束!', 30, canvas.height/2 - 20);ctx.font = '20px Arial';ctx.fillText('按R键重新开始', 50, canvas.height/2 + 20);}// 初始化游戏function init() {initBoard();score = 0;level = 1;lines = 0;scoreElement.textContent = score;levelElement.textContent = level;piece = randomPiece();nextPiece = randomPiece();drawNextPiece();drawBoard();piece.draw();}// 游戏主循环function gameLoop() {if(isPaused || !isRunning) return;let now = Date.now();let delta = now - dropStart;if(delta > SPEED / level) {piece.moveDown();dropStart = Date.now();}drawBoard();piece.draw();rAF = requestAnimationFrame(gameLoop);}// 添加控制按钮事件document.getElementById('startBtn').addEventListener('click', () => {if(!isRunning) {init();isRunning = true;isPaused = false;document.getElementById('startBtn').disabled = true;document.getElementById('pauseBtn').disabled = false;document.getElementById('restartBtn').disabled = false;dropStart = Date.now();gameLoop();}});document.getElementById('pauseBtn').addEventListener('click', () => {if(isRunning) {isPaused = !isPaused;document.getElementById('pauseBtn').textContent = isPaused ? '继续' : '暂停';if(!isPaused) {dropStart = Date.now();gameLoop();}}});document.getElementById('restartBtn').addEventListener('click', () => {cancelAnimationFrame(rAF);init();isRunning = true;isPaused = false;document.getElementById('pauseBtn').textContent = '暂停';dropStart = Date.now();gameLoop();});// 键盘控制document.addEventListener('keydown', (event) => {if(!isRunning || isPaused) return;if(event.keyCode === 37) { // 左piece.moveLeft();dropStart = Date.now();} else if(event.keyCode === 38) { // 上if(piece.y >= 0) {piece.rotate();dropStart = Date.now();}} else if(event.keyCode === 39) { // 右piece.moveRight();dropStart = Date.now();} else if(event.keyCode === 40) { // 下piece.moveDown();} else if(event.keyCode === 80) { // P键暂停document.getElementById('pauseBtn').click();}});</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/897148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能开发面经AI、大数据、算法

以下是一份AI算法开发岗位的面试面经&#xff0c;结合最新行业趋势和经典问题&#xff0c;涵盖技术解析与实战案例&#xff0c;供参考&#xff1a; 一、机器学习基础&#xff08;占比约30%&#xff09; 1. 过拟合与欠拟合的解决方案 问题&#xff1a;如何解决模型过拟合&…

【原创】Ollama Test API For Linux/MacOS/Unix

安装Json解析工具 Linux/Unix sudo apt-get install jq -yMacOS brew install jq -y设置环境变量 export IP"192.168.250.229" export PORT"8080" export MODEL"deepseek-r1:7b"检查Ollama版本 curl http://"$IP":"$PORT&qu…

【Git】基本指令

工作区、暂存区、版本库 工作区&#xff1a;是在电脑上你要写代码或文件的目录。暂存区&#xff1a;英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件&#xff08;.git/index&#xff09;中&#xff0c;我们把暂存区有时也叫作索引&#xff08;index&#xff09;。…

从数据到决策,永洪科技助力良信电器“智”领未来

在数字经济浪潮汹涌的时代&#xff0c;数字化转型已成为企业增强竞争力、实现可持续发展的必由之路。良信电器&#xff0c;作为国内知名的电气设备制造企业&#xff0c;积极响应时代号召&#xff0c;携手永洪科技&#xff0c;共同开启了数字化转型的新篇章。 上海良信电器股份有…

带触屏笔记本关闭屏幕触控方法

以联想yogaPro16s2023为例 该笔记本显示器为触控屏&#xff0c;不想使用屏幕触控功能&#xff1b; 关闭方法如下&#xff1a; Win11与win10操作一样 鼠标放到开始&#xff0c;右键&#xff0c;选择&#xff0c;设备管理器 找到&#xff0c;人体学输入设备&#xff0c;符合H…

大模型——基于 DIFY 的自动化数据分析实战

基于 DIFY 的自动化数据分析实战 简介: 本文介绍如何使用DIFY搭建数据分析自动化流程,实现从输入需求到查询数据库、LLM分析再到可视化输出的全流程。基于经典的employees数据集和DIFY云端环境,通过LLM-SQL解析、SQL执行、LLM数据分析及ECharts可视化等模块,高效完成数据分…

中原银行:从“小机+传统数据库”升级为“OceanBase+通用服务器”,30 +系统成功上线|OceanBase DB大咖说(十五)

OceanBase《DB 大咖说》第 15 期&#xff0c;我们邀请到了中原银行金融科技部数据团队负责人&#xff0c;吕春雷。本文为本期大咖说的精选。 吕春雷是一位资历深厚的数据库专家&#xff0c;从传统制造企业、IT企业、甲骨文公司到中原银行&#xff0c;他在数据库技术与运维管理…

django各种mixin用法

在 Django 中,Mixin 是一种用于扩展类功能的设计模式。通过 Mixin,可以在不修改原有类的情况下,为其添加新的方法或属性。Django 中的 Mixin 广泛应用于视图(View)、表单(Form)、模型(Model)等组件中。以下是 Django 中常见 Mixin 的用法和示例: 一、视图(View)中的…

SpringBoot集成Netty实现Ws和Tcp通信

本教程将指导你如何在 Spring Boot 项目中集成 Netty&#xff0c;实现 WebSocket 和 TCP 通信。以下是详细的步骤和代码示例。 环境准备 在 你的pom.xml 中添加 Netty 依赖&#xff1a; <dependency><groupId>io.netty</groupId><artifactId>nett…

与中国联通技术共建:通过obdiag分析OceanBase DDL中的报错场景

中国联通软件研究院&#xff08;简称联通软研院&#xff09;在全面评估与广泛调研后&#xff0c;在 2021年底决定采用OceanBase 作为基础&#xff0c;自研分布式数据库产品CUDB&#xff08;即China Unicom Database&#xff0c;中国联通数据库&#xff09;。目前&#xff0c;该…

机器学习-随机森林解析

目录 一、.随机森林的思想 二、随机森林构建步骤 1.自助采样 2.特征随机选择 3构建决策树 4.集成预测 三. 随机森林的关键优势 ​**(1) 减少过拟合** ​**(2) 高效并行化** ​**(3) 特征重要性评估** ​**(4) 耐抗噪声** 四. 随机森林的优缺点 ​优点 ​缺点 五.…

深度集成DeepSeek,智问BI@GPT引领商业智能“深度思考“革命

当下传统的数据分析工具如同显微镜&#xff0c;虽然能帮助我们看到数据的细节&#xff0c;却难以揭示数据背后的深层规律。亿信华辰最新升级的智问BIGPT产品&#xff0c;通过深度集成DeepSeek大模型&#xff0c;首次在商业智能领域实现了"深度思考"功能。这项突破性创…

Mysql安装方式

方式一&#xff1a;安装包安装 下载安装包 官网直接下载&#xff1a;https://dev.mysql.com/downloads/ 安装配置 2.1、双击刚刚下载好的msi文件&#xff0c;开始安装MySQL。 2.2、选择自定义模式Custom安装 2.3、点击选择自己电脑对应的mysql安装目录 2.5、继续点击下一步&…

unity调用本地部署deepseek全流程

unity调用本地部署deepseek全流程 deepseek本地部署 安装Ollama 搜索并打开Ollama官网[Ollama](https://ollama.com/download) 点击Download下载对应版本 下载后点击直接安装 安装deepseek大语言模型 官网选择Models 选择deepseek-r1&#xff0c;选择对应的模型&#xff0…

Linux - 网络基础(应用层,传输层)

一、应用层 1&#xff09;发送接收流程 1. 发送文件 write 函数发送数据到 TCP 套接字时&#xff0c;内容不一定会立即通过网络发送出去。这是因为网络通信涉及多个层次的缓冲和处理&#xff0c;TCP 是一个面向连接的协议&#xff0c;它需要进行一定的排队、确认和重传等处理…

wxWidgets GUI 跨平台 入门学习笔记

准备 参考 https://wiki.wxwidgets.org/Microsoft_Visual_C_NuGethttps://wiki.wxwidgets.org/Tools#Rapid_Application_Development_.2F_GUI_Buildershttps://docs.wxwidgets.org/3.2/https://docs.wxwidgets.org/latest/overview_helloworld.htmlhttps://wizardforcel.gitb…

使用joblib 多线程/多进程

文章目录 1. Joblib 并行计算的两种模式多进程(Multiprocessing,适用于 CPU 密集型任务)多线程(Multithreading,适用于 I/O 密集型任务)2. Joblib 的基本用法3. Joblib 多进程示例(适用于 CPU 密集型任务)示例:计算平方4. Joblib 多线程示例(适用于 I/O 密集型任务)…

神旗视讯Linux client 3.4版本发布和开源

在国产化替代的大潮中&#xff0c;神旗视讯推出专为统信 Linux、麒麟 Linux OS 打造打造的开源视频会议客户端&#xff0c;全面适配国产 x86 及 arm64 架构 CPU&#xff0c;以稳定、安全、灵活的特性&#xff0c;为国产操作系统用户带来前所未有的高效沟通体验&#xff0c;同时…

HCIA-IP路由动态-RIP

一、概念 动态路由是指路由器通过运行动态路由协议&#xff08;RIP、OSPF等&#xff09;&#xff0c;自动学习和发现网络中的路由信息。路由器之间通过交换路由协议数据包&#xff0c;互相通告自己所知道的网络信息&#xff0c;从而构建和更新路由表。 二、RIP(路由信息协议)…

VEC系列-RabbitMQ 入门笔记

消息队列&#xff08;MQ&#xff09;对于开发者来说是一个经常听到的词汇&#xff0c;但在实际开发中&#xff0c;大多数人并不会真正用到它。网上已经有很多关于 MQ 概述和原理的详细讲解&#xff0c;官网文档和技术博客也都介绍得很深入&#xff0c;因此&#xff0c;我在这里…