W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
這個中秋可是悲催,別人放假,我還得在家辦公寫項目,帶娃的時間都沒有,這不,娃要纏著陪她玩積木游戲,哎,心中有事,陪娃都陪不好,咋整,靈機一動,先搞個小游戲讓娃耍個把小時,畢竟孩子長時間對著電腦不好,寫個貪吃蛇吧,能玩很久。
先看一下簡單的界面是這樣的:
網頁游戲,比較簡單,一個頁面就搞定了,代碼是這樣的,直接生成一個 html 就能玩了。
創(chuàng)建一個簡單的貪吃蛇網頁游戲,使用 HTML、CSS 和 JavaScript 三件套,簡單高效。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Snake Game</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #333;
margin: 0;
}
canvas {
border: 1px solid #fff;
background-color: #000;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const gridSize = 20;
const tileCount = canvas.width / gridSize;
let snake = [{ x: 10, y: 10 }];
let food = { x: 5, y: 5 };
let direction = { x: 0, y: 0 };
let nextDirection = { x: 0, y: 0 };
let speed = 200;
function gameLoop() {
// Update snake direction
direction = nextDirection;
// Move snake
const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };
snake.unshift(head);
// Check for food collision
if (head.x === food.x && head.y === food.y) {
placeFood();
} else {
snake.pop();
}
// Check for wall collision
if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
gameOver();
return;
}
// Check for self collision
for (let i = 1; i < snake.length; i++) {
if (snake[i].x === head.x && snake[i].y === head.y) {
gameOver();
return;
}
}
drawGame();
}
function drawGame() {
// Clear canvas
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw snake
ctx.fillStyle = 'lime';
snake.forEach(part => {
ctx.fillRect(part.x * gridSize, part.y * gridSize, gridSize, gridSize);
});
// Draw food
ctx.fillStyle = 'red';
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
}
function placeFood() {
food.x = Math.floor(Math.random() * tileCount);
food.y = Math.floor(Math.random() * tileCount);
// Make sure food doesn't appear on the snake
for (let i = 0; i < snake.length; i++) {
if (snake[i].x === food.x && snake[i].y === food.y) {
placeFood();
}
}
}
function changeDirection(event) {
switch (event.keyCode) {
case 37: // Left arrow
if (direction.x === 0) {
nextDirection = { x: -1, y: 0 };
}
break;
case 38: // Up arrow
if (direction.y === 0) {
nextDirection = { x: 0, y: -1 };
}
break;
case 39: // Right arrow
if (direction.x === 0) {
nextDirection = { x: 1, y: 0 };
}
break;
case 40: // Down arrow
if (direction.y === 0) {
nextDirection = { x: 0, y: 1 };
}
break;
}
}
function gameOver() {
alert('Game Over!');
snake = [{ x: 10, y: 10 }];
direction = { x: 0, y: 0 };
nextDirection = { x: 0, y: 0 };
placeFood();
}
document.addEventListener('keydown', changeDirection);
setInterval(gameLoop, speed);
placeFood();
</script>
</body>
</html>
前端三件套:
HTML:包含一個 <canvas>
元素,貪吃蛇游戲將會在這個畫布上渲染。
CSS:簡單地設置了畫布的外觀。
JavaScript:游戲邏輯,包括:
gameLoop
函數:負責蛇的移動、碰撞檢測、食物生成等。drawGame
函數:繪制蛇和食物。placeFood
函數:隨機放置食物在畫布上。changeDirection
函數:監(jiān)聽鍵盤事件,改變蛇的移動方向。gameOver
函數:處理游戲結束的邏輯。下面再詳細解釋一下這個小游戲的實現邏輯:
這個貪吃蛇游戲使用 HTML、CSS 和 JavaScript 編寫,代碼實現的邏輯和流程如下:
<canvas id="gameCanvas" width="400" height="400"></canvas>
<canvas>
元素作為游戲畫布,游戲會在這個區(qū)域繪制蛇、食物等內容。id="gameCanvas"
以便在 JavaScript 中通過 document.getElementById
獲取它。width
和 height
屬性定義了畫布的尺寸為 400x400 像素。body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #333;
margin: 0;
}
canvas {
border: 1px solid #fff;
background-color: #000;
}
JavaScript 部分包含了游戲的核心邏輯,包括蛇的移動、食物的生成、碰撞檢測、繪制和用戶輸入的處理。
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const gridSize = 20;
const tileCount = canvas.width / gridSize;
let snake = [{ x: 10, y: 10 }];
let food = { x: 5, y: 5 };
let direction = { x: 0, y: 0 };
let nextDirection = { x: 0, y: 0 };
let speed = 200;
canvas
:獲取畫布元素。ctx
:獲取畫布的 2D 渲染上下文,用于繪制圖形。gridSize
:網格大小,每個網格 20x20 像素。tileCount
:計算畫布中網格的數量,canvas.width / gridSize
(這里為 20x20 個網格)。snake
:蛇的初始位置,初始為一個對象數組,蛇頭位置在 {x: 10, y: 10}
。food
:食物的初始位置 {x: 5, y: 5}
。direction
和 nextDirection
:蛇的當前移動方向和下一個移動方向。speed
:控制游戲循環(huán)的速度,單位是毫秒。function gameLoop() {
// Update snake direction
direction = nextDirection;
// Move snake
const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };
snake.unshift(head);
// Check for food collision
if (head.x === food.x && head.y === food.y) {
placeFood();
} else {
snake.pop();
}
// Check for wall collision
if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
gameOver();
return;
}
// Check for self collision
for (let i = 1; i < snake.length; i++) {
if (snake[i].x === head.x && snake[i].y === head.y) {
gameOver();
return;
}
}
drawGame();
}
gameLoop
是游戲的主循環(huán)函數,使用 setInterval
在一定時間間隔內重復調用,實現游戲的實時更新。x
和 y
坐標,將新頭部添加到 snake
數組的開頭。placeFood
生成新的食物位置;否則,移除蛇尾(snake.pop()
),維持蛇的長度。gameOver
函數結束游戲。gameOver
函數結束游戲。drawGame
函數更新畫布。function drawGame() {
// Clear canvas
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw snake
ctx.fillStyle = 'lime';
snake.forEach(part => {
ctx.fillRect(part.x * gridSize, part.y * gridSize, gridSize, gridSize);
});
// Draw food
ctx.fillStyle = 'red';
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
}
drawGame
函數負責繪制游戲的每一幀。snake
數組,在蛇每個部分的位置上繪制一個綠色矩形。food
的位置繪制一個紅色矩形。function placeFood() {
food.x = Math.floor(Math.random() * tileCount);
food.y = Math.floor(Math.random() * tileCount);
// Make sure food doesn't appear on the snake
for (let i = 0; i < snake.length; i++) {
if (snake[i].x === food.x && snake[i].y === food.y) {
placeFood();
}
}
}
placeFood
隨機在畫布上放置食物。placeFood
重新生成位置。function changeDirection(event) {
switch (event.keyCode) {
case 37: // Left arrow
if (direction.x === 0) {
nextDirection = { x: -1, y: 0 };
}
break;
case 38: // Up arrow
if (direction.y === 0) {
nextDirection = { x: 0, y: -1 };
}
break;
case 39: // Right arrow
if (direction.x === 0) {
nextDirection = { x: 1, y: 0 };
}
break;
case 40: // Down arrow
if (direction.y === 0) {
nextDirection = { x: 0, y: 1 };
}
break;
}
}
changeDirection
函數監(jiān)聽鍵盤事件,更新蛇的移動方向。function gameOver() {
alert('Game Over!');
snake = [{ x: 10, y: 10 }];
direction = { x: 0, y: 0 };
nextDirection = { x: 0, y: 0 };
placeFood();
}
gameOver
函數在蛇撞墻或自身時調用,顯示“游戲結束”信息,并重置游戲狀態(tài)。document.addEventListener('keydown', changeDirection);
setInterval(gameLoop, speed);
placeFood();
changeDirection
函數。setInterval
定期調用 gameLoop
,使游戲持續(xù)運行。placeFood
函數生成初始食物位置。gameLoop
) 不斷更新蛇的位置、檢查碰撞、繪制游戲元素,形成動畫效果。好了,現在可以靜靜的寫項目了,專心致志,效率翻倍。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯系方式:
更多建議: