关于这个问题,我最先想到的就是炸弹的使用方式是键盘按压式,还是敲击键盘式,(即key_pressed 或 KEYDOWN)。那么现在你可以想想这里有没有弄错了。
后来我发现确实是用了KEYDOWN的方法,还是出现这种状况,那我就开始思考问题究竟出现在哪?
if not pause:
if event.type == pg.KEYDOWN: #全屏炸弹
if event.key== pg.K_SPACE and bomb_count > 0:
bomb_count -= 1
bomb_sound.play()
print('go on')
for each in groups:
if each.rect.bottom > 0:
each.alive = False
在这里我就想到一个简单方便检测bug的方法,我在我要检测错误的地方加上一条print语句,其中的内容并不重要,重要的是看print语句有没有被执行,或者执行了几次。(也可以写成print(bomb_count),这样可以直观的看到炸弹数量的减少,而且是由这段代码引起的)
结果却如图所示,go on 被打印了多次???
这时我就要思考了,为什么一个KEYDOWN的事件会背执行这么多次??
这里我就想到, 有没有可能是因为敌机爆炸的动画延时了大概12帧左右导致的?但是我随机就发现,我的if判断语句好像没有联系到敌机是否爆炸(即enemy.alive == False或者True),所以这个猜想是不太可能成立的。
于是我只能重新读自己写的又臭又长的代码,自我感觉好像没问题,这时我实在没办法,我就思考会不会是语句之间顺序的问题???
我把前面那段代码提到最前面,就像这样:
while running:
for event in pg.event.get():
if event.type == pg.KEYDOWN:
if event.key== pg.K_SPACE: #全屏炸弹
bomb_count -= 1
bomb_sound.play()
for each in groups:
if each.rect.bottom > 0:
each.alive = False
然后我震惊的发现,再次按空格键,炸弹居然没有再减少到 0 。这么说就是语句顺序出现了问题,于是我重新读自己的代码,原来未修改的错误代码如下:
while running:
for event in pg.event.get():
if me.life == 0:
running = False
elif event.type == pg.QUIT:
pg.quit() #这个必须在sys.quit前面,否则程序冲突
sys.exit()
elif event.type == SUPPLY: #补给发放
supply_sound.play()
if random.choice([True,False]):
bo_supply.reset()
else:
bu_supply.reset()
elif event.type == pg.MOUSEBUTTONDOWN: #鼠标点击切换暂停
if event.button == 1 and pause_rect.collidepoint(event.pos):
pause = not pause
elif event.type == pg.MOUSEMOTION:
if pause_rect.collidepoint(event.pos):
if pause:
pause_image = resume_pressed_image
else:
pause_image = pause_pressed_image
else:
if pause:
pause_image = resume_nor_image
else:
pause_image = pause_nor_image
screen.blit(bg,(0,0)) #把屏幕重新绘制,防止暂停偷看屏幕
if not pause: #游戏暂停
if event.type == pg.KEYDOWN:
if event.key== pg.K_SPACE: #全屏炸弹
bomb_count -= 1
bomb_sound.play()
for each in groups:
if each.rect.bottom > 0:
each.alive = False
key_pressed = pg.key.get_pressed() #获得哪些按键被长按
if key_pressed[pg.K_w] or key_pressed[pg.K_UP]: #游戏操作
me.moveUp()
if key_pressed[pg.K_s] or key_pressed[pg.K_DOWN]:
me.moveDown()
if key_pressed[pg.K_a] or key_pressed[pg.K_LEFT]:
me.moveLeft()
if key_pressed[pg.K_d] or key_pressed[pg.K_RIGHT]:
me.moveRight()
仔细地读一读,不难发现screen.blit(if not pause这句也是)这一语句居然和for event这一语句的递进关系处于同一级!这就表明当程序执行到这时前面的for event in pg.event.get()语句中的event已经结束了,那么我的空格键事件当然不会再正常执行。
于是解决方法就出来了,我们只需要把空格的那段语句提前到screen.blit语句前面就好了,但是要注意的是我们这里有暂停功能的,那么暂停后,你总不能按爆炸吧。因此还要在前面加上一句if not pause:即可。
部分正确代码:
elif not pause:
if event.type == pg.KEYDOWN:
if event.key== pg.K_SPACE: #全屏炸弹
bomb_count -= 1
bomb_sound.play()
for each in groups:
if each.rect.bottom > 0:
each.alive = False
screen.blit(bg,(0,0)) #把屏幕重新绘制,防止暂停偷看屏幕
if not pause: #游戏暂停
key_pressed = pg.key.get_pressed() #获得哪些按键被长按
if key_pressed[pg.K_w] or key_pressed[pg.K_UP]: #游戏操作
me.moveUp()
if key_pressed[pg.K_s] or key_pressed[pg.K_DOWN]:
me.moveDown()
if key_pressed[pg.K_a] or key_pressed[pg.K_LEFT]:
me.moveLeft()
if key_pressed[pg.K_d] or key_pressed[pg.K_RIGHT]:
me.moveRight()
总结:写代码的经验还是太少,相对于这种复制大型一点的代码,语句的逻辑混乱就出现了,看来我还是要再多加练习。。。