基于HTML+JS实现贪吃蛇小游戏

多的不说,先看效果

具体实现如下:

1. HTML 结构

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇游戏</title>
    <style>
        /* CSS 样式 */
    </style>
</head>
<body>
    <header>
        <h1>贪吃蛇游戏</h1>
    </header>

    <div class="game-container">
        <canvas id="gameCanvas" width="600" height="400"></canvas>
        <div class="score">当前得分:<span id="score">0</span></div>
        <div id="gameOverMessage" class="game-over">游戏结束</div>
        <button id="restartButton" class="restart-button">重新开始</button>
    </div>

    <script>
        /* JavaScript 代码 */
    </script>
</body>
</html>

2. CSS 样式

body {
    font-family: Arial, sans-serif;
    text-align: center;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
}

header {
    background: #333;
    color: #fff;
    padding: 10px 0;
}

.game-container {
    margin: 20px auto;
    padding: 20px;
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    max-width: 800px;
}

canvas {
    border: 1px solid #000;
}

.score {
    font-size: 24px;
    margin-top: 20px;
}

.game-over {
    display: none;
    font-size: 30px;
    color: black;
    margin-top: 20px;
}

.restart-button {
    display: none;
    margin-top: 20px;
    padding: 10px 20px;
    font-size: 18px;
    color: white;
    background-color: #007bff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

.restart-button:hover {
    background-color: #0056b3;
}

样式解释:
  • body: 设置了页面的字体、背景色、对齐方式等。
  • header: 定义了页面标题的背景色和字体颜色。
  • .game-container: 游戏区域的容器,设置了背景、边距、内边距、圆角和阴影。
  • canvas: 设置了画布的边框。
  • .score: 显示得分的样式。
  • .game-over: 游戏结束时的提示信息,初始状态为隐藏。
  • .restart-button: 重新开始按钮的样式,初始状态为隐藏。

3. JavaScript 代码

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreDisplay = document.getElementById('score');
const gameOverMessage = document.getElementById('gameOverMessage');
const restartButton = document.getElementById('restartButton');

const gridSize = 20; // 网格大小
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;

let snake, food, dx, dy, score, changingDirection, gameOver;

function initGame() {
    snake = [{x: 200, y: 200}, {x: 180, y: 200}, {x: 160, y: 200}];
    food = {x: 300, y: 200};
    dx = gridSize; // 水平移动速度
    dy = 0; // 垂直移动速度
    score = 0;
    changingDirection = false;
    gameOver = false;

    gameOverMessage.style.display = 'none';
    restartButton.style.display = 'none';
    scoreDisplay.textContent = score;
    main();
}

function draw() {
    if (gameOver) return;

    ctx.clearRect(0, 0, canvasWidth, canvasHeight);

    // 画蛇
    ctx.fillStyle = 'green';
    snake.forEach(part => ctx.fillRect(part.x, part.y, gridSize, gridSize));

    // 画食物
    ctx.fillStyle = 'red';
    ctx.fillRect(food.x, food.y, gridSize, gridSize);

    // 更新蛇的位置
    let head = {x: snake[0].x + dx, y: snake[0].y + dy};
    snake.unshift(head);

    // 检查蛇是否吃到食物
    if (head.x === food.x && head.y === food.y) {
        score += 10;
        scoreDisplay.textContent = score;
        placeFood();
    } else {
        snake.pop();
    }

    // 检查蛇是否撞墙或自己
    if (head.x < 0 || head.x >= canvasWidth || head.y < 0 || head.y >= canvasHeight ||
        snake.some((part, index) => index !== 0 && part.x === head.x && part.y === head.y)) {
        gameOver = true;
        gameOverMessage.style.display = 'block';
        restartButton.style.display = 'block';
    }

    changingDirection = false;
}

function placeFood() {
    food = {
        x: Math.floor(Math.random() * (canvasWidth / gridSize)) * gridSize,
        y: Math.floor(Math.random() * (canvasHeight / gridSize)) * gridSize
    };
}

function changeDirection(event) {
    if (changingDirection) return;
    changingDirection = true;

    const keyPressed = event.key;
    if (keyPressed === 'ArrowUp' && dy === 0) {
        dx = 0;
        dy = -gridSize;
    } else if (keyPressed === 'ArrowDown' && dy === 0) {
        dx = 0;
        dy = gridSize;
    } else if (keyPressed === 'ArrowLeft' && dx === 0) {
        dx = -gridSize;
        dy = 0;
    } else if (keyPressed === 'ArrowRight' && dx === 0) {
        dx = gridSize;
        dy = 0;
    }
}

function main() {
    draw();
    if (!gameOver) {
        setTimeout(main, 100); // 控制游戏速度
    }
}

function restartGame() {
    initGame();
}

document.addEventListener('keydown', changeDirection);
restartButton.addEventListener('click', restartGame);

initGame();

JavaScript 代码解释:
  1. 全局变量:

    • canvas 和 ctx: 画布和绘图上下文。
    • scoreDisplaygameOverMessagerestartButton: 页面元素。
    • gridSize: 网格的大小,用于蛇的每一部分和食物的尺寸。
    • canvasWidth 和 canvasHeight: 画布的宽度和高度。
    • snakefooddxdyscorechangingDirectiongameOver: 游戏状态变量。
  2. initGame:

    • 初始化游戏的状态,包括蛇的位置、食物的位置、速度、得分等。
    • 隐藏游戏结束信息和重新开始按钮。
    • 调用 main 函数开始游戏循环。
  3. draw:

    • 清空画布并绘制蛇和食物。
    • 更新蛇的位置。
    • 检查蛇是否吃到食物,如果吃到则更新得分并重新放置食物。
    • 检查蛇是否撞墙或撞到自己,如果是则游戏结束,并显示游戏结束信息和重新开始按钮。
  4. placeFood:

    • 随机生成新的食物位置。
  5. changeDirection:

    • 根据键盘事件改变蛇的移动方向,但防止蛇反向移动。
  6. main:

    • 调用 draw 函数更新游戏状态,并通过 setTimeout 控制游戏速度。
  7. restartGame:

    • 调用 initGame 函数重新初始化游戏,开始新的游戏。
  8. 事件监听:

    • keydown 事件用于改变蛇的方向。
    • click 事件用于重新开始游戏。

这个代码实现了一个简单的贪吃蛇游戏,其中包括了蛇的移动、吃食物、游戏结束检测以及重新开始功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java小诚

新手一个,望包涵

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值