Apr-04-2017, 06:47 PM
I have 5 files that tie together to create a simple alien invaders type game. While adding the bullet function I've made a mistake somewhere and cannot find it. The game starts up just fine and the ship is able to move_left and move_right. When the K_SPACE is depressed the game crashes and leaves a traceback which is hard to follow. This is all the code from each file and the traceback:
alien_invasion.py:
alien_invasion.py:
import pygame from settings import Settings from ship import Ship import game_functions as gf from pygame.sprite import Group def run_game(): # Initialize pygame, settings, and create a screen obj. pygame.init() ai_settings = Settings() screen = pygame.display.set_mode( (ai_settings.screen_width, ai_settings.screen_height)) pygame.display.set_caption("Alien Invasion") # Make ship. ship = Ship(ai_settings, screen) # Make bullet group to store bullets in. bullets = Group() # Start the main loop for game. while True: gf.check_events(ai_settings, screen, ship, bullets) ship.update() bullets.update() gf.update_screen(ai_settings, screen, ship, bullets) run_game()game_functions.py:
import sys import pygame from bullet import Bullet def check_keydown_events(event, ai_settings, screen, ship, bullets): if event.key == pygame.K_RIGHT: ship.moving_right = True elif event.key == pygame.K_SPACE: new_bullet = Bullet(ai_settings, screen, ship) bullets.add(new_bullet) elif event.key == pygame.K_LEFT: ship.moving_left = True def check_keyup_events(event, ship): if event.key == pygame.K_RIGHT: ship.moving_right = False elif event.key == pygame.K_LEFT: ship.moving_left = False def check_events(ai_settings, screen, ship, bullets): """ Respond to keypresses and moust events. """ # Watch for keyboard 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): """ Update images on the screen. """ # Redraw all bullets behind ship and aliens. for bullet in bullets.sprites(): bullet.draw_bullet() # Redraw the screen during each pass through the loop. screen.fill(ai_settings.bg_color) ship.blitme() # Make most recently drawn screen visible. pygame.display.flip()settings.py:
class Settings(): """ A class to store all settings for Alien Invasion. """ def __init__(self): """ Initialize the game's settings. """ # Screen settings self.screen_width = 1200 self.screen_height = 700 self.bg_color = (230, 230, 230) # Ship settings self.ship_speed_factor = 1.5 # Bullet settings self.bullet_speed_factor = 1 self.bullet_width = 3 self.bullet_height = 15 self.bullet_color = 60, 60, 60bullet.py:
import pygame from pygame.sprite import Sprite class Bullet(Sprite): def __init(self, ai_settings, screen, ship): """ Create a bullet object at the ships current position. """ super(Bullet, self).__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 bullets 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)ship.py:
import pygame class Ship(): def __init__(self, ai_settings, screen): """ Initialize the ship and set its starting position. """ self.screen = screen self.ai_settings = ai_settings # Load the ship image and get its rect. self.image = pygame.image.load('images/ship.bmp') self.rect = self.image.get_rect() self.screen_rect = screen.get_rect() # Start each new ship at the bottom center of the screen. self.rect.centerx = self.screen_rect.centerx self.rect.bottom = self.screen_rect.bottom self.center = float(self.rect.centerx) # Movement flag self.moving_right = False self.moving_left = False def update(self): """ Update ships position based on the movement flag. """ if self.moving_right and self.rect.right < self.screen_rect.right: self.center += self.ai_settings.ship_speed_factor if self.moving_left and self.rect.left > 0: self.center -= self.ai_settings.ship_speed_factor self.rect.centerx = self.center def blitme(self): """ Draw the ship at its current location. """ self.screen.blit(self.image, self.rect)Traceback:
Error:/usr/bin/python3.5 /root/PythonProjects/alien_invasion/alien_invasion.py
Traceback (most recent call last):
File "/root/PythonProjects/alien_invasion/alien_invasion.py", line 27, in <module>
run_game()
File "/root/PythonProjects/alien_invasion/alien_invasion.py", line 22, in run_game
gf.check_events(ai_settings, screen, ship, bullets)
File "/root/PythonProjects/alien_invasion/game_functions.py", line 29, in check_events
check_keydown_events(event, ai_settings, screen, ship, bullets)
File "/root/PythonProjects/alien_invasion/game_functions.py", line 9, in check_keydown_events
new_bullet = Bullet(ai_settings, screen, ship)
File "/usr/local/lib/python3.5/dist-packages/pygame-1.9.4.dev0-py3.5-linux-x86_64.egg/pygame/sprite.py", line 124, in __init__
self.add(*groups)
File "/usr/local/lib/python3.5/dist-packages/pygame-1.9.4.dev0-py3.5-linux-x86_64.egg/pygame/sprite.py", line 142, in add
self.add(*group)
TypeError: add() argument after * must be an iterable, not Settings
Process finished with exit code 1
I understand this is a lot of code to go through and could take some time to help find the error. Any help is very much appreciated. Thank you in advance.