我是靠谱客的博主 辛勤母鸡,这篇文章主要介绍【贪吃蛇】canvas + 原生 JS, 10 行极限实现贪吃蛇上代码注释版,现在分享给大家,希望可以做个参考。

上代码

  • html
    复制代码
    1
    2
    <canvas width="600" height="600">不支持 canvas</canvas>
  • css
    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    canvas { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #ccc; border-radius: 10px; border: 1px solid #000; }
  • js
    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var ctx = document.querySelector('canvas').getContext('2d'), direction = [{ x: -1, y: 0 }, { x: 0, y: -1 }, { x: 1, y: 0 }, { x: 0, y: 1 }], preDir = direction[1], food = { x: -1, y: -1 }, snkArr = [{ x: 14, y: 20 }, { x: 14, y: 21 }, { x: 14, y: 22 }]; var draw = ({ x, y }, color) => (ctx.fillStyle = color, ctx.fillRect(x * 20, y * 20, 19, 19), 1); var changeDir = e => Math.abs((e.keyCode - 37) - direction.indexOf(preDir)) != 2 && (e.keyCode - 37) >= 0 && (e.keyCode - 37) <= 3 && (preDir = direction[e.keyCode - 37], document.removeEventListener('keydown', changeDir)); setInterval(() => { if (document.addEventListener('keydown', changeDir) || snkArr.map((val, i) => { snkArr[0].x + preDir.x == val.x && snkArr[0].y + preDir.y == val.y && (snkArr[0].x = 31) }) && !(snkArr[0].x + preDir.x >= 30 || snkArr[0].y + preDir.y >= 30 || snkArr[0].x + preDir.x <= -1 || snkArr[0].y + preDir.y <= -1)) { snkArr.unshift({ x: snkArr[0].x + preDir.x, y: snkArr[0].y + preDir.y }); draw({ x: snkArr[0].x, y: snkArr[0].y }, '#0aa'); !(((snkArr[0].x == food.x && snkArr[0].y == food.y) || (food.x == -1 && draw(snkArr.pop(), '#ccc'))) && draw(((() => { while (snkArr.indexOf({ x: food.x = ~~(Math.random() * 29), y: food.y = ~~(Math.random() * 29) }) > -1); })(), food), 'orange')) && draw(snkArr.pop(), '#ccc'); } else alert('Game over!', location.reload()); }, 150);

注释版

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
var ctx = document.querySelector('canvas').getContext('2d'), // 2d 对象 direction = [{ x: -1, y: 0 }, { x: 0, y: -1 }, { x: 1, y: 0 }, { x: 0, y: 1 }], // 方向列表,分别是 左 上 右 下 的位移增量,后面通过 keycode - 37 直接访问到该增量 preDir = direction[1], // 当前方向,值为 direction 中四个元素之一 food = { x: -1, y: -1 }, // 食物的位置,初始化为 -1 ,第一次循环生成 snkArr = [{ x: 14, y: 20 }, { x: 14, y: 21 }, { x: 14, y: 22 }]; // 蛇身 // 画方块,{x,y} 为方块的坐标,认为 20 * 20 为一个像素,实现中会做处理, color 为方块颜色 var draw = ({ x, y }, color) => (ctx.fillStyle = color, ctx.fillRect(x * 20, y * 20, 19, 19), 1); // keydown 的回调 var changeDir = e => { // 禁止同方向变化 Math.abs((e.keyCode - 37) - direction.indexOf(preDir)) != 2 // 禁止其他按键影响 && (e.keyCode - 37) >= 0 // preDir 赋值 && (e.keyCode - 37) <= 3 && (preDir = direction[e.keyCode - 37], // 移除事件监听,防止两帧之间连续改变方向 document.removeEventListener('keydown', changeDir)); } setInterval(() => { // 添加事件监听 // map 判断有没有碰到蛇身,碰到后置蛇头超出范围 if (document.addEventListener('keydown', changeDir) || snkArr.map((val, i) => { snkArr[0].x + preDir.x == val.x && snkArr[0].y + preDir.y == val.y && (snkArr[0].x = 31) }) // 判断蛇头有没有超出范围 && !(snkArr[0].x + preDir.x >= 30 || snkArr[0].y + preDir.y >= 30 || snkArr[0].x + preDir.x <= -1 || snkArr[0].y + preDir.y <= -1)) { // snkArr 蛇身增加新蛇头 snkArr.unshift({ x: snkArr[0].x + preDir.x, y: snkArr[0].y + preDir.y }); // 画蛇头 draw({ x: snkArr[0].x, y: snkArr[0].y }, '#0aa'); // 条件:if 碰到食物,(同时判断若食物未初始化则画食物) !(((snkArr[0].x == food.x && snkArr[0].y == food.y) || (food.x == -1 && draw(snkArr.pop(), '#ccc'))) // then 画食物 && draw(((() => { while (snkArr.indexOf({ x: food.x = ~~(Math.random() * 29), y: food.y = ~~(Math.random() * 29) }) > -1); })(), food), '#fff')) // else 不去蛇尾(意为没碰到食物则去蛇尾) && draw(snkArr.pop(), '#ccc'); } else { // 游戏结束 alert('Game over!', location.reload() ); } }, 150);

最后

以上就是辛勤母鸡最近收集整理的关于【贪吃蛇】canvas + 原生 JS, 10 行极限实现贪吃蛇上代码注释版的全部内容,更多相关【贪吃蛇】canvas内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部