离开屏幕后从游戏中移除一颗子弹

Remove a bullet from the game after going off-screen

我必须为我在大学的编程课程创建 Space Invaders 这很好,但是我在离开屏幕后从游戏中删除子弹时遇到问题。游戏中子弹向右移动,离开屏幕后应该会消失,但我不知道如何创建。

子弹结构模块

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    def __init__(self, ai_settings, screen, ship):
        #Creates a bullet object in the current position of the ship
        super(Bullet, self).__init__()
        self.screen = screen

        #Create bullets in position(0,0) and set correct position
        self.rect = pygame.Rect(0, 0
            , ai_settings.bullet_widht, ai_settings.bullet_height)
        self.rect.centery = ship.rect.centery
        self.rect.right = ship.rect.right

        #Position of bullets kept in float format
        self.x = float(self.rect.x)

        self.color = ai_settings.bullet_color
        self.speed_factor = ai_settings.bullet_speed_factor

    def update(self):
        #Moves the bullet right the screen
        #Update a position of bullet in float format
        self.x += self.speed_factor
        #Update a position of rectangle
        self.rect.x = self.x

    def draw_bullet(self):
        #Displaying a bullet on the screen
        pygame.draw.rect(self.screen, self.color, self.rect)

游戏功能模块

import sys
import pygame
from bullet import Bullet

def check_keydown_events(event, ai_settings, screen, ship, bullets):
    #Reacts to keystrokes
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    elif event.key == pygame.K_UP:
        ship.moving_up = True
    elif event.key == pygame.K_DOWN:
        ship.moving_down = True
    elif event.key == pygame.K_SPACE:
        fire_bullets(ai_settings, screen, ship, bullets)

def check_keyup_events(event, ship):
    #Reacts when keys are released
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        ship.moving_left = False    
    elif event.key == pygame.K_UP:
        ship.moving_up = False
    elif event.key == pygame.K_DOWN:
        ship.moving_down = False

def check_events(ai_settings, screen, ship, bullets):
    #Handles keystrokes and mouse events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event, ai_settings, screen, ship, bullets)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event, ship)

def update_screen(ai_settings, screen, ship, bullets):
    #Updates the screen, and the last picture
    screen.fill(ai_settings.bg_color)
    #All bulets Displays behind ship and aliens
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    #Displays the last screen
    pygame.display.flip()

def update_bullets(bullets):
    #Delete bullets, over the edge of the screen
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)

def fire_bullets(ai_settings, screen, ship, bullets):
    #Create a new bullet and add it to the group bullets
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)

我认为您正在使用 pygame.sprite.Group 来跟踪您的子弹,但您可以以更优雅的方式使用它。每个 Bullet 精灵在每个游戏循环中重新绘制,您应该在创建精灵时为 Bullet 创建一个 image 属性,然后调用 bullets.draw() 绘制所有子弹。您的更新功能对于子弹的移动没问题,但您可以添加边界检查并在精灵离开屏幕时将其杀死。

然后在你的主游戏循环中,你可以调用 bullets.update() 来移动子弹,然后调用 bullets.draw() 来绘制子弹。

我已经根据您的代码创建了一个最小示例来说明我的意思。项目符号是在按键时创建的,一旦离开屏幕就会被删除。

import random
import pygame

WIDTH, HEIGHT = 640, 480
FPS = 60

class Bullet(pygame.sprite.Sprite):
    def __init__(self, bullet_width=10, bullet_height=3):
        # Creates a bullet object in the current position of the ship
        super(Bullet, self).__init__()
        # Create a image for the bullet
        self.image = pygame.Surface((bullet_width, bullet_height))
        self.image.fill(pygame.Color("gold"))
        self.rect = self.image.get_rect()
        # set the bullet position to the left of the screen and a random y
        self.rect.x = 0
        self.rect.y = random.randint(0, HEIGHT - bullet_height)
        self.speed_factor = 3

    def update(self):
        # Moves the bullet right the screen
        self.rect.x += self.speed_factor
        # remove the sprite from the group if it is off the screen
        if self.rect.x > WIDTH:
            self.kill()

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
bullets = pygame.sprite.Group()

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            # spawn a bullet
            bullets.add(Bullet())
    # update game state
    bullets.update()
    # draw the background
    screen.fill(pygame.Color("turquoise"))
    # draw bullets
    bullets.draw(screen)
    # update display
    pygame.display.update()
    # update window title to display the number of bullets
    pygame.display.set_caption(f"Bullets: {len(bullets.sprites())}")
    clock.tick(FPS)
pygame.quit()