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 错误,但却对游戏的整体行为产生重大影响。
我正在研究 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 错误,但却对游戏的整体行为产生重大影响。