17.3.1 添加move方法
Move方法如下所示:
让我们一段一段地来介绍这个方法。
创建新的头部
在❶处,将this.segments数组的第一个元素保存到了变量head中。在该方法中,将多次引用贪吃蛇的这个第一段,因此,使用这个变量将减少很多录入,并且使得代码更容易阅读一些。现在,我们直接输入head,而不必一次次地重复使用this.segments[0]。
在❷处,创建了变量newHead,它将用来存储表示贪吃蛇的新头部的(这是我们准备添加的)块。
在❸处,将this.direction设置为和this.nextDirection相等,这会将贪吃蛇的移动方向更新为与最近按下的箭头键一致(当我们介绍keydown事件处理程序的时候,将会更详细地看到这是如何工作的)。
Direction和nextDirection
对于动画中的每一步,贪吃蛇的Direction属性都会更新一次,因为每个动画步骤都会调用一次move方法。另一方面,当玩家在任何时候按下一个箭头键,nextDirection属性都会更新(因此,如果玩家按键真的很愉,这个属性理论上可能会在每个动画步骤中更新多次)。通过保持这两个属性各自分离,我们确保了如果玩家在动画的两个步骤之间非常快速地按下两个箭头键,贪吃蛇不会回过头来碰到自己。
从❹处开始,使用一系列的if…else语句来确定贪吃蛇的方向 ,在每种情况下,我们为贪吃蛇创建了一个新的头部并且将其保存到变量newHead中。根据移动的方向,给已有的头部加上或减去一个行或列,从而直接将这个新的头部放到旧的头部的旁边(根据贪吃蛇移动的方向,在右边、左边、上边或下边)。例如,图17-5展示了当this.nextDirection设置为”down”的时候,如何给贪吃蛇添加新的头部。
图17-5当this.nextDirection为”down”的时候创建newHead
检查碰撞并添加头部
在❺处,调用checkCollision方法来确定贪吃蛇是否和墙或者自身发生碰撞。稍后再来看这个方法的代码,但是,你可能猜到了,如果贪吃蛇和某些物体发生碰撞,该方法会返回true。如果发生这种情况,if语句的主体部分会调用gameOver函数来结束游戏,并且在画布上显示”Game Over”。
跟在gameOver后面的return关键字,会退出前面的move方法,跳过其后面的任何代码。只有在checkCollisison返回true的时候,才会遇到return关键字,因此,如果贪吃蛇没有和任何物体发生碰撞,将会执行剩余的代码。
只要贪吃蛇没有和某个物体碰撞,就会在贪吃蛇的前面添加新的头部,在❻处,通过使用unshift把newHead添加到segments数组的开始,从而做到这一点。要了解unshift方法如何用于数组的更多细节,参见3.6.2小节。
吃苹果
在❼处,使用equal方法来比较newHead和apple.position。如果这两个块位于相同的位置,equal方法将会返回true,这意味着,贪吃蛇吃掉了苹果。
如果贪吃蛇吃掉了苹果,我们增加分数然后在苹果上调用move将其移动到一个新的位置。如果贪吃蛇没有吃掉苹果,在this.segments之上调用pop。这将会删除贪吃蛇的尾部,并保持贪吃蛇为同样的大小(因为move已经在贪吃蛇的头部添加了一个段)。当贪吃蛇吃掉苹果的时候,它会长长一段,因为我们向其头部添加了一个段而没有删除掉尾部。
我们还没有定义apple,因上经,这个方法的当前版本还不能完整地工作。如果你想要测试它,可以删除位于❼的整个if…else语句,并用如下的代码行替代它:
this.segments.pop();
然后,你需要做的只是定义checkCollision方法,我们接下来就干这件事情。
本站内容未经许可,禁止任何网站及个人进行转载。