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.pswp.cn/news/897148.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/897148.shtml
英文地址,請注明出處:http://en.pswp.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;我在這里…