离开屏幕后从游戏中移除一颗子弹
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()
我必须为我在大学的编程课程创建 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()