Pygame飞机大战为什么一按空格键所有炸弹都用光了?

关于这个问题,我最先想到的就是炸弹的使用方式是键盘按压式,还是敲击键盘式,(即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()

总结:写代码的经验还是太少,相对于这种复制大型一点的代码,语句的逻辑混乱就出现了,看来我还是要再多加练习。。。

猜你喜欢

转载自blog.csdn.net/The_RedMaple/article/details/106093210