0

My problem with the code is that the ship's movement is strange; sometimes when I press the left or right arrow key it doesn't move the correct way. Or, the ship doesn't move at all. In this project I have the modules alien.py, alien_invasion.py, bullet.py, button.py, gamefunctions.py, game_stats.py, scoreboard.py, settings.py, and ship.py. However, I will only provide the most relevant ones.

ship.py:

    import pygame
    class Ship():
         def __init__(self, screen, ai_settings):
              self.screen = screen
              self.ai_settings = ai_settings
              self.image = pygame.image.load('images/spaceship.png')
              self.rect = self.image.get_rect()
              self.screen_rect = screen.get_rect()
              self.rect.centerx = self.screen_rect.centerx
              self.rect.bottom = self.screen_rect.bottom
              self.center = float(self.rect.centerx)
              self.moving_right = False
              self.moving_left = False

          def update(self):
              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):
               self.screen.blit(self.image, self.rect)

          def center_ship(self):
              self.center = self.screen_rect.centerx 

game_functions.py:

    import sys
    import pygame
    from bullet import Bullet
    from alien import Alien
    from time import sleep
         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_LEFT:
                   ship.moving_left = True
              elif event.key == pygame.K_SPACE:
                   fire_bullet(ai_settings, screen, ship, bullets)
              
         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, stats, play_button, ship, aliens, bullets):
               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)

alien_invasion.py:

    import sys
    import pygame
    import game_functions as gf
    from settings import Settings
    from ship import Ship
    from pygame.sprite import Group

    def run_game():
         pygame.init()
         ai_settings = Settings()
         screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
         screen = pygame.display.set_mode((1200, 650))
         pygame.display.set_caption("Alien Invasion")
         while True:
             gf.check_events(ai_settings, screen, stats, play_button, ship, aliens, bullets)
             if stats.game_active:
                  ship.update()
                  gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets)
                  gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
             gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button)
             for event in pygame.event.get():
                  if event.type == pygame.QUIT:
                       sys.exit()
             screen.fill(ai_settings.bg_color)
             ship.blitme()
             screen.fill(bg_color)

      run_game()
Jack Brown
  • 11
  • 2
  • If someone presses the K_RIGHT key and holds it down for a second, how many keydown events will that trigger? One, or more than one? – John Gordon Sep 04 '20 at 01:06
  • 1
    You shouldn't loop over `pygame.event.get()` in multiple places, the loop that just checks for the `QUIT` event in your main loop is probably processing and throwing away the events you are interested in. – Iain Shelvington Sep 04 '20 at 01:08
  • @IainShelvington I deleted the pygame.event.get() in the main loop, and now the movements work! Thanks! – Jack Brown Sep 04 '20 at 01:22

1 Answers1

0

The problem is caused by multiple calls to pygame.event.get().

pygame.event.get() get all the messages and remove them from the queuepygame.event.get() get all the messages and remove them from the queue. See the documentation:

This will get all the messages and remove them from the queue. [...]

If pygame.event.get() is called in multiple event loops, only one loop receives the events, but never all loops receive all events. As a result, some events appear to be missed.

Get the events once and use them in multiple loops or pass the list or events to functions and methods where they are handled:

def check_events(event_list, ai_settings, screen, stats, play_button, ship, aliens, bullets):
    
    for event in event_list:

        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 run_game():
    # [...]

    while True:
    
        event_list = pygame.event.get()

        gf.check_events(event_list, ai_settings, screen, stats, play_button, ship, aliens, bullets)
         
        # [...]
             
        for event in event_list :
            if event.type == pygame.QUIT:
                sys.exit()
       
        # [...]
Rabbid76
  • 202,892
  • 27
  • 131
  • 174