Python13_项目一 :外星人入侵游戏04(重构check_event() 以及 使飞船发射子弹)

为了使代码模块化、结构化,我们将check_event()函数中的按键响应,重构为两个函数:分别是check_keydown() 【响应按键】和 check_keyup()  【响应松开】。

重构后的代码如下:(此代码为本节部分代码,整体代码稍后,这段代码看看就好

# 响应按键 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

那么接下来,就是要增加子弹。对于增加子弹,我们需要先在settings.py文件中增加子弹的属性。然后,写一个bullet.py文件,保存Bullet类,为的是创建一个子弹的rect对象,并且能让子弹从屏幕中绘制出来。具体文件如下所示:

bullet.py代码如下所示:

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 标记的都是更新有关的!!!

settings.py

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

game_funtion.py

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))

alien_invasion.py

# 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()

猜你喜欢

转载自blog.csdn.net/qq_35069382/article/details/81241260