本文已参与「新人创作礼」活动,一起开启掘金创作之路。 上次我们在(一)中创建了游戏的背景,现在我们这里将要实现用键盘控制飞船的移动、射击子弹,但是在此之前我们还有一个非常重要的部分--重构。
重构
在大型项目中,经常需要添加新代码重构旧的代码,简单来说就把一些代码整理成函数,用函数之前的代码就变成了一句函数。这里我们就需要把之前的run_game()拆分成两个辅助方法,基本上辅助方法要以单个下划线打头。 我们直接回顾上此的代码
def run_game(self):
while True:
#这里把管理事件的代码移动到这两个函数里面了,代码在下面
self._check_events()
self._update_screen()
def _check_events(self):
#这个是之前按键和鼠标的代码
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
def _update_screen(self):
#更新图像,切换到新屏幕
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
pygame.display.flip()
飞船的控制
这里我开始把按键链接到电脑,每一次按下一个按键,pygame上都会注册一个事件,这里每次按下都会注册一个KEYDOWN事件,如果检测到这个事件就会移动
def _check_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN: #检测到了按键被按下
if event.type == pygame.K_RIGHT:#按下的键是右键
self.ship.rect.x +=1#这里的距离+1,即右边移
左右持续移动
# 添加左右的移动的标志,立flag是好个方法,简化代码过程
self.moving_right = False
self.moving_left = False
但检测到左右移动键按下后,flag变成1
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
这个时候我们在主运行加入移动函数,update()
def run_game(self):
"""Start the main loop for the game."""
while True:
self._check_events()
self.ship.update()#控制移动
self._update_screen()
下面这个就是移动函数
def update(self):
if self.moving_right:
self.ship.rect.x +=1#右移动加一
if self.moving_left:
self.ship.rect.x -=1#左移动减一
调整数独、限制活动范围 这里我们就整体展现下ship加工部分了。
import pygame
class Ship:
def __init__(self, ai_game):
self.screen = ai_game.screen
self.settings = ai_game.settings#这里添加一个settings属性,等会要在update用
self.screen_rect = ai_game.screen.get_rect()
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
self.rect.midbottom = self.screen_rect.midbottom
#这里有个方法是储存小数值,因为飞船移动的是像素,所以这里要要把位置赋给能够储存小数值的变量
self.x = float(self.rect.x)
# 移动的flag
self.moving_right = False
self.moving_left = False
def update(self):
if self.moving_right and self.rect.right < self.screen_rect.right:
#飞船未飞出右边的边缘
self.x += self.settings.ship_speed
#移动的速度会不断地加一个像素的大小,注意:主函数中已经设置了速度为self.ship_speed=1.5
if self.moving_left and self.rect.left > 0:
#如果飞船未飞出左侧,左侧是0
self.x -= self.settings.ship_speed
#根据self.x更新rect对象
self.rect.x = self.x
再次重构 因为一句添加了不少内容,所以
def _check_events(self):
"""Respond to keypresses and mouse events."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
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):
#这是刚才的语句,写进了这个句子
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.key == pygame.K_LEFT:
self.ship.moving_left = True
def _check_keyup_events(self, event):
#同样的
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
elif event.key == pygame.K_LEFT:
self.ship.moving_left = False
按Q键退出
def _check_keydown_events(self, event):
"""Respond to keypresses."""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.key == pygame.K_LEFT:
self.ship.moving_left = True
#这里我们设置的按键Q退出,接受到Q键反应接受后执行sys模块的退出指令
elif event.key == pygame.K_q:
sys.exit()
全屏运行
def __init__(self):
"""Initialize the game, and create game resources."""
pygame.init()
self.settings = Settings()
#游戏开始时传入的是(0,0)以及参数pygame.FULLSCREEN,这个指令是覆盖整个屏幕
self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
#这里使用屏幕的高和宽更新数据
self.settings.screen_width = self.screen.get_rect().width
self.settings.screen_height = self.screen.get_rect().height