Reputation: 25
I have to create Space Invaders for my programming course in college which would be fine, but I have a problem with removing a bullet from the game after going off-screen. In the game, the bullets move to the right and should disappear after leaving the screen, but I do not know how to create it.
It's a module of bullet structure
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)
It's a game function module
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)
Upvotes: 1
Views: 422
Reputation: 3245
I think you're using a pygame.sprite.Group
to keep track of your bullets, but you can use it in a more elegant way. Each Bullet
sprite is redrawing every game loop, you should create an image
attribute for Bullet
on sprite creation, then call bullets.draw()
to draw all the bullets. Your update function is fine for the bullet movement, but you can add the bounds check and kill the sprite if it is off the screen.
Then in your main game loop, you can just call bullets.update()
to move the bullets, and bullets.draw()
to draw the bullets.
I've created a minimal example to show what I mean, based on your code. Bullets are created on a key press and removed once they're off the screen.
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()
Upvotes: 1