Nov-22-2024, 10:29 PM
(This post was last modified: Nov-22-2024, 10:29 PM by deanhystad.)
A few problems.
Your aliens list is messed up. Each alien appears twice in the list.
You don't synchronize when the aliens change direction. You change direction part way through moving the aliens. Let's say we have 4 aliens
Your aliens list is messed up. Each alien appears twice in the list.
for row_number in range(5): for column_number in range(6): x = alien_horizontal_spacing + column_number * (alien_width + alien_horizontal_spacing) y = alien_vertical_spacing + row_number * (alien_height + alien_vertical_spacing) alien = alien_image.get_rect(x = alien_horizontal_spacing + column_number * (alien_width + alien_horizontal_spacing), y = alien_vertical_spacing + row_number * (alien_height + alien_vertical_spacing)) aliens.append(alien) # Adding rectangle here a= row_number *20 b= column_number * 20 invader = Invader(x, y) aliens.append(alien) # Adding same rectangle hereYour event loop is wrong. You only process pygame once at the start of the program. Instead of this:
running = True if running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False #sys.quit() while True: screen.fill(0) for alien in aliens: alien.x += alien_speed if alien.x <= 0 or alien.x >= screen_width-alien_width: alien_speed *= -1 for alien in aliens: alien.y += 20 for alien in aliens: screen.blit(alien1,(alien))It should look like this:
running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False screen.fill(0) for alien in aliens: alien.x += alien_speed if alien.x <= 0 or alien.x >= screen_width-alien_width: alien_speed *= -1 for alien in aliens: alien.y += 20 for alien in aliens: screen.blit(alien1,(alien))That will let you quit the game. Eventually when you add key press or mouse events you'll need the event loop to continue running during the entirety of the game.
You don't synchronize when the aliens change direction. You change direction part way through moving the aliens. Let's say we have 4 aliens
1 2 3 4The aliens are moving left to right (speed = 1) when alien 2 collides with the right side of the screen. When this happens, the aliens change direction (speed = -1) and drop 20 pixels in the Y direction. Because alien 1 and alien 2 moved right 1 pixel before the direction change, and because aliens 3 and 4 are going to move left instead of right, aliens 1 and 2 are 2 pixels further right (+x) than aliens 3 and 4.
1 2 3 4What you should do is reverse all the aliens at the same time. Like this:
reverse = False for alien in aliens: alien.x += alien_speed reverse = reverse or alien.x <= 0 or alien.x >= screen_width-alien_width if reverse: alien_speed *= -1 for alien in aliens: alien.y += 20You are not using sprites the way they are meant to be used. A sprite is an image and a rectangle. When a sprite is designed correctly you can group sprites and greatly reduce how much code you need to write. I would write your code like this:
import pygame class Invader(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() # sprites should have an image and a rect. This lets you draw all the sprites in a group. self.image = alien1 self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y def update(self, x=0, y=0): # Having an update method lets you update all the sprites in a group. self.rect.x += x self.rect.y += y def left(self): # returns x coordinate for left side of sprite return self.rect.left def right(self): # returns x coordinate for right side of sprite. return self.rect.right pygame.init() clock = pygame.time.Clock() # Should use a clock to regulate the update rate of the game. alien_image = pygame.image.load("invader_image.png") alien1 = pygame.transform.scale(alien_image, (50, 50)) aliens = pygame.sprite.Group( ( Invader(100, 50), Invader(50, 100), Invader(150, 100), Invader(100, 150), ) ) alien_speed = 8 screen_width = 1200 screen_height = 800 screen = pygame.display.set_mode((screen_width, screen_height)) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if any(a.left() <= 0 or a.right() >= screen_width for a in aliens): # Check if any alien reached edge of window. # yes alien_speed = -alien_speed aliens.update(alien_speed, 20) # Moves all the aliens with 1 call. else: # no aliens.update(alien_speed) screen.fill(0) aliens.draw(screen) # Draws all the aliens with 1 call. pygame.display.update() clock.tick(60) # Regulates time so this loop runs 60 times a second. pygame.quit()If you don't use a clock, your game will run differently on different computers.