如何修复《Python Crash Course》Alien Invasion项目飞船水平鼠标移动控制问题
问题:Alien Invasion游戏鼠标水平控制飞船功能失效
我正在修改《Python Crash Course》一书中的Alien Invasion游戏控制逻辑,想要实现仅通过鼠标水平控制飞船图片移动。我在Stack Overflow找到了如下参考代码:
import pygame as pg pg.init() screen = pg.display.set_mode((640, 480)) clock = pg.time.Clock() BG_COLOR = pg.Color('gray12') IMG = pg.Surface((120, 90)) IMG.fill((0, 120, 200)) x = 200 y = 300 done = False while not done: for event in pg.event.get(): if event.type == pg.QUIT: done = True elif event.type == pg.MOUSEMOTION: if event.buttons[0]: # Left mouse button pressed. x += event.rel[0] y += event.rel[1] screen.fill(BG_COLOR) screen.blit(IMG, (x, y)) pg.display.flip() clock.tick(60) pg.quit()
我尝试将该逻辑适配到我的项目中,但目前鼠标移动识别功能无法正常工作,以下是我的项目代码:
主程序 Alien_Invasion.py
import pygame from settings import Settings from ship import Ship import game_functions as gf def run_game(): # Initialisiert das Spiel + erstellt ein screen-Objekt pygame.init() ai_settings = Settings() screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height)) pygame.display.set_caption("Alien Invasion") # Erstellt das Schiff ship = Ship(ai_settings,screen) # Startet die Hauptschleife des Spiels. while gf.check_events(ship): ship.update() gf.update_screen(ai_settings, screen, ship) run_game()
游戏功能模块 game_functions.py
import pygame,time import pygame.locals as pyl clock = pygame.time.Clock() x=0 def check_events(ship): # Lauscht auf Tastaturereignisse. for event in pygame.event.get(): if event.type == pygame.QUIT: return False elif event.type == pyl.MOUSEMOTION: x = event.rel[0] if x>0: ship.moving_right=True if x<0: ship.moving_left=True clock.tick(60) return True def update_screen(ai_settings, screen, ship): #Zeichnet den Bildschirm bei jedem Schleifendurchlauf neu screen.fill(ai_settings.bg_color) ship.blitme() # Macht den als letztes gezeichneten Bi1dschirm sichtbar pygame.display.flip()
飞船类模块 ship.py
import pygame class Ship(): def __init__(self,ai_settings,screen): self.screen = screen self.ai_settings = ai_settings # lädt das Bi1d des Schiffes und ruft dessen umgebendes Rechteck ab self.image=pygame.image.load('images/ship.bmp') self.rect=self.image.get_rect() self.screen_rect= screen.get_rect() # Platziert jedes neue Schiff mittig am unteren Bildschirmrand self.rect.centerx = self.screen_rect.centerx self.rect.bottom = self.screen_rect.bottom # speichert einen Kommawert für den Schiffsmittelpunkt self.center=float(self.rect.centerx) self.moving_right=False self.moving_left=False def update(self): #Aktualisiert den Wert für den Mittelpunkt des Schiffs, nicht des Rechtecks 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 #Aktualisiert das rect-Objekt auf der Grundlage von self.center self.rect.centerx=self.center def blitme(self): self.screen.blit(self.image, self.rect)
配置类模块 settings.py
class Settings(): def __init__(self): # Bildschirmeinstellungen self.screen_width = 1200 self.screen_height = 800 self.bg_color = (80,80,255) self.ship_speed_factor = 1.5
解决方案
你的代码有两个核心问题:
- 没有重置
moving_right和moving_left的状态,只要触发过一次鼠标移动,这两个标记就会一直保持True,飞船会持续向对应方向移动,不会停止也无法正确响应后续鼠标操作 - 缺少参考代码中「按住鼠标左键才触发移动」的判断逻辑,默认只要鼠标移动就会触发位移
方案1:沿用拖动控制逻辑(和参考代码效果一致)
直接修改game_functions.py中的check_events函数即可:
def check_events(ship): # 每次循环先重置移动状态,避免状态残留 ship.moving_right = False ship.moving_left = False for event in pygame.event.get(): if event.type == pygame.QUIT: return False elif event.type == pyl.MOUSEMOTION: # 仅按住左键时响应移动 if event.buttons[0]: x_offset = event.rel[0] if x_offset > 0: ship.moving_right = True if x_offset < 0: ship.moving_left = True clock.tick(60) return True
方案2:实现鼠标位置跟随(无需按住拖动,更顺滑)
如果不需要拖动控制,想让飞船直接跟着鼠标水平位置移动,可以用更简单的实现方式:
- 修改
game_functions.py的check_events函数:
def check_events(ship): for event in pygame.event.get(): if event.type == pygame.QUIT: return False elif event.type == pyl.MOUSEMOTION: # 直接把鼠标的x坐标赋值给飞船中心 ship.center = event.pos[0] clock.tick(60) return True
- 可以删掉
ship.py中所有和moving_right、moving_left相关的逻辑,也可以保留不影响运行。
内容的提问来源于stack exchange,提问作者jörg
相关产品推荐
相关产品推荐

