Reputation: 103
I am currently doing an exercise in python crash course where I have multiple rows of stars and I am making all of them move downwards towards the bottom of the screen. When I change the settings to make the stars move to the side instead, everything works. However, when I try to make them move downwards, only one row of stars appear at the very top of the screen and then they move down(as opposed to the whole screen being populated with aliens that move down). Not sure what is causing the issue, and would greatly appreciate any help and assistance. Thank you all!
stars_game.py
from star import Star
from random import randint
class StarGame:
def __init__(self):
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode(
(0,0), pygame.FULLSCREEN)
self.settings.screen_width = self.screen.get_rect().width
self.settings.screen_height = self.screen.get_rect().height
pygame.display.set_caption("Star Game")
self.stars = pygame.sprite.Group()
self._create_fleet()
def run_game(self):
while True:
self._check_events()
self._update_stars()
self._update_screen()
def _create_fleet(self):
star = Star(self)
star_width, star_height = star.rect.size
#star_width += 20
#star_height += 20
available_space_x = self.settings.screen_width - (2 * star_width)
number_stars_x = available_space_x // (2 * star_width)
available_space_y = (self.settings.screen_height - 2 * star_height)
number_rows = available_space_y // (2 * star_height)
for row_number in range(number_rows):
for star_number in range(number_stars_x):
self._create_star(star_number, row_number)
def _create_star(self, star_number, row_number):
star = Star(self)
star_width, star_height = star.rect.size
star.x = star_width + 2 * star_width * star_number
star.rect.x = star.x
star.rect.y = star.rect.height + 2 * star.rect.height * row_number
self.stars.add(star)
def _update_stars(self):
"""Update the positions of all stars in the fleet."""
self.stars.update()
def _check_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
sys.exit()
def _update_screen(self):
self.screen.fill(self.settings.bg_color)
self.stars.draw(self.screen)
pygame.display.flip()
if __name__ == '__main__':
sg = StarGame()
sg.run_game()
settings.py
class Settings:
"""A class to store all settings for Alien Invasion."""
def __init__(self):
"""Initialise the game's settings."""
#Screen settings
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230, 230, 230)
self.star_speed = 1.0
star.py
import pygame
from pygame.sprite import Sprite
class Star(Sprite):
def __init__(self, sg_game):
super().__init__()
self.screen = sg_game.screen
self.settings = sg_game.settings
self.image = pygame.image.load('images/alien.bmp')
self.rect = self.image.get_rect()
self.rect.x = self.rect.width
self.rect.y = self.rect.height
self.x = float(self.rect.x)
self.y = float(self.rect.y)
def update(self):
self.y += self.settings.star_speed
self.rect.y = self.y
Upvotes: 1
Views: 158
Reputation: 210880
You have to initialize star.y
attribute instead of star.rect.y
in the _create_star
method:
class StarGame:
# [...]
def _create_star(self, star_number, row_number):
star = Star(self)
star_width, star_height = star.rect.size
star.x = star_width + 2 * star_width * star_number
star.y = star.rect.height + 2 * star.rect.height * row_number
self.stars.add(star)
However, synchronize the position stored in the rect
attribute in update
, via the x
and y
attribute:
class Star(Sprite):
# [...]
def update(self):
self.y += self.settings.star_speed
self.rect.topleft = round(self.x), round(self.y)
Upvotes: 2