标签:ODB 结束 lse 总结 连接 段落 过程 打包 解决办法
贪吃蛇游戏已经告一段落了,在完成这个游戏的过程中,我遭遇了许多“坎坷”和“挫折”,下面就几个让我印象深刻的“挫折”做一个具体的讲解,以此来为这个贪吃蛇项目画上一个完整句号。(包括打包这个游戏时遇到的问题及解决方式。)
#贪吃蛇死亡判定 def isdead(self): #条件1——贪吃蛇撞墙 if (self.snake_body[len(self.snake_body)-1][0] == self.living_space[0] - self.size or self.snake_body[len(self.snake_body)-1][0] == self.living_space[0] + self.living_space[2]) or (self.snake_body[len(self.snake_body)-1][1] == self.living_space[1] - self.size or self.snake_body[len(self.snake_body)-1][1] == self.living_space[1] + self.living_space[3]): #print(‘die for me 1‘) return True #条件2——贪吃蛇“追尾” for bodynet in self.snake_body[:-1]: if bodynet == self.snake_body[len(self.snake_body)-1]: #print(‘die for me 2‘) return True
通过贪吃蛇再次因此死亡而呈现的死亡原因(die for me 2)我得出贪吃蛇是因头部触碰到身体其他部位而“死亡”的结论。(即头部坐标与身体其他部分坐标出现重合)。然而在贪吃蛇因为这种情况而死亡时窗体中并没有呈现出其头部与身体其他部分触碰的情形,看来答案只能在代码中寻找了。
#开始主循环 while True: #for _ in range(8): print(‘while start‘) for event in pygame.event.get(): #print(‘get event‘) #print(‘direction‘,DIRECTION) if event.type == QUIT: pygame.quit() exit() elif event.type == KEYDOWN: if event.key == K_LEFT and DIRECTION != ‘RIGHT‘: DIRECTION = ‘LEFT‘ elif event.key == K_RIGHT and DIRECTION != ‘LEFT‘: DIRECTION = ‘RIGHT‘ #print(DIRECTION) elif event.key == K_UP and DIRECTION != ‘DOWN‘: DIRECTION = ‘UP‘ elif event.key == K_DOWN and DIRECTION != ‘UP‘: DIRECTION = ‘DOWN‘ #print(DIRECTION) elif event.key == K_SPACE: pause_flag = 0 while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() exit() if event.type == KEYDOWN: if event.key == K_SPACE: pause_flag = 1 if pause_flag == 1: break elif event.key == K_LSHIFT: SNAKE_SPEED *= 3 print(‘DIRECTION‘,DIRECTION) elif event.type == KEYUP: if event.key == K_LSHIFT: SNAKE_SPEED /= 3 foodbody = food._food_pos #获取当前食物的坐标,用以判断贪吃蛇移动后是否是吃食物 snake.move(DIRECTION,foodbody) #贪吃蛇开始移动 #print(‘before:‘,food._food_pos,snake.snake_body[snake.head]) snakebody = snake.snake_body #获取移动后贪吃蛇的坐标集,用以确保食物不会在贪吃蛇身体中生成 exist = snake.foodstate #获取食物状态标志位,判断食物是否被贪吃蛇吃了 food.if_exist(exist,snakebody) #根据食物状态判断是否随机生成新的食物 #print(‘foodbody:‘,food._food_pos) #print(‘snakebodyhead:‘,snake.snake_body[snake.head]) if snake.isdead(): #判断贪吃蛇是否死亡 #pygame.mixer.music.stop() #print(‘dead:‘,snakebody) print(‘dead‘,DIRECTION) sounddead.play() terminate(screen) else: pass
我在循环开始的地方添加了“print(‘while start‘)",在循环结束的地方,也就是pygame.display.update()之后添加了“print("update")”;通过这两个语句来表示一次while循环的过程,根据这种方法可以分析出贪吃蛇死亡的那次while循环中发生了什么。然后在监测键盘输入的代码之后添加“print(‘DIRECTION‘,DIRECTION)”,以此来打印出监测到的方向DIRECTION的值;并在terminate()之前打印出贪吃蛇死亡前的移动方向做确认。下面是贪吃蛇非正常死亡时命令行显示的结果:
我在第一次看到这个结果时,感到十分纳闷,为什么print("DIRECTION",DIRECTION)这个语句会被执行两次,这明明是在一次while循环里面,真正百思不得其解。后面我看到了在这个语句外面还有一个while循环(之前的暂停功能while循环是写在监听键盘代码的外面),于是就把暂停功能的while循环改了,放到了监听方向的代码之后(改后的代码就是上面贴出的代码);但是,然并卵,还是会出现这种问题,于是我继续把这一段的代码看了一遍,寻找循环语句。
然后我突然就看到了"for event in pygame.event.get():"这句代码,再去看了一下pygame.event.get()方法的详细资料,发现原来问题还真出现在这里。(pygame.event资料链接:http://www.pygame.org/docs/ref/event.html)
通过上面的资料信息可以了解到pygame.event.get()方法返回的是Eventlist,是一个事件序列(多个事件的集合),那么当在键盘按下不同按键的时间间隔足够短,pygame.event.get()方法就会在一次while主循环中获取到多个事件,for event in pygame.event.get(): 语句就会执行不止一次,这样就会出现上面一次while主循环中打印两次DIRECTION的结果。这样一来,如果在游戏初始贪吃蛇移动方向DIRECTION是RIGHT,那么先按下上UP后再按下LEFT,就会使“elif event.key == K_RIGHT and DIRECTION != ‘LEFT‘”中的"and DIRECTION != ‘LEFT‘"语句的作用失效,就会出现贪吃蛇“逆行”的情况导致其头部坐标与身体其他部位的坐标出现重合,进而死亡。
这个bug的解决办法就是换.get()方法改用.poll()方法,因为.poll()方法在一次while主循环中只会监听并返回一个事件,不会出现先UP后LEFT的情况。
GATEWAY_FLAG标志位为1表示贪吃蛇触发了传送门,正在进入
while True: #for _ in range(8): #print(‘while start‘) #进入传送门的过程限制移动 if GATEWAY_FLAG == 1: pygame.event.set_blocked(KEYDOWN) #获取事件 event = pygame.event.poll() #print(‘get event‘) #print(‘direction‘,DIRECTION) #判定事件 if event.type == QUIT: pygame.quit() exit() #控制贪吃蛇移动方向 elif event.type == KEYDOWN: if event.key == K_LEFT and DIRECTION != ‘RIGHT‘: DIRECTION = ‘LEFT‘ elif event.key == K_RIGHT and DIRECTION != ‘LEFT‘: DIRECTION = ‘RIGHT‘ #print(DIRECTION) elif event.key == K_UP and DIRECTION != ‘DOWN‘: DIRECTION = ‘UP‘ elif event.key == K_DOWN and DIRECTION != ‘UP‘: DIRECTION = ‘DOWN‘ #print(DIRECTION)
GATEWAY_FLAG标志位为2表示贪吃蛇已经彻底进入传送门,即将前第三关
#判定是否进行传送 if GATEWAY_FLAG == 2: #恢复贪吃蛇移动锁定 pygame.event.set_allowed(KEYDOWN) GATEWAY_FLAG = 0
贪吃蛇篇章,就此结束。
标签:ODB 结束 lse 总结 连接 段落 过程 打包 解决办法
原文地址:https://www.cnblogs.com/3fman/p/9363097.html