前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >童年回味——js实现贪吃蛇教程

童年回味——js实现贪吃蛇教程

作者头像
逝兮诚
发布2019-10-30 13:26:52
6090
发布2019-10-30 13:26:52
举报
文章被收录于专栏:代码人生

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/luo4105/article/details/72900989

通知

游戏目前还在更新,博客只实现核心功能,获得最新版请访问github地址。

github地址:” https://github.com/programluo/snackeat”,

发布地址

初始版本:” https://programluo.github.io/snackeat/old-version/snakeat.html”

最新版本:“https://programluo.github.io/snackeat/”

实现思路

背景和蛇实现

使用canvas画布,蛇的身体是一串的正方形

用二维数组去存蛇的身体,二维数组中的每一个数组为蛇身体的每一块的坐标,并跟据坐标在canvas上画方块

代码语言:javascript
复制
var sn = [
       [2, 4],
       [1, 4]
    ]
function draw(t, c) {
   ctx.fillStyle = c;
   ctx.fillRect(t[0] * 20 + 1, t[1] * 20 + 1, 18, 18);
}

蛇的移动和转向

移动

蛇向前移动就是在二维数组头部插入一个新的数组,删除二维尾部最后一个数组,画图时也是如此,头部画一个方块,尾部把方块的背景色改成画布背景色。

代码语言:javascript
复制
sn.unshift(n = [sn[0][0] + rlx[0], sn[0][1]+ rlx[1]]); //sn数组头部添加一个元素
draw(n, "Lime");
draw(sn.pop(), "black"); //sn数组去掉最后一个元素
转向

获得前后左右键的方法

代码语言:javascript
复制
document.onkeydown = function(e) {
         fx= e.keyCode;
}

其中

代码语言:javascript
复制
keycode  37 = Left
keycode  38 = Up
keycode  39 = Right
keycode  40 = Down

这些操作对应的下个头结点坐标的运算是

代码语言:javascript
复制
Left:          head.x-1, head.y+0;
Up:           head.x+0,head.y-1;
Right:       head.x+1,head.y+0;
Down:      head.x+0,head.y+1;
代码语言:javascript
复制
action = [[-1,0], [0, -1], [1, 0], [0, 1]],
document.onkeydown = function(e) {
   if ((fx - e.keyCode) % 2 != 0) {
       fx = e.keyCode;
       rlx = action[e.keyCode - 37] || rlx;
    }
}
sn.unshift(n = [sn[0][0] + rlx[0], sn[0][1]+ rlx[1]]);

死亡判断

撞墙:判断新增的头数组的左右坐标超过边界

撞自己:二维数组已存在新增头数组(排除头数组,即从二维数组的第二个数组开始比较)

代码语言:javascript
复制
if ((n[0] < 0 || n[0] > 15) || (n[1]< 0 || n[1] > 15) || sn.indexOfArray(n, 1) >= 0) {
   return alert("GAME OVER");
}
Array.prototype.indexOfArray = function() {
   var len = arguments.length;
    if (1 == len) {
       var arr = arguments[0];
       for (var i = this.length - 1; i >= 0; i--) {
           if (this[i].toString() == arr.toString()) {
                return i;
           }
       }
    }else {
       var arr = arguments[0];
       var index = ~~(arguments[1]);
       for (var i = this.length - 1; i >= index; i--) {
           if (this[i].toString() == arr.toString()) {
                return i;
           }
       }
    }
   return -1;
}

奖励食物

食物生成规则

吃掉食物后生成新的食物,生成食物的坐标要在地图内,生成食物的坐标不可和蛇身体重复

代码语言:javascript
复制
if (dz.toString() == n.toString()) {
   while ((sn.indexOfArray(dz = [~~(Math.random() * 15), ~~(Math.random() *15)])) >= 0);
   draw(dz, "Yellow");
}
获得食物

获得食物,蛇身增长一段(不执行删除尾借点操作)

代码语言:javascript
复制
if (dz.toString() == n.toString()) {
} else
   draw(sn.pop(), "black"); //sn数组去掉最后一个元素

代码

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
 
<head>
   <meta charset="UTF-8">
   <title>Document</title>
   <scriptsrc="http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
 
<body>
   <canvas id="cas" style="border:solid 1px#CCC;background-color: black" height="300"width="300"></canvas>
</body>
<script>
var sn = [ /*存蛇身体坐标的二维数组*/
       [2, 4],
       [1, 4]
   ],
   action = [
       [-1, 0],
       [0, -1],
       [1, 0],
        [0, 1]
   ],
   dz = [3, 4],
   /*食物坐标*/
   rlx = [1, 0],
   /*蛇下一步爬行操作*/
   fx, /*当前方向,即键盘上下左右值*/
   n, /*蛇头坐标*/
   ctx =document.getElementById("cas").getContext("2d");
 
Array.prototype.indexOfArray = function() {
   var len = arguments.length;
   if (1 == len) {
       var arr = arguments[0];
       for (var i = this.length - 1; i >= 0; i--) {
           if (this[i].toString() == arr.toString()) {
                return i;
           }
       }
    }else {
       var arr = arguments[0];
       var index = ~~(arguments[1]);
       for (var i = this.length - 1; i >= index; i--) {
           if (this[i].toString() == arr.toString()) {
                return i;
           }
       }
    }
   return -1;
}
 
function draw(t, c) {
   ctx.fillStyle = c;
   ctx.fillRect(t[0] * 20 + 1, t[1] * 20 + 1, 18, 18);
}
 
document.onkeydown = function(e) {
   if ((fx - e.keyCode) % 2 != 0) {
       fx = e.keyCode;
       rlx = action[e.keyCode - 37] || rlx;
    }
}
 
! function() {
   sn.unshift(n = [sn[0][0] + rlx[0], sn[0][1] + rlx[1]]); //sn数组头部添加一个元素
   if ((n[0] < 0 || n[0] > 15) || (n[1] < 0 || n[1] > 15) ||sn.indexOfArray(n, 1) >= 0) {
       return alert("GAME OVER");
    }
   draw(n, "Lime");
   if (dz.toString() == n.toString()) {
       while ((sn.indexOfArray(dz = [~~(Math.random() * 15), ~~(Math.random() *15)])) >= 0);
       draw(dz, "Yellow");
    }else
       draw(sn.pop(), "black"); //sn数组去掉最后一个元素
   setTimeout(arguments.callee, 130);
}();
</script>
</html>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/06/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 通知
  • 实现思路
    • 背景和蛇实现
      • 蛇的移动和转向
        • 移动
        • 转向
      • 死亡判断
        • 奖励食物
          • 食物生成规则
          • 获得食物
      • 代码
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档