🐍 别碰墙!大学生手撸贪吃蛇:回忆童年,怒涨姿势!

前言:

还记得小时候玩的那种掌机游戏机,虽然没有现在掌机那么高级,甚至有可以玩 steam 的掌机,但是那是有就已经算好了,最近网站刚搭好,闲来无事,突然回忆起了小时候在小游戏机上玩得昏天黑地的贪吃蛇,那真是像素级别的快乐啊!于是乎,我决定用代码重温一下童年,顺便也让大家看看,大学牲是如何用前端 “还原经典” 的 (手动狗头)。

啥?你没玩过贪吃蛇?(六百六十六你就别装嫩了)

让大江浩带你玩吧~

开干!技术选型和思路

这次是前端三剑客:HTML、CSS 和 JavaScript,纯手工打造一条会扭动的蛇!

我的前端是跟着 b 站大佬 “西部开源” 学的,感兴趣的可以去支持支持。

废话少说,正片开始:

  • HTML: 搭建游戏界面,就像盖房子的地基。
  • CSS: 美化界面,给蛇穿上好看的衣服,让食物看起来更诱人。
  • JavaScript: 编写游戏逻辑,控制蛇的移动、吃东西、判断胜负等等,让蛇 “活” 起来!

核心思路:

  1. 游戏地图: 用一个二维数组来表示游戏区域,每个元素代表一个格子,格子可以为空、是蛇的身体或者食物。
  2. 蛇: 蛇也是一个数组,存储蛇身上每个格子的坐标。
  3. 食物: 随机生成食物的坐标,确保食物不在蛇的身体上。
  4. 移动: 通过改变蛇头的坐标来实现蛇的移动。
  5. 碰撞检测: 判断蛇头是否撞到墙或者自己的身体。

代码环节 (狂敲黑板!竖起小耳朵认真听讲!)

. HTML 结构:

<!DOCTYPE html>
<html>
<head>
    <title>贪吃蛇</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <canvas id="gameCanvas" width="400" height="400"></canvas>
    <script src="script.js"></script>
</body>
</html>
  • canvas: 游戏的主要舞台,所有东西都在这里画出来。
  • style.css: 用来美化界面。
  • script.js: 游戏逻辑的主要代码。

2. CSS 样式:

body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #222;
}

#gameCanvas {
    background-color: #000;
    border: 2px solid #fff;
}

这个是创建一个区域,让游戏区域居中显示,背景颜色设为黑色,边框为白色。

3. JavaScript 逻辑 (重头戏!)

const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");

const gridSize = 20; // 每个格子的大小
const gridCount = canvas.width / gridSize; // 格子数量

let snake = [{ x: 10, y: 10 }]; // 蛇的初始位置
let food = { x: 15, y: 10 }; // 食物初始位置
let dx = 1; // x 轴移动方向 (1: 右, -1: 左, 0: 不动)
let dy = 0; // y 轴移动方向 (1: 下, -1: 上, 0: 不动)
let score = 0;
let gameStarted = false;
let gameInterval;

// 绘制游戏元素
function draw() {
    // 清空画布
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 画蛇
    snake.forEach(segment => {
        ctx.fillStyle = "#fff";
        ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
    });

    // 画食物
    ctx.fillStyle = "#f00";
    ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);

     // 显示分数
     ctx.fillStyle = "#fff";
     ctx.font = "16px Arial";
     ctx.fillText("Score: " + score, 10, 20);
}

// 移动蛇
function moveSnake() {
    const head = { x: snake[0].x + dx, y: snake[0].y + dy };

    // 检查是否撞到墙
    if (head.x < 0 || head.x >= gridCount || head.y < 0 || head.y >= gridCount) {
        gameOver();
        return;
    }

    // 检查是否撞到自己
    for (let i = 1; i < snake.length; i++) {
        if (head.x === snake[i].x && head.y === snake[i].y) {
            gameOver();
            return;
        }
    }

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

    // 将新蛇头添加到蛇的头部
    snake.unshift(head);
}

// 生成食物
function generateFood() {
    let newFood;
    while (!newFood || isSnakeCell(newFood)) {
        newFood = {
            x: Math.floor(Math.random() * gridCount),
            y: Math.floor(Math.random() * gridCount)
        };
    }
    return newFood;
}

// 检查一个格子是否是蛇的身体
function isSnakeCell(cell) {
    for (let i = 0; i < snake.length; i++) {
        if (cell.x === snake[i].x && cell.y === snake[i].y) {
            return true;
        }
    }
    return false;
}

// 游戏结束
function gameOver() {
    clearInterval(gameInterval);
    alert("Game Over! Your score: " + score);
    resetGame();
}

// 重置游戏
function resetGame() {
    snake = [{ x: 10, y: 10 }];
    food = generateFood();
    dx = 1;
    dy = 0;
    score = 0;
    startGame();
}

// 改变蛇的移动方向
document.addEventListener("keydown", (event) => {
    switch (event.key) {
        case "ArrowUp":
            if (dy === 0) { // 避免向上移动时立即向下移动
                dx = 0;
                dy = -1;
            }
            break;
        case "ArrowDown":
            if (dy === 0) {
                dx = 0;
                dy = 1;
            }
            break;
        case "ArrowLeft":
            if (dx === 0) {
                dx = -1;
                dy = 0;
            }
            break;
        case "ArrowRight":
            if (dx === 0) {
                dx = 1;
                dy = 0;
            }
            break;
    }
});

// 开始游戏
function startGame() {
    clearInterval(gameInterval);
    gameInterval = setInterval(() => {
        moveSnake();
        draw();
    }, 100);
}

startGame(); // 启动游戏循环

(我勒个扫杠,敲懵 b 了)

代码解读 (划重点!这是考试要考的!(doge))

  • canvas 和 ctx: 获取 canvas 元素和 2D 渲染上下文,就像拿到画板和画笔。
  • gridSize 和 gridCount: 定义每个格子的大小和数量,控制游戏区域的大小和精度。
  • snake 和 food: 定义蛇和食物的初始状态,用坐标表示它们在游戏区域的位置。
  • dx 和 dy: 定义蛇的移动方向,控制蛇的运动轨迹。
  • draw() 函数: 负责绘制游戏元素,包括蛇、食物和游戏背景。
  • moveSnake() 函数: 负责移动蛇,检查是否吃到食物、撞到墙或者自己。
  • generateFood() 函数: 负责随机生成食物的位置,确保食物不会出现在蛇的身体上。
  • gameOver() 函数: 负责处理游戏结束的逻辑,弹出提示框,并重置游戏。
  • addEventListener(): 监听键盘事件,控制蛇的移动方向。
  • setInterval(): 设置定时器,让游戏循环运行,不断更新游戏状态。

运行结果:

打开你的浏览器,运行 HTML 文件,就能看到一条在黑色方格子里扭动的白色小蛇,还有红色的食物等着你去吃!用方向键控制蛇的移动,看看你能吃到多少个食物!

下一步计划:

  • 加入更多功能:例如暂停、加速、难度选择等等。
  • 美化界面:例如给蛇穿上更漂亮的衣服,让食物看起来更诱人。

这个就留给高手了,我是低手我不会。

温馨提示: 代码仅供参考,或者说仅供娱乐(嘻嘻),请根据自己的实际情况进行修改和优化。(叠甲保命)

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇