pygame飞机游戏运行一段时间后就报错,请大佬们看一下,谢谢

用pygame做的飞机游戏运行一段时间就会报错

import pygame
import random
import math

# 初始化
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("飞机大战2")
icon = pygame.image.load("./resource/ufo.png")
pygame.display.set_icon(icon)
bgimg = pygame.image.load("./resource/bg.png")

# 背景音乐
pygame.mixer.music.load("./resource/bg.wav")
pygame.mixer.music.play(-1)

# 射中音效
bao_sound = pygame.mixer.Sound("./resource/exp.wav")

# 飞机
playerimg = pygame.image.load("./resource/player.png")
playerx = 400
playery = 500
playerStep = 0

# 分数
score = 0
font = pygame.font.Font("freesansbold.ttf", 32)


def show_score():
    text = f"score:    {score}"
    score_render = font.render(text, True, (0, 255, 0))
    screen.blit(score_render, (10, 10))


# 游戏结束
is_over = False
over_font = pygame.font.Font("freesansbold.ttf", 64)


def check_is_over():
    if is_over:
        text = "GAME OVER"
        render = over_font.render(text, True, (255, 0, 0))
        screen.blit(render, (200, 250))


# 添加敌人
number_of_enemies = 6


class Enemy:

    def __init__(self):
        self.img = pygame.image.load("./resource/enemy.png")
        self.x = random.randint(200, 600)
        self.y = random.randint(50, 250)
        self.step = random.randint(2, 6)

    def reset(self):
        self.x = random.randint(200, 600)
        self.y = random.randint(50, 250)


enemies = []
for i in range(number_of_enemies):
    enemies.append(Enemy())


def distance(bx, by, ex, ey):
    a = bx - ex
    b = by - ey
    return math.sqrt(a * a + b * b)


class Bullet:
    def __init__(self):
        self.img = pygame.image.load("./resource/bullet.png")
        self.x = playerx + 16
        self.y = playery + 10
        self.step = 10

    def hit(self):
        global score
        for e in enemies:
            if distance(self.x, self.y, e.x, e.y) < 30:
                # 子弹命中
                bao_sound.play()
                bullets.remove(self)
                e.reset()
                score += 1
                print(score)


bullets = []


def show_bullets():
    for b in bullets:
        screen.blit(b.img, (b.x, b.y))
        b.hit()
        b.y -= b.step
        if b.y < 0:
            bullets.remove(b)


def show_enemy():
    global is_over
    for e in enemies:
        screen.blit(e.img, (e.x, e.y))
        e.x += e.step
        if e.x > 736 or e.x < 0:
            e.step *= -1
            e.y += 40
            if e.y > 450:
                is_over = True
                print("游戏结束啦")
                enemies.clear()


def move_player():
    global playerx
    playerx += playerStep
    # 防止飞机出界
    if playerx > 736:
        playerx = 736
    if playerx < 0:
        playerx = 0


# 游戏主循环
running = True
while running:
    screen.blit(bgimg, (0, 0))
    show_score()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        # 控制飞机移动
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_RIGHT]:
            playerStep = 5
        elif keys_pressed[pygame.K_LEFT]:
            playerStep = -5
        else:
            playerStep = 0
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                print("发射子弹")
                # 创建子弹
                b = Bullet()
                bullets.append(Bullet())

    screen.blit(playerimg, (playerx, playery))
    move_player()
    show_enemy()
    show_bullets()
    check_is_over()
    pygame.display.update()
最佳答案

你的代码中的一些部分可能会引起问题,以下是我发现的一些可能的问题和解决方案:

  1. 子弹创建问题:在你按下空格键时,你实际上创建了两个子弹对象,并将其中一个添加到了bullets列表中。在bullets.append(Bullet())这一行,你应该将已经创建的子弹对象b添加到列表中,而不是新创建一个对象。

  2. 子弹和敌人碰撞检测问题:在迭代bullets列表并删除其中的元素时,你可能会遇到运行时错误。一个更好的解决方案是将要删除的子弹添加到一个单独的列表中,并在迭代完成后删除它们。同样的问题可能也存在于enemies列表中。

  3. 事件处理问题:你在处理键盘事件时可能会遇到问题,因为你在主循环中混合使用了事件处理和keys_pressed检测。

针对以上问题,以下是一些修改建议:

  1. 修复子弹创建

    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_SPACE:
            print("发射子弹")
            # 创建子弹
            b = Bullet()
            bullets.append(b)  # 使用已创建的对象b
  2. 改进子弹和敌人碰撞检测

    def show_bullets():
        bullets_to_remove = []
        for b in bullets:
            screen.blit(b.img, (b.x, b.y))
            b.hit()
            b.y -= b.step
            if b.y < 0:
                bullets_to_remove.append(b)
        for b in bullets_to_remove:
            bullets.remove(b)
  3. 改进事件处理:你可以将键盘移动逻辑移动到事件处理之外,以便更好地控制玩家移动:

    keys_pressed = pygame.key.get_pressed()
    if keys_pressed[pygame.K_RIGHT]:
        playerStep = 5
    elif keys_pressed[pygame.K_LEFT]:
        playerStep = -5
    else:
        playerStep = 0
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        # 其他事件处理逻辑

这些修改应该有助于改善代码的稳定性并减少运行时错误。如果你遇到特定的错误消息,请提供详细信息,这样我可以更准确地确定问题所在。

8个月前 评论
jianggaojun (楼主) 8个月前
讨论数量: 2

你的代码中的一些部分可能会引起问题,以下是我发现的一些可能的问题和解决方案:

  1. 子弹创建问题:在你按下空格键时,你实际上创建了两个子弹对象,并将其中一个添加到了bullets列表中。在bullets.append(Bullet())这一行,你应该将已经创建的子弹对象b添加到列表中,而不是新创建一个对象。

  2. 子弹和敌人碰撞检测问题:在迭代bullets列表并删除其中的元素时,你可能会遇到运行时错误。一个更好的解决方案是将要删除的子弹添加到一个单独的列表中,并在迭代完成后删除它们。同样的问题可能也存在于enemies列表中。

  3. 事件处理问题:你在处理键盘事件时可能会遇到问题,因为你在主循环中混合使用了事件处理和keys_pressed检测。

针对以上问题,以下是一些修改建议:

  1. 修复子弹创建

    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_SPACE:
            print("发射子弹")
            # 创建子弹
            b = Bullet()
            bullets.append(b)  # 使用已创建的对象b
  2. 改进子弹和敌人碰撞检测

    def show_bullets():
        bullets_to_remove = []
        for b in bullets:
            screen.blit(b.img, (b.x, b.y))
            b.hit()
            b.y -= b.step
            if b.y < 0:
                bullets_to_remove.append(b)
        for b in bullets_to_remove:
            bullets.remove(b)
  3. 改进事件处理:你可以将键盘移动逻辑移动到事件处理之外,以便更好地控制玩家移动:

    keys_pressed = pygame.key.get_pressed()
    if keys_pressed[pygame.K_RIGHT]:
        playerStep = 5
    elif keys_pressed[pygame.K_LEFT]:
        playerStep = -5
    else:
        playerStep = 0
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        # 其他事件处理逻辑

这些修改应该有助于改善代码的稳定性并减少运行时错误。如果你遇到特定的错误消息,请提供详细信息,这样我可以更准确地确定问题所在。

8个月前 评论
jianggaojun (楼主) 8个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!