重构后的代码如下:(此代码为本节部分代码,整体代码稍后,这段代码看看就好)
# 响应按键 03
def check_keydown(event, ai_settings, screen, ship, bullets):
if event.key == pygame.K_RIGHT:
# 向右移动飞船
ship.moving_right = True
# ship.rect.centerx += 10
elif event.key == pygame.K_LEFT:
# 向左移动飞船
# ship.rect.centerx -= 10
ship.moving_left = True
# 响应松开 03
def check_keyup(event, ship):
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
# 响应按键和鼠标事件
def check_event(ai_setting, screen, ship, bullets): # 03
for i in pygame.event.get():
if i.type == pygame.QUIT:
sys.exit()
elif i.type == pygame.KEYDOWN:
check_keydown(i, ai_setting, screen, ship, bullets) # 重构
# 03 if i.key == pygame.K_RIGHT:
# 03 # 向右移动飞船
# 03 ship.moving_right = True
# 03 # ship.rect.centerx += 10
# 03 elif i.key == pygame.K_LEFT:
# 03 # 向左移动飞船
# 03 # ship.rect.centerx -= 10
# 03 ship.moving_left = True
elif i.type == pygame.KEYUP:
check_keyup(i, ship) # 重构
# 03 if i.key == pygame.K_RIGHT:
# 03 ship.moving_right = False
# 03 elif i.key == pygame.K_LEFT:
# 03 ship.moving_left = False
import pygame
from pygame.sprite import Sprite # 导入精灵
# 一个对飞船发射的子弹进行管理的类
class Bullet(Sprite):
def __init__(self,ai_setting,screen,ship):
# 在飞船所处的位置创建一个子弹对象
super().__init__() # 初始化父类 2.7写法super(Bullet,self).__init__()
self.screen = screen
# 在(0,0)处创建一个表示子弹的矩形,再设置正确的位置
# 我们创建了子弹的属性rect 。子弹并非基于图像的,因此我们必须使用pygame.Rect()类从空白开始创建一个矩形
# 我们在(0, 0)处创建这个矩形,但接下来的两行代码将其移到了正确的位置
self.rect = pygame.Rect(0,0,ai_setting.bullet_width,ai_setting.bullet_height)
# 我们将子弹的centerx设置为飞船的rect.centerx 。
# 子弹应从飞船顶部射出,因此我们将表示子弹的rect的top属性设置为飞船的rect的top属性,
# 让子弹看起来像是从飞船中射出的
self.rect.centerx = ship.rect.centerx
self.rect.top = ship.rect.top
# 存储用小数表示的子弹位置
self.y = float(self.rect.y)
self.color = ai_setting.bullet_color
self.speed = ai_setting.bullet_speed_factor
# 向上移动子弹
def update(self, *args):
# 更新表示子弹位置的小数值
self.y -= self.speed
# 更新表示子弹位置的rect的位置
self.rect.y = self.y
# 在屏幕上绘制子弹
def draw_bullet(self):
# 函数draw.rect()使用存储在self.color中的颜色填充表示子弹的rect占据的屏幕部分
pygame.draw.rect(self.screen,self.color,self.rect)
然后附上更新后的其他.py文件代码。
带 03 标记的都是更新有关的!!!
class Setting(): # 存储《外星人入侵》中所有的设置类
def __init__(self): # 初始化游戏设置
self.screen_width = 1200 # 屏幕设置
self.screen_height = 800
self.bg_color = (230,230,230)
self.ship_speed_factor = 1.5 # 02 设置飞船速度
# 03 设置子弹
self.bullet_speed_factor = 1 # 子弹速度
self.bullet_width = 3 # 子弹宽度
self.bullet_height = 15 # 子弹长度
self.bullet_color = 60,60,60 # 子弹颜色
self.bullet_allowed = 3 # 限制子弹数量为3
import sys
import pygame
from alien.bullet import Bullet # 03
# 响应按键 03
def check_keydown(event, ai_settings, screen, ship, bullets):
if event.key == pygame.K_RIGHT:
# 向右移动飞船
ship.moving_right = True
# ship.rect.centerx += 10
elif event.key == pygame.K_LEFT:
# 向左移动飞船
# ship.rect.centerx -= 10
ship.moving_left = True
# 03 创建一颗子弹,并将其加入到编组bullets中
elif event.key == pygame.K_SPACE:
if len(bullets) < ai_settings.bullet_allowed: # 限制三个子弹
# 玩家按空格键时,创建一颗新子弹(一个名为new_bullet 的Bullet 实例),
new_bullet = Bullet(ai_settings, screen, ship)
# 并使用方法add() 将其加入到编组bullets中
bullets.add(new_bullet)
# 响应松开 03
def check_keyup(event, ship):
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
# 响应按键和鼠标事件
def check_event(ai_setting, screen, ship, bullets): # 03
for i in pygame.event.get():
if i.type == pygame.QUIT:
sys.exit()
elif i.type == pygame.KEYDOWN:
check_keydown(i, ai_setting, screen, ship, bullets) # 重构
# 03 if i.key == pygame.K_RIGHT:
# 03 # 向右移动飞船
# 03 ship.moving_right = True
# 03 # ship.rect.centerx += 10
# 03 elif i.key == pygame.K_LEFT:
# 03 # 向左移动飞船
# 03 # ship.rect.centerx -= 10
# 03 ship.moving_left = True
elif i.type == pygame.KEYUP:
check_keyup(i, ship) # 重构
# 03 if i.key == pygame.K_RIGHT:
# 03 ship.moving_right = False
# 03 elif i.key == pygame.K_LEFT:
# 03 ship.moving_left = False
def update_screen(ai_setting, screen, ship, bullets): # 更新屏幕上的图像,并切换到新屏幕
# 每次循环时都重绘屏幕
screen.fill(ai_setting.bg_color)
# 03 在飞船和外星人后面重绘所有子弹
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
# 让最近绘制的屏幕可见
pygame.display.flip()
# 03 更新子弹位置,并删除已经消失的子弹
def update_bullet(bullets):
bullets.update() # 更新子弹位置
# 03 删除已经消失,看不到的子弹
for bull in bullets.copy():
if bull.rect.bottom <= 0:
bullets.remove(bull)
print(len(bullets))
# 02 import sys
import pygame
from alien.settings import Setting # 01
from alien.ship import Ship # 01
import alien.game_function as gf # 02
from pygame.sprite import Group # 03 pygame.sprite.Group 类类似于列表,但提供了有助于开发游戏的额外功能
def run_game(): # 初始化游戏,并且创建一个屏幕对象
pygame.init() # 初始化背景设置,让Pygame能够正确地工作
# 01 screen = pygame.display.set_mode((1200, 800)) # 创建一个名为screen 的显示窗口,括号里是元组!!!
# 01 # 这个游戏的所有图形元素都将在其中绘制
ai_set = Setting() # 因为导入类而做了代码替换
screen = pygame.display.set_mode(
(ai_set.screen_width,ai_set.screen_height)
)
# 01 bg_color = (230,230,230) # 设置背景颜色
pygame.display.set_caption('外星人入侵')
# 创建一艘飞船对象
ship = Ship(ai_set,screen)
# 03 导入Group类并且创建一个Group实例,用于存储子弹的编组
bullets = Group()
# 为让程序响应事件,我们编写一个事件循环,以侦听事件,并根据发生的事件执行相应的任务。
while True: # 游戏的主循环
# 02 for event in pygame.event.get(): # 监视键盘和鼠标
# 02 if event.type == pygame.QUIT: #编写一系列的if 语句来检测并响应特定的事件
# 02 sys.exit() # 我们调用sys.exit() 来退出游戏
gf.check_event(ai_set,screen,ship,bullets) # 02 03
ship.update() # 02
gf.update_bullet(bullets) # 03
# 03 bullets.update() # 03
# # 03 删除已经消失,看不到的子弹
# for bull in bullets.copy():
# if bull.rect.bottom <= 0:
# bullets.remove(bull)
# print(len(bullets))
# 01screen.fill(bg_color) # 每次循环都重绘屏幕
# 02 screen.fill(ai_set.bg_color)
# 02 ship.blitme() # 调用blitme函数,使飞船出现
# 02 pygame.display.flip() # 让最近绘制的屏幕可见
gf.update_screen(ai_set,screen,ship,bullets) # 02 03
run_game()