Reputation: 1
I am new in learning Python from Python Crash Course by Eric Matthes. In the Alien Invasion project I encountered trouble. I investigated so much, compared the book line by line, but I couldn't find the problem.
Here in the last columns, I didn't get the logic of writing if case?
alien_invasion.py
import sys
import pygame
from settings import Settings
from ship import Ship
class AlienInvasion:
"""Overall class to manage game assets and behavior."""
def __init__(self):
"""Initialize the game, and create game resources."""
pygame.init()
self.settings = Settings()
self.ship = Ship(self)
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("Alien Invasion")
# Set the background color.
# self.bg_color = (self.settings.bg_color)
def run_game(self):
"""Start the main loop for the game."""
while True:
# Watch for keyboard and mouse events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Make the most recently drawn screen visible
pygame.display.flip()
# Redraw the screen during each pass through the loop.
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
if __name__ == '__main__': # investigate the logic of this line of code
# Make a game instance, and run the game.
ai = AlienInvasion()
ai.run_game()
And in ship.py could someone explain to me why we write ai_game
in initial module.
ship.py
import pygame
class Ship:
"""A class to manage the ship."""
def __init__(self, ai_game):
"""Initialize the ship and set its starting position."""
self.screen = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
# Load the ship image and get its rect.
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
# Start each new ship at the bottom center of the screen
self.rect.midbottom = self.screen_rect.midbottom
def blitme(self):
"""Draw the ship at its current location."""
self.screen.blit(self.image, self.rect)
settings.py
class Settings:
"""A class to store all settings for Alien Invasion."""
def __init__(self):
"""Initialize the game settings."""
# Screen settings
self.screen_width = 1000
self.screen_height = 650
self.bg_color = (230, 230, 230)
When I run alien_invasion.py I get the following error:
"C:\Users\User\PycharmProjects\Alien Invasion\venv\Scripts\python.exe" "C:/Users/User/PycharmProjects/Alien Invasion/alien_invasion.py" pygame 1.9.6 Hello from the pygame community. https://www.pygame.org/contribute.html Traceback (most recent call last): File "C:/Users/User/PycharmProjects/Alien Invasion/alien_invasion.py", line 37, in <module> ai = AlienInvasion() File "C:/Users/User/PycharmProjects/Alien Invasion/alien_invasion.py", line 15, in __init__ self.ship = Ship(self) File "C:\Users\User\PycharmProjects\Alien Invasion\ship.py", line 8, in __init__ self.screen = ai_game.screen AttributeError: 'AlienInvasion' object has no attribute 'screen' Process finished with exit code 1
Upvotes: 0
Views: 1351
Reputation: 15309
You simply need two switch these two lines so they are in order, from:
self.ship = Ship(self)
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
to:
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
self.ship = Ship(self)
The reason for this is that you create a Ship
object which wants to access the AlienInvasion
's screen
, so you need to define it before the Ship
, otherwise it's undefined.
Here in the last columns, I didn't get the logic of writing if case?
if __name__ == '__main__'
is a special construct in Python. It means the following block will only be executed if you run the script directly, rather than importing the script inside some other script. It isn't really needed for a game but it's good practice to get used to it anyway.
And in ship.py could someone explain to me why we write
ai_game
in initial module.
The Ship
basically want to have access to the original AlienInvasion
object because it holds information related to the game, like in this case the screen to draw on. The AlienInvasion
object then gets passed as using Ship(self)
which calls Ship.__init__(self, ai_game)
(The left self
turns into the right ai_game
).
Good luck with studying!
Upvotes: 1