Reputation: 115
My Alien Invasion game does not show bullets being fired. I am copying most of the code from the Python Crash Course book (with minor changes here and there), so I'm guessing it is due to a syntax error that I can't find.
I've looked over the code in the book and tried to find differences between them. I changed K_SPACE to K_w to see if the spacebar wasn't registering or something like that, but the bullets still would not fire.
alien_invasion.py
import pygame
from pygame.sprite import Group
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
# initialize game and create a screen object
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode(
(ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption('Alien Invasion')
# set the background color
bg_color= ai_settings.bg_color
# make a ship
ship = Ship(ai_settings, screen)
# make a group to store bullets in
bullets = Group()
# start the main loop for the game
running = True
while running:
running = gf.check_events(ai_settings, screen, ship, bullets)
ship.update()
bullets.update()
gf.update_screen(ai_settings, screen, ship, bullets)
pygame.quit()
run_game()
game_functions.py
import pygame
from bullet import Bullet
def check_events(ai_settings, screen, ship, bullets):
"""respond to keypresses and mouse events"""
running = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False # different from Python Crash Course
elif event.type == pygame.KEYDOWN:
check_keydown_events(event, ai_settings, screen, ship, bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event, ship)
return running
def update_screen(ai_settings, screen, ship, bullets):
"""update images on the screen and flip to the new screen"""
# redraw the screen during each pass through the loop
screen.fill(ai_settings.bg_color)
ship.blitme()
# make the most recently drawn screen visible
pygame.display.flip()
# redraw all bullets behind ship and aliens
for bullet in bullets.sprites():
bullet.draw_bullet()
def check_keydown_events(event, ai_settings, screen, ship, bullets):
"""respond to keypresses"""
if event.key == pygame.K_d:
ship.moving_right = True
elif event.key == pygame.K_a:
ship.moving_left = True
elif event.key == pygame.K_SPACE:
# create a new bullet and add it to the bullets groups
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)
def check_keyup_events(event, ship):
"""respond to key releases"""
if event.key == pygame.K_d:
ship.moving_right = False
elif event.key == pygame.K_a:
ship.moving_left = False
bullet.py
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
"""a class to manage bullets fired from the ship"""
def __init__(self, ai_settings, screen, ship):
"""create a bullet object at the ship's current position"""
super().__init__()
self.screen = screen
# create a bullet rect at (0, 0) and then set correct position
self.rect = pygame.Rect(0, 0, ai_settings.bullet_width, ai_settings.bullet_height)
self.rect.centerx = ship.rect.centerx
self.rect.top = ship.rect.top
# store the bullet's position as a decimal value
self.y = float(self.rect.y)
self.color = ai_settings.bullet_color
self.speed_factor = ai_settings.bullet_speed_factor
def update(self):
"""move the bullet up the screen"""
# update the decimal position of the bullet
self.y -= self.speed_factor
# update the rect position
self.rect.y = self.y
def draw_bullet(self):
"""draw the bullet to the screen"""
pygame.draw.rect(self.screen, self.color, self.rect)
left out settings.py and ship.py but can provide them if necessary
Expected outcome: bullet go pew pew
Actual outcome: Game does not crash, but nothing happens when spacebar is pressed.
Upvotes: 2
Views: 1113
Reputation: 110456
The problem seems to be on the update_screen
function - you first draw
everything, updates the screen, and then draws the bullets, after the screen is updated. Simply moving the call to ...display.flip()
to the end of the function might make your bullets show up (unless there is something other that is also wrong).
def update_screen(ai_settings, screen, ship, bullets):
"""update images on the screen and flip to the new screen"""
# redraw the screen during each pass through the loop
screen.fill(ai_settings.bg_color)
ship.blitme()
# take this out of here
# pygame.display.flip()
# redraw all bullets behind ship and aliens
for bullet in bullets.sprites():
bullet.draw_bullet()
# to here
pygame.display.flip()
Upvotes: 4