游戏开发(一)之简单的贪吃蛇游戏:HTML、CSS和JavaScript教程

在本教程中,我们将逐步构建一个简单的贪吃蛇游戏。这个项目适合初学者,可以帮助你理解HTML、CSS和JavaScript的基础知识,并掌握如何将它们结合起来创建一个完整的游戏。

准备工作
在开始之前,请确保你已经安装了一个代码编辑器(如Visual Studio Code)和一个浏览器(如Chrome或Firefox)。

第一步:创建HTML文件
首先,我们需要一个HTML文件来定义游戏的结构。在你的项目文件夹中创建一个名为index.html的文件,并添加以下代码:

解释
<!DOCTYPE html>:声明文档的类型为 HTML5,帮助浏览器正确渲染页面。
<html lang="en">:定义 HTML 文档的根元素,并指定语言为英文。
<head>:包含文档的元数据和资源链接。
<meta charset="UTF-8">:设置字符编码为 UTF-8,确保网页支持多语言字符。
<meta name="viewport" content="width=device-width, initial-scale=1.0">:确保网页在移动设备上适应宽度,并设置初始缩放级别。
<title>贪吃蛇小游戏</title>:设置网页的标题。
<style>:包含内部 CSS 样式,用于设置页面的样式。
canvas:设置 canvas 元素的背景颜色、显示方式、外边距和边框样式。
#score:为分数显示元素预留了样式设置位置(目前为空)。
<body>:文档主体,包含页面的实际内容。
<canvas id="gameCanvas" width="500" height="500"></canvas>:定义了一个用于绘制游戏的画布,大小为 500x500 像素。
<div id="score">分数: 0</div>:一个显示游戏分数的 div 元素。
<script src="game.js"></script>:引入外部 JavaScript 文件,用于实现游戏逻辑。
第二步:创建JavaScript文件
在你的项目文件夹中创建一个名为game.js的文件,并添加以下代码:

const canvas = document.getElementById('gameCanvas');
 
const ctx = canvas.getContext('2d');
 
const scoreDisplay = document.getElementById('score');
 
const eatSound = document.getElementById('eatSound');
 
const gridSize = 20;
 
const canvasWidth = canvas.width;
 
const canvasHeight = canvas.height;
 
const gridWidth = canvasWidth / gridSize;
 
const gridHeight = canvasHeight / gridSize;
 
 
 
let snake = [{ x: 10, y: 10 }];
 
let food = generateFood();
 
let dx = 1, dy = 0;
 
let score = 0;
 
let speed = 100; // 游戏速度 (毫秒)
 
let gameInterval;
 
let isPaused = false; // 暂停状态
 
 
 
document.addEventListener('keydown', changeDirection);
 
document.addEventListener('keydown', controlGame);
 
startGame();
 
 
 
function changeDirection(e) {
 
    switch (e.keyCode) {
 
        case 37: // 左箭头
 
            if (dx === 0) { dx = -1; dy = 0; }
 
            break;
 
        case 38: // 上箭头
 
            if (dy === 0) { dx = 0; dy = -1; }
 
            break;
 
        case 39: // 右箭头
 
            if (dx === 0) { dx = 1; dy = 0; }
 
            break;
 
        case 40: // 下箭头
 
            if (dy === 0) { dx = 0; dy = 1; }
 
            break;
 
    }
 
}
 
 
 
function controlGame(e) {
 
    switch (e.keyCode) {
 
        case 80: // 'P' 键
 
            togglePause();
 
            break;
 
        case 187: // '+' 键
 
            speed = Math.max(10, speed - 10); // 增加速度
 
            updateGameSpeed();
 
            break;
 
        case 189: // '-' 键
 
            speed += 10; // 减少速度
 
            updateGameSpeed();
 
            break;
 
    }
 
}
 
 
 
function startGame() {
 
    gameInterval = setInterval(loop, speed);
 
}
 
 
 
function loop() {
 
    if (isPaused) return;
 
 
 
    const head = { ...snake[0] };
 
    head.x += dx;
 
    head.y += dy;
 
 
 
    // 碰撞检测
 
    if (head.x < 0 || head.x >= gridWidth || head.y < 0 || head.y >= gridHeight || 
snakeCollision(head)) {
 
        endGame();
 
        return;
 
    }
 
 
 
    snake.unshift(head);
 
 
 
    // 检查是否吃到食物
 
    if (snake[0].x === food.x && snake[0].y === food.y) {
 
        score += 10; // 增加分数
 
        scoreDisplay.textContent = `分数: ${score}`;
 
        eatSound.play(); // 播放音效
 
        food = generateFood(); // 生成新的食物
 
    } else {
 
        snake.pop();
 
    }
 
 
 
    drawGame();
 
}
 
 
 
function drawGame() {
 
    ctx.fillStyle = '#f4f4f4';
 
    ctx.fillRect(0, 0, canvasWidth, canvasHeight);
 
 
 
    ctx.fillStyle = 'red';
 
    ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
 
 
 
    ctx.fillStyle = 'green';
 
    snake.forEach(segment => {
 
        ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
 
    });
 
}
 
 
 
function snakeCollision(head) {
 
    for (let i = 1; i < snake.length; i++) {
 
        if (head.x === snake[i].x && head.y === snake[i].y) {
 
            return true;
 
        }
 
    }
 
    return false;
 
}
 
 
 
function generateFood() {
 
    let foodPosition;
 
    while (true) {
 
        foodPosition = { x: Math.floor(Math.random() * gridWidth), y: 
Math.floor(Math.random() * gridHeight) };
 
        if (!snakeCollision(foodPosition)) break; // 确保食物不出现在蛇身上
 
    }
 
    return foodPosition;
 
}
 
 
 
function endGame() {
 
    clearInterval(gameInterval);
 
    alert(`游戏结束!你的得分是: ${score}`);
 
    resetGame();
 
}
 
 
 
function resetGame() {
 
    snake = [{ x: 10, y: 10 }];
 
    dx = 1;
 
    dy = 0;
 
    score = 0;
 
    scoreDisplay.textContent = `分数: ${score}`;
 
    food = generateFood();
 
    startGame();
 
}
 
 
 
function togglePause() {
 
    isPaused = !isPaused;
 
    if (!isPaused) {
 
        startGame();
 
    } else {
 
        clearInterval(gameInterval);
 
    }
 
}
 
 
 
function updateGameSpeed() {
 
    clearInterval(gameInterval);
 
    startGame();
 
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值