【前端】使用 Canvas 實現貪吃蛇小游戲

使用 Canvas 實現貪吃蛇小游戲

在這篇博客中,我們將介紹如何使用 HTML5 Canvas 和 JavaScript 實現一個簡單的貪吃蛇(Snake)小游戲。這個項目是一個基礎的游戲開發練習,它可以幫助你理解如何在 Canvas 上繪圖、如何處理用戶輸入以及如何管理游戲狀態。
在這里插入圖片描述

項目結構

在開始之前,確保你的項目文件結構如下:

  • index.html
  • index.css
  • index.js

HTML 部分

首先,我們在 index.html 中定義 Canvas 和一個重新開始按鈕。

<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>貪吃蛇游戲</title><link rel="stylesheet" href="index.css">
</head>
<body><canvas id="gameCanvas" width="400" height="400"></canvas><button id="restartButton" style="display: none;" onclick="restartGame()">重新開始</button><script src="index.js"></script>
</body>
</html>

CSS 部分

index.css 中,我們可以設置 Canvas 和按鈕的樣式。

/* styles.css */
body {display: flex;flex-direction: column;justify-content: center;align-items: center;height: 100vh;margin: 0;background-color: #f0f0f0;
}canvas {border: 1px solid #000;background-color: #fff;
}button {display: none;margin-top: 20px;padding: 10px 20px;font-size: 16px;cursor: pointer;position: absolute;
}

JavaScript 部分

接下來,我們在 script.js 中編寫游戲的主要邏輯。

1. 初始化 Canvas 和變量

我們首先獲取 Canvas 元素及其上下文,并定義游戲所需的一些變量。

const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const restartButton = document.getElementById("restartButton");const gridSize = 20; // 格子大小
const rows = canvas.height / gridSize;
const cols = canvas.width / gridSize;

2. 初始化游戲

創建 initGame 函數來初始化游戲狀態:

function initGame() {snake = [{ x: cols / 2, y: rows / 2 }, { x: cols / 2 + 1, y: rows / 2 }];food = {x: Math.floor(Math.random() * cols),y: Math.floor(Math.random() * rows),};direction = { x: 1, y: 0 };lastDirection = { x: 1, y: 0 };gameOver = false;restartButton.style.display = "none";gameLoop();
}

3. 繪制游戲元素

我們需要兩個函數來繪制蛇和食物:

function drawCell(x, y, color) {ctx.fillStyle = color;ctx.fillRect(x * gridSize, y * gridSize, gridSize, gridSize);ctx.strokeStyle = "#000";ctx.lineWidth = 2; // 可以根據需要調整ctx.strokeRect(x * gridSize, y * gridSize, gridSize, gridSize);
}function drawSnake() {snake.forEach((part) => drawCell(part.x, part.y, "#409EFF"));
}function drawFood() {drawCell(food.x, food.y, "#E6A23C");
}

4. 更新蛇的位置

創建 updateSnake 函數來更新蛇的位置,并檢查它是否吃到食物或撞到墻及自身:

function updateSnake() {const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };if (head.x === food.x && head.y === food.y) {food = {x: Math.floor(Math.random() * cols),y: Math.floor(Math.random() * rows),};} else {snake.pop();}snake.unshift(head);// 撞墻或撞到自己if (head.x < 0 ||head.x >= cols ||head.y < 0 ||head.y >= rows ||snake.slice(1).some((part) => part.x === head.x && part.y === head.y)) {gameOver = true;}lastDirection = direction;
}

5. 游戲循環

創建 gameLoop 函數來處理游戲的繪制和更新:

function gameLoop() {if (!gameOver) {ctx.clearRect(0, 0, canvas.width, canvas.height);drawFood();updateSnake();drawSnake();setTimeout(gameLoop, 100);} else {ctx.font = "100px Arial";ctx.fillStyle = "#F56C6C";ctx.fillText("Game Over", canvas.width / 4, canvas.height / 2);restartButton.style.display = "block"; // 顯示重新開始按鈕}
}

6. 處理用戶輸入

添加鍵盤事件監聽來控制蛇的移動方向:

window.addEventListener("keydown", (event) => {switch (event.key) {case "ArrowUp":if (lastDirection.y === 0) direction = { x: 0, y: -1 };break;case "ArrowDown":if (lastDirection.y === 0) direction = { x: 0, y: 1 };break;case "ArrowLeft":if (lastDirection.x === 0) direction = { x: -1, y: 0 };break;case "ArrowRight":if (lastDirection.x === 0) direction = { x: 1, y: 0 };break;}
});

7. 重新開始游戲

最后,創建一個函數用于重新啟動游戲:

function restartGame() {initGame();  // 重新啟動游戲
}initGame();  // 啟動游戲

總結

通過這篇博客,你學習了如何使用 HTML5 Canvas 和 JavaScript 來實現一個簡單的貪吃蛇小游戲。我們展示了如何繪制游戲元素,處理用戶輸入,并管理游戲狀態。希望這個項目能幫助你對游戲開發有更深入的理解,并激發你進行更多有趣的項目開發!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/13535.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/13535.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/13535.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Laravel(Lumen8) + Supervisor 實現多進程redis消息隊列

相關文章:Supervisor守護進程工具安裝與使用 1、通用消息隊列 /App/Job/CommonJob.php: <?phpnamespace App\Jobs; use Illuminate\Support\Facades\Log; use Illuminate\Support\Str;class CommonJob extends Job {public $timeout; //超時時間protected $data; //隊列…

Android:OkHttp網絡請求框架的使用

目錄 一&#xff0c;OkHttp簡介 二&#xff0c;OkHttp請求處理流程 三&#xff0c;OkHttp環境配置 四&#xff0c;OkHttp的使用 1.get網絡請求 2.post上傳表單數據 3.post上傳json格式數據 4.文件上傳 5.文件下載 一&#xff0c;OkHttp簡介 OkHttp是square公司推出的一…

npm 源管理工具 nrm

npm 源管理工具 nrm 安裝(可能很慢, 多試幾次) npm install -g nrm查看可選擇源列表 nrm ls切換源 nrm use <registry>如: nrm use taobao

rust的版本問題,安裝問題,下載問題

rust的版本、安裝、下載問題 rust版本問題&#xff0c; 在使用rust的時候&#xff0c;應用rust的包&#xff0c;有時候包的使用和rust版本有關系。 error: failed to run custom build command for pear_codegen v0.1.2 Caused by: process didnt exit successfully: D:\rus…

鴻蒙全面開發指南:入門、生態安全與資源支持

鴻蒙全面開發指南&#xff1a;入門、生態安全與資源支持 本文全面梳理了鴻蒙操作系統的開發入門流程&#xff0c;涵蓋了開發環境準備、工具使用、項目創建、模擬器配置到應用安全設計的各個方面。通過本文&#xff0c;讀者不僅能夠了解鴻蒙開發的基本步驟&#xff0c;也能深入理…

Aspose.PDF功能演示:在 JavaScript 中將 TXT 轉換為 PDF

您是否正在尋找一種在 JavaScript 項目中將純文本文件從TXT無縫轉換為PDF格式的方法&#xff1f;您來對地方了&#xff01;無論您是要構建 Web 應用程序、創建生產力工具&#xff0c;還是只是希望簡化工作流程&#xff0c;直接從 JavaScript 代碼中將 TXT 轉換為 PDF 的功能都可…

第3天 Web源碼拓展_小迪網絡安全筆記

1.關于web源碼目錄結構 #數據庫配置文件 后臺目錄 模板目錄 數據庫目錄 1.1數據庫配置文件: 1.1就拿wordpress來說,先到官網下載源碼:Download – WordPress.org,解壓源碼之后: 2.2找到目錄下名為 wp-config-sample.php的文件,這就是數據庫配置文件: 設想: 我們在滲透…

FOURIER NEURAL OPERATOR FOR PARAMETRIC PARTIAL DIFFERENTIAL EQUATIONS

參數偏微分方程的傅里葉神經算子 論文鏈接&#xff1a;https://arxiv.org/abs/2010.08895 項目鏈接&#xff1a;https://github.com/neuraloperator/neuraloperator 作者博客&#xff1a;https://zongyi-li.github.io/blog/2020/fourier-pde/ 參數偏微分方程的傅里葉神經算子…

本地部署Terraria泰拉瑞亞私服并通過內網穿透生成公網地址遠程聯機

文章目錄 前言1. 下載Terraria私服2. 本地運行Terraria 私服3. 本地Terraria私服連接4. Windwos安裝Cpolar 工具5. 配置Terraria遠程聯機地址6. Terraria私服遠程聯機7. 固定遠程聯機地址8. 固定的聯機地址測試 前言 本文將為你詳細介紹在本地如何運行泰拉瑞亞本地私服和結合C…

認識 React Hooks

回顧函數組件 函數組件 沒有組件實例 不能監聽各個生命周期 無法擴展屬性和方法 沒有 state 和 setState 只是輸入 props &#xff0c;輸出 jsx &#xff0c;純函數。 // class 組件class List extends React.Component {constructor(props) {super(props)}render() {con…

信息泄露--注意點點

目錄 明確目標: 信息泄露: 版本軟件 敏感文件 配置錯誤 url基于文件: url基于路由: 狀態碼: http頭信息泄露 報錯信息泄露 頁面信息泄露 robots.txt敏感信息泄露 .get文件泄露 --判斷: 搜索引擎收錄泄露 BP: 爆破: 明確目標: 失能 讀取 寫入 執行 信息泄…

【文末附gpt升級方案】Ilya離開OpenAI內幕探究:算力削減與商業優先策略的沖突

Ilya離開OpenAI內幕探究&#xff1a;算力削減與商業優先策略的沖突 一、引言 在人工智能&#xff08;AI&#xff09;領域的飛速發展中&#xff0c;OpenAI一直以其領先的技術和創新產品而備受矚目。然而&#xff0c;近日發生的Ilya Sutskever離開OpenAI的事件卻引起了業界的廣…

java企業級云MES系統全套源碼,支持app、小程序、H5、臺后管理

企業級云MES全套源碼&#xff0c;支持app、小程序、H5、臺后管理端 企業級智能制造MES系統源碼&#xff0c;技術架構&#xff1a;springboot vue-element-plus-admin MES指的是制造企業生產過程執行系統&#xff0c;是一套面向制造企業車間執行層的生產信息化管理系統。MES可以…

棧(基于動態順序表實現的棧)

棧的簡單介紹 關于棧的性質咳咳 棧&#xff1a;棧是一種特殊的線性表,其中只讓在一端插入和刪除元素。 后進先出 進行插入刪除的那一端叫棧頂&#xff0c;另一端叫棧底 我們實現的棧是基于一個動態順序表的的棧&#xff0c;會實現棧的 入棧&#xff0c;出棧&#xff0c;獲取…

修改默認時區,默認語言,默認國家

確認時區&#xff0c;語言&#xff0c;國家 build/make/target/product/languages_default.mkframeworks/base/packages/SettingsLib/res/xml/timezones.xml設備mk中添加相關內容 PRODUCT_PROPERTY_OVERRIDES \persist.sys.timezoneEurope/AmsterdamPRODUCT_PROPERTY_OVERRI…

嵌入式學習——3——超時timeout

1、自帶超時參數的函數 select自帶超時 定義超時時間變量 struct timeval tv {5, 0}; while(1) { tv.tv_sec 5; tv.tv_usec 0; int res select(1, &readfds, NULL, NULL, &tv); ..... } poll自帶超時 1、poll函數的第三個參數&#xff0c;是以毫秒為單位的超時時間…

前端vue用el-table如何實現表頭內容過長換行處理,實現換行效果

前端vue用el-table如何實現表頭內容過長換行處理&#xff0c;實現換行效果 這是效果圖 有兩種方法&#xff0c;一種簡易版本&#xff0c;一種萬能方法,都是el-table&#xff0c;先看文檔 表頭標題是可以自定義的 方法一 label的解釋寫在代碼里面了&#xff0c;這里會自動形成換…

Python概述

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 了解Python Python&#xff0c;本義是指“蟒蛇”。1989年&#xff0c;荷蘭人Guido van Rossum發明了一種面向對象的解釋型高級編程語言&#xff0c;…

利用神經網絡學習語言(六)——總結與常見面試問題

相關說明 這篇文章的大部分內容參考自我的新書《解構大語言模型&#xff1a;從線性回歸到通用人工智能》&#xff0c;歡迎有興趣的讀者多多支持。 文章列表&#xff1a; 利用神經網絡學習語言&#xff08;一&#xff09;——自然語言處理的基本要素利用神經網絡學習語言&…

Java基礎入門day49

day49 tomcat 啟動 進入tomcat的bin目錄&#xff0c;雙擊或者運行startup.bat文件啟動tomcat 控制臺最后出現服務器啟動在多少毫米之內&#xff0c;代表服務器成功啟動 org.apache.catalina.startup.Catalina.start Server startup in 405 ms 驗證tomcat 在瀏覽器中輸入 loca…