科学教育

搜索
查看: 414|回复: 1
打印 上一主题 下一主题

1

[复制链接]

2

主题

3

帖子

18

积分

新手上路

Rank: 1

积分
18
跳转到指定楼层
楼主
发表于 2025-12-10 15:02:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 潘芊宇 于 2025-12-10 15:04 编辑


const context = canvas.getContext("2d");
const startButton = document.getElementById("startButton");

const gridSize = 20;
let snake = [{x: 200, y: 200}];\\1
let food = {x: 0, y: 0};
let dx = gridSize;
let dy = 0;
let score = 0;

\\....2
function drawSnake() {
    context.clearRect(0, 0, canvas.width, canvas.height);
    snake.forEach(part => {
        context.fillStyle = "green";
        context.fillRect(part.x, part.y, gridSize, gridSize);
    });
}

function generateFood() {
    food.x = Math.floor(Math.random() * canvas.width / gridSize) * gridSize;
    food.y = Math.floor(Math.random() * canvas.height / gridSize) * gridSize;
}

function drawFood() {
    context.fillStyle = "red";
    context.fillRect(food.x, food.y, gridSize, gridSize);
}

function moveSnake() {
    const head = {x: snake[0].x + dx, y: snake[0].y + dy};
    snake.unshift(head);
    if (head.x === food.x && head.y === food.y) {
        score++;
        generateFood();
    } else {
        snake.pop();
    }
}

function changeDirection(event) {
    const keyPressed = event.keyCode;
    if (keyPressed === 37 && dx === 0) {
        dx = -gridSize;
        dy = 0;
    }
    if (keyPressed === 38 && dy === 0) {
        dx = 0;
        dy = -gridSize;
    }
    if (keyPressed === 39 && dx === 0) {
        dx = gridSize;
        dy = 0;
    }
    if (keyPressed === 40 && dy === 0) {
        dx = 0;
        dy = gridSize;
    }
}

function gameLoop() {
    moveSnake();
    drawSnake();
    drawFood();
    if (snake[0].x < 0 || snake[0].x >= canvas.width || snake[0].y < 0 || snake[0].y >= canvas.height) {
        clearInterval(game);
        alert("Game Over! Your score is " + score);
    }
}

startButton.addEventListener("click", () => {
    snake = [{x: 200, y: 200}];
    dx = gridSize;
    dy = 0;
    score = 0;
    generateFood();
    game = setInterval(gameLoop, 100);
});

document.addEventListener("keydown", changeDirection);
回复

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
沙发
发表于 2025-12-10 15:03:18 | 只看该作者
好的!我来帮你把代码改成用 WASD 键控制小蛇的方向。W 是上,A 是左,S 是下,D 是右。

首先,我发现你代码里有两个地方写得不完整,我帮你补充一下:

1. 蛇的身体数组 snake 应该初始化为一个有几个方块的数组,比如:

  1. let snake = [
  2.   {x: 100, y: 100},
  3.   {x: 80, y: 100},
  4.   {x: 60, y: 100}
  5. ];
复制代码


2. 在移动蛇的时候,需要用 snake[0] 表示蛇头的位置,而不是 snake.x。

3. 一些细节我要帮你修正一下,让整体流程更顺畅。

下面是修改好的代码,并且把方向键改成 WASD 控制了:

  1. const canvas = document.getElementById("gameCanvas");
  2. const context = canvas.getContext("2d");
  3. const startButton = document.getElementById("startButton");

  4. const gridSize = 20;
  5. let snake = [];
  6. let food = {x: 0, y: 0};
  7. let dx = gridSize;
  8. let dy = 0;
  9. let score = 0;
  10. let game;

  11. function drawSnake() {
  12.     context.clearRect(0, 0, canvas.width, canvas.height);
  13.     snake.forEach(part => {
  14.         context.fillStyle = "green";
  15.         context.fillRect(part.x, part.y, gridSize, gridSize);
  16.     });
  17. }

  18. function generateFood() {
  19.     food.x = Math.floor(Math.random() * (canvas.width / gridSize)) * gridSize;
  20.     food.y = Math.floor(Math.random() * (canvas.height / gridSize)) * gridSize;
  21. }

  22. function drawFood() {
  23.     context.fillStyle = "red";
  24.     context.fillRect(food.x, food.y, gridSize, gridSize);
  25. }

  26. function moveSnake() {
  27.     // 新蛇头的位置 = 旧蛇头 + 移动距离
  28.     const head = {x: snake[0].x + dx, y: snake[0].y + dy};
  29.    
  30.     // 把新蛇头放到数组最前面
  31.     snake.unshift(head);

  32.     if (head.x === food.x && head.y === food.y) {
  33.         // 吃到食物,分数增加,重新生成食物
  34.         score++;
  35.         generateFood();
  36.     } else {
  37.         // 没吃到食物,去掉蛇尾巴,让蛇保持长度
  38.         snake.pop();
  39.     }
  40. }

  41. function changeDirection(event) {
  42.     const keyPressed = event.key.toLowerCase(); // 把按键转成小写
  43.    
  44.     // 防止蛇直接反方向撞自己,比如向右时不能直接变向左
  45.     if ((keyPressed === 'a' || keyPressed === 'arrowleft') && dx === 0) { // 左
  46.         dx = -gridSize;
  47.         dy = 0;
  48.     } else if ((keyPressed === 'w' || keyPressed === 'arrowup') && dy === 0) { // 上
  49.         dx = 0;
  50.         dy = -gridSize;
  51.     } else if ((keyPressed === 'd' || keyPressed === 'arrowright') && dx === 0) { // 右
  52.         dx = gridSize;
  53.         dy = 0;
  54.     } else if ((keyPressed === 's' || keyPressed === 'arrowdown') && dy === 0) { // 下
  55.         dx = 0;
  56.         dy = gridSize;
  57.     }
  58. }

  59. function checkGameOver() {
  60.     const head = snake[0];
  61.     // 蛇头碰到边界,游戏结束
  62.     if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height) {
  63.         return true;
  64.     }
  65.     // 蛇头碰到自己身体,游戏结束
  66.     for (let i = 1; i < snake.length; i++) {
  67.         if (head.x === snake[i].x && head.y === snake[i].y) {
  68.             return true;
  69.         }
  70.     }
  71.     return false;
  72. }

  73. function gameLoop() {
  74.     moveSnake();
  75.     if (checkGameOver()) {
  76.         clearInterval(game);
  77.         alert("游戏结束!你的得分是 " + score);
  78.         return;
  79.     }
  80.     drawSnake();
  81.     drawFood();
  82. }

  83. startButton.addEventListener("click", () => {
  84.     // 初始化蛇,蛇头在中间靠左一点
  85.     snake = [
  86.         {x: 100, y: 100},
  87.         {x: 80, y: 100},
  88.         {x: 60, y: 100}
  89.     ];
  90.     dx = gridSize;
  91.     dy = 0;
  92.     score = 0;
  93.     generateFood();
  94.     if (game) {
  95.         clearInterval(game);
  96.     }
  97.     game = setInterval(gameLoop, 100);
  98. });

  99. document.addEventListener("keydown", changeDirection);
复制代码


### 讲解一下怎么用 WASD 控制:

- 我们监听键盘事件,检测你按的是哪个键。
- 按 W 就让蛇往上跑(dy = -gridSize),按 A 就往左跑(dx = -gridSize),按 S 往下跑(dy = gridSize),按 D 往右跑(dx = gridSize)。
- 这样小蛇就能听你的指令,用 WASD 按键跑来跑去啦!

你可以试着运行这段代码,看小蛇能否用 WASD 控制移动,吃到红色的食物,得分增加。如果碰到墙壁或者撞到自己,就会显示游戏结束。

如果你有任何问题,或者想增加功能,可以随时告诉我哦!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表