pygame开发坦克游戏时玩家与敌人碰撞触发游戏冻结如何解决
坦克版太空侵略者游戏冻结问题修复
问题根因
1. 退出流程错误
你在QUIT事件处理中先执行了pygame.quit()再将running设为False,循环后续仍会执行screen.blit、pygame.display.update()等pygame接口调用,已销毁的pygame实例执行这些操作会直接触发无响应。
2. 碰撞检测逻辑缺陷
子弹与敌人碰撞检测时,你将sort排序操作放在了碰撞触发的分支内,每检测到一次碰撞就执行两次排序,当子弹、敌人数量较多时性能开销会大幅上升;同时如果多个子弹命中同一个敌人,待删除的索引列表会出现重复值,删除时会触发索引越界报错导致冻结。
3. 玩家碰撞处理逻辑不全
玩家和敌人碰撞时,仅加载了gameover图片没有展示,也没有做后续退出处理,设置running=False后循环后续的pygame操作同样会触发无响应。
4. 冗余代码浪费性能
循环末尾三段手动清空临时列表的代码完全多余,每次循环都会重新初始化这三个列表,额外占用计算资源。
修复后的完整代码
import pygame import random WIDTH=600 HEIGHT=600 FPS = 60 WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) BLUE = (0, 0, 255) # 修复原颜色定义错误 GREEN = (48, 69, 48) pygame.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) clock = pygame.time.Clock() # 提前加载gameover图片,避免运行时加载卡顿 gameover_img = pygame.image.load("gameover.PNG") player_img = pygame.image.load('transparentplayer.png') player = player_img.get_rect() player.centerx = WIDTH // 2 player.bottom = HEIGHT - 50 enemy_img = pygame.image.load('transparent.png') enemies = [] for i in range(3): enemy = enemy_img.get_rect() enemy.x = random.randint(0, WIDTH - 103) enemy.y = -50 enemies.append(enemy) bullet_img = pygame.image.load('transparentbullet.png') bullets = [] direction = 'none' running = True game_over = False while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if not game_over and event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: direction = 'left' if event.key == pygame.K_RIGHT: direction = 'right' if event.key == pygame.K_UP: direction = 'up' if event.key == pygame.K_DOWN: direction = 'down' if event.key == pygame.K_SPACE: bullet = bullet_img.get_rect() bullet.centerx = player.centerx bullet.y = player.top bullets.append(bullet) if event.type == pygame.KEYUP and event.key != pygame.K_SPACE: direction = 'none' if not game_over: screen.fill(GREEN) if direction == 'left': if player.x > 0: player.x -= 4 if direction == 'right': if player.right < WIDTH: player.x += 4 if direction == 'up': if player.y > 0: player.y -= 4 if direction == 'down': if player.bottom < HEIGHT: player.y += 4 for enemy in enemies: enemy.y += 3 if enemy.top > HEIGHT: enemy.y = -70 enemy.x = random.randint(0, WIDTH - 103) for enemy in enemies: screen.blit(enemy_img, (enemy.x, enemy.y)) for bullet in bullets: bullet.y -= 3 for bullet in bullets: screen.blit(bullet_img, (bullet.x, bullet.y)) temp = [] for i in range(len(bullets)): if bullets[i].y < 0: temp.append(i) temp.sort(reverse=True) for i in temp: del bullets[i] temp1 = [] temp2 = [] for i in range(len(bullets)): for j in range(len(enemies)): if bullets[i].colliderect(enemies[j]): temp1.append(i) temp2.append(j) # 排序移到循环外,且先去重避免索引错误 temp1 = sorted(list(set(temp1)), reverse=True) temp2 = sorted(list(set(temp2)), reverse=True) for i in temp1: del bullets[i] for i in temp2: del enemies[i] for enemy in enemies: if player.colliderect(enemy): game_over = True break screen.blit(player_img, (player.x, player.y)) else: # 显示gameover图片 screen.blit(gameover_img, (0,0)) pygame.display.update() clock.tick(FPS) pygame.quit()
内容的提问来源于stack exchange,提问作者tornadogrmk1
相关产品推荐
相关产品推荐

