如何完善基于Canvas的简易贪吃蛇游戏水平移动及吃食物逻辑?
完善贪吃蛇吃食物逻辑及功能实现
看起来你已经搭好了贪吃蛇的基础框架,现在咱们来把吃食物的逻辑补全,顺便完善蛇身增长、新食物生成这些核心功能。
首先修复吃食物的判断逻辑
原代码里的eat函数判断条件没写完,其实因为蛇头和食物都是以10px为单位的格子(你设置了size_x=10,食物坐标也是*10的整数),所以直接判断蛇头的x和food_position_x相等、y和food_position_y相等就可以了,不用做多余的取整计算。
然后补充核心功能
要实现完整的吃食物流程,还需要:
- 用数组管理蛇身的每一段坐标,方便后续增长
- 吃到食物后,蛇身增加一段
- 生成新的食物,并且避免食物出现在蛇身上
完整改进后的代码示例
(function() { var canvas = document.getElementById('canvas'), ctx = canvas.getContext('2d'), speed = 2, // 用数组存储蛇的每一段,初始蛇头在(0,0) snake = [{x: 0, y: 0}], // 初始移动方向:水平向右,每次移动10px(匹配格子大小) x_move = speed * 10, y_move = 0, food_position_x, food_position_y, size = 10; // 统一格子大小 // 初始化生成食物 generateFood(); function generateFood() { // 生成随机食物坐标(10px倍数) food_position_x = Math.floor(Math.random() * canvas.width / size) * size; food_position_y = Math.floor(Math.random() * canvas.height / size) * size; // 避免食物出现在蛇身上,如果重合就重新生成 for (let segment of snake) { if (segment.x === food_position_x && segment.y === food_position_y) { generateFood(); return; } } } function eat() { const head = snake[0]; // 判断蛇头是否碰到食物 if (head.x === food_position_x && head.y === food_position_y) { console.log('吃到食物啦!'); // 蛇身增长:在蛇尾添加一段(坐标和当前蛇尾一致,下一次移动会自动跟上) snake.push({...snake[snake.length - 1]}); // 生成新的食物 generateFood(); } } function draw() { // 清空画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 绘制蛇 ctx.fillStyle = '#00ff00'; snake.forEach(segment => { ctx.fillRect(segment.x, segment.y, size, size); }); // 绘制食物 ctx.fillStyle = '#ff0000'; ctx.fillRect(food_position_x, food_position_y, size, size); } function update() { const head = {...snake[0]}; // 更新蛇头位置 head.x += x_move; head.y += y_move; // 把新蛇头放到数组最前面,移除蛇尾(除非吃到食物) snake.unshift(head); // 只有没吃到食物的时候才移除蛇尾,吃到的话蛇身就会增长 if (!(head.x === food_position_x && head.y === food_position_y)) { snake.pop(); } // 检查是否吃到食物 eat(); // 绘制画面 draw(); // 循环调用,实现动画 requestAnimationFrame(update); } // 启动游戏 update(); })();
关键改动说明
- 蛇身管理:用
snake数组存储每一段的坐标,初始只有蛇头,吃到食物时在数组末尾添加一段,移动时通过unshift添加新蛇头、pop移除蛇尾来实现移动效果。 - 食物生成逻辑:新增
generateFood函数,不仅生成随机坐标,还会检查是否和蛇身重合,避免食物出现在蛇身上。 - 移动逻辑优化:把每次移动的距离改成
speed*10,这样蛇每次移动一个格子的距离,和你的坐标系统更匹配。 - 吃食物判断:直接比较蛇头和食物的坐标,逻辑更清晰准确。
你可以把这段代码替换原来的部分,然后给canvas设置合适的宽高(比如width="400" height="400"),就能看到完整的吃食物和蛇身增长效果啦!
内容的提问来源于stack exchange,提问作者Reza Saadati
相关产品推荐
相关产品推荐

