首先我们获取 body 数组的长度 存入i 中,然后倒序倒序倒序遍历 i ,根据 i 作为索引, 从蛇尾巴开始向蛇脑袋遍历,大家想象一下,贪吃蛇的蛇身是不是都是按部就班的沿着脑袋走过的路径走的? 你给它绕个直角、或者正方形它总是老老实实的走完,所以我们每次移动,只需要控制蛇脑袋移动,让蛇身体让它他们挨个获取他们前面那一节身体的坐标就可以了
所以,这里我们倒序遍历,将第 i 节身体赋值前一节身体的 x 属性和 y 属性
蛇身的重新赋值做完了,我们判断一下蛇头的移动方向,因为是固定的4个方向,所以这里使用switch较为方便,
根据 上、下、左、右不一样的情况对 头部的x和y增加或减少
既然是贪吃蛇,我们食物也创建好了,需要实现贪吃蛇吃食物这个过程
首先我们分别计算出 蛇脑袋和食物的X和Y
然后,我们判断一下,
当蛇脑袋的x,y 和食物的x,y都相等的时候,
我们延长一节蛇身,这里我复制了一份最后一节蛇身体 然后追加入body数组,注意!
因为对象是引用类型,所以必须这样拆开赋值
最后,再调用一次食物的初始化,产生新的食物
同样的,这里我也将,Snake 对象暴露给window,供下方的Game.js中的代码调用
Game.js 代码分析
在Game.js中,开头就定义了that
用来保存this 的指向,供后面使用
我们分别实例化一个 “食物”对象和一个“贪吃蛇”对象
传入地图对象,并赋值
、属性设置好了
那既然是游戏那我们是不是应该设定点游戏规则,
当我们的小蛇到达地图边界时,小蛇就会一头撞死了,游戏结束,
并且我们也没有实现小蛇的移动,让我们来接着实现吧
这里我定义了一个runSnake函数,传入 food 和map 对象
首先,定义一个计时器,存入timeId这个变量中
调用一个蛇的 move(移动) 和 init (初始化函数)
在小蛇成功移动之后,我们再判断一下,小蛇是否已经走到边界了,
计算出,地图宽度最多能被蛇头的宽度分为几份,高度同理
取出蛇头自身的x和y
判断 如果蛇头x<0 说明越过左边界,超过maxX则说明超过右边界,
y同理
如果越过边界,则清除定时器,执行一个弹框
注意,我在这个定时器中的方法后加个一个bind 并传入了开始定义的 that ,也就是提前保存的this 指向,如果不加,这里的代码多处用到了this ,因为setInterVal 的指向为window 所以会导致代码出现错误,无法找到这些方法和属性
接下来我们再来实现一下如何用键盘控制小蛇的移动
根据keycode 来更改 snake对象的 direction ,
同样的,此处的this 指向也不正确,指向的是 触发该事件的对象,这是无法调用snake对象的,所以我们必须改变它,在bind中传入(that)
然后将Game 对象暴露给 window
接着定义初始化游戏的函数
分别调用food对象的初始化函数、小蛇的初始化函数,调用runSnake函数开启定时器让小蛇跑起来
最后绑定上keydown 事件
最后的最后
实例化一个Game对象
调用gm 的init 贪吃蛇小demo就实现了
效果展示
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数学运算用法总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript数组操作技巧总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》