Python 速成班,外星人入侵 - 飞船到达屏幕右上角后没有移动

Python Crash Course, Alien Invasion - a ship doesn't move after reaching the screen's right corner

我正在研究 Erick Matthes 的“Python 速成班”中的外星人入侵。我一直在尝试让一艘船在屏幕上移动。大多数时候,船会按预期移动。然而,在到达屏幕的最右角后,飞船不再对按键做出反应。按键盘上的左箭头键根本不会向左移动船。我的代码有什么问题?

alien_invasion.py

"""The main module of the Alien Invasion"""
import sys
import pygame
from settings import Settings
from ship import Ship

class AlienInvasion():
    """A class storing and managing all game's functionality."""
    def __init__(self):
        """Initialize essential settings."""
        self.settings = Settings()
        self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
        self.settings.window_width = self.screen.get_rect().width
        self.settings.window_height = self.screen.get_rect().height
        pygame.display.set_caption(self.settings.game_title)
        self.ship = Ship(self)
        self._run_game()

    def _end_game(self):
        """Close the game's window."""
        pygame.quit()
        sys.exit()

    def _check_events(self):
        """Check events and react to them."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self._end_game()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
             

    def _check_keydown_events(self, event):
        """Detect pressed keys and react accordingly."""
        if event.key == pygame.K_q:
            self._end_game()
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        if event.key == pygame.K_LEFT:
            self.ship.moving_left = True

    def _check_keyup_events(self, event):
        """Detect released keys and react accordingly."""
        if event.key == pygame.K_RIGHT:
            self.ship_moving_right = False
        if event.key == pygame.K_LEFT:
            self.ship.moving_left = False
            

    def _update_screen(self):
        """Draw the most recent surface on the screen."""
        self.screen.fill(self.settings.background_colour)
        self.ship.update()
        self.ship.blitme()
        pygame.display.flip()

    

    def _run_game(self):
        """Start a new game"""
        while True:
            #Main loop
            self._check_events()
            self._update_screen()

ai = AlienInvasion()

ship.py

"""A module containing a Ship class"""
import pygame
class Ship():
    """A simple attempt to represent a ship."""
    def __init__(self, ai):
        """Initialize a ship's settings."""
        self.ai = ai
        self.screen = self.ai.screen
        self.image = pygame.image.load('ship.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = self.screen.get_rect()
        self.rect.midbottom = self.screen_rect.midbottom
        #Motions' attributes
        self.moving_right = False
        self.moving_left = False
        self.x = float(self.rect.x)
        self.speed = self.ai.settings.ship_speed

    def blitme(self):
        """Draw a ship on the screen."""
        self.screen.blit(self.image, self.rect)

    def update(self):
        """Update a ship's position on the screen."""
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.x += self.speed
        if self.moving_left and self.rect.left > 0:
            self.x -= self.speed
        self.rect.x = self.x
    

settings.py

"""Module containing a Settings class"""
class Settings():
    """A module managing all game's essential settings."""
    def __init__(self):
        """Initialize settings."""
        self.background_colour = (230, 230, 230)
        self.game_title = 'Alien Invasion'
        self.window_width = 1200
        self.window_height = 600
        self.window_size = (self.window_width, self.window_height)
        #Ship's settings
        self.ship_speed = 1.5
        
 

飞船不会向左移动,这意味着它可能在向右移动时卡住了。这指出了释放向右移动的问题,这发生在 _check_keydown_events():

def _check_keyup_events(self, event):
    """Detect released keys and react accordingly."""
    if event.key == pygame.K_RIGHT:
        self.ship_moving_right = False
    if event.key == pygame.K_LEFT:
        self.ship.moving_left = False

这是有问题的行:

        self.ship_moving_right = False

这应该是 self.ship.moving_right,而不是 self.ship_moving_right。正确的版本找到游戏的ship属性,将船的moving_right属性设置为False。错误的版本创建了一个新的游戏属性ship_moving_right,并设置为False;它永远不会改变 self.ship.moving_right 的值。因此,在接下来的游戏中,飞船会尝试向右移动。这是一个很好的例子,说明一个角色如何不产生 Python 错误,但却对游戏的整体行为产生重大影响。