原标题:少儿编程分享:手把手教你用PYTHON编写贪吃蛇(二)

检测和判断

无论我们制作的简单或者复杂的游戏

这都是最关键的两个部分

事件处理循环

61. while True: # 游戏主循环
62. for event in pygame.event.get(): # 事件处理循环
63. if event.type == QUIT:
64. terminate()
65. elif event.type == KEYDOWN:
66. if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT:
67. direction = LEFT
68. elif (event.key == K_RIGHT or event.key == K_d) and direction != LEFT:
69. direction = RIGHT
70. elif (event.key == K_UP or event.key == K_w) and direction != DOWN:
71. direction = UP
72. elif (event.key == K_DOWN or event.key == K_s) and direction != UP:
73. direction = DOWN
74. elif event.key == K_ESCAPE:
75. terminate()

从第61行开始,我们进入了游戏的主循环。第62行的for循环用于进行事件(event)处理。如果事件(event)是QUIT事件,我们将调用terminate()函数 。

如果时间不是QUIT,而是按下键盘(KEYDOWN)的话,我们就检测按下的的键是不是WASD中的某一个。除此之外,我们还需要一个额外的检测, 确保小蛇不会转到和当前行进方向相反的方向,因为这样它就会立马撞到自己啦!例如,如果小蛇在向左行进,而玩家按到了向右的按键,在我们代码的控制下,小蛇是不会做出反应的!

撞击检测

77. # 检测小蛇是否撞到自己或者超出窗口边缘
78. if wormCoords[HEAD]['x'] == -1 or wormCoords[HEAD]['x'] == CELLWIDTH or wormCoords[HEAD]['y'] == -1 or wormCoords[HEAD]['y'] == CELLHEIGHT:
79. return # 游戏结束
80. for wormBody in wormCoords[1:]:
81. if wormBody['x'] == wormCoords[HEAD]['x'] and wormBody['y'] == wormCoords[HEAD]['y']:
82. return # 游戏结束

这段代码中,我们检测小蛇的头是否超出了游戏窗口的边缘,或者撞到了一个被自己的另一段身体占据的小方格。

那么应该如何检测小蛇的头是否超出窗口边缘呢?由于窗口内所有小方格的坐标有一定范围,我们只需要检测小蛇是否超出这个范围就可以了。网格横坐标的范围是0到CEELWIDTH-1,纵坐标的范围是0到CELLHEIGHT-1。因而如果小蛇头部的横坐标为-1(超出窗口左侧)或CELLWIDTH(超出窗口右侧),或者纵坐标为-1(超出窗口上沿)或CELLHEIGHT(超出窗口下沿),小蛇就超出了窗口的范围。

这时,我们的代码会让游戏结束,第79行的return让runGame函数停止并返回到第46行该函数被调用的地方。接着,showGameOverScreen函数被调用,游戏界面上出现了“Game Over”的字样。

第80行到82行对储存在wormCoords中小蛇身体进行循环。wormCoords的索引从0开始,而0储存的是小蛇的头部,小蛇的身体部分从索引1开始,所以我们使用wormCoords[1:]从索引1开始循环。如果小蛇头部的横纵坐标x、y和身体的横纵坐标x、y相等,我们的代码就将结束游戏并退出runGame函数,返回到第46行函数被调用的地方,显示游戏结束页面(和上面相似)。

吃到苹果啦!

84. # 检测小蛇是否吃到苹果
85. if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']:
86. # 暂时不要移除小蛇的尾部
87. apple = getRandomLocation() # 在某处放一个新苹果
88. else:
89. del wormCoords[-1] # 移除小蛇的尾部

这段代码用于检测小蛇是否吃到了苹果,检测方法和上面一段检测小蛇是否撞到了自身相似:如果小蛇头部的横纵坐标x、y和苹果的横纵坐标x、y相同的话,小蛇就吃到了苹果。如果小蛇吃掉了苹果,我们就在一个新的位置放一个新苹果,这个新位置将由getRandomLocation函数随机产生。

如果小蛇没有吃到苹果,我们将小蛇的尾部,即身体的最后一段从wormCoords列表中删去。注意,负数索引值代表从列表的末尾开始数,-1代表列表的最后一项,-2代表倒数第二项。

为了不断更新小蛇的位置,我们需要删除小蛇的尾部并在小蛇移动的方向上画一个新的头部,这样小蛇才能不断行进并且在没吃到苹果的时候保持身体长度不变。代码的第89行移除了小蛇的尾部。在下面的“移动小蛇”模块,即代码的91到100行,我们将会在小蛇移动的方向上添加一段身体作为小蛇移动后的头部。