首页
登录 | 注册

Pygame实战之外星人入侵NO.4——射击

飞船已经创建好了,接下来就要装填弹药了。(本想将修改的代码涂红显示,但系统问题导致无法正常显示,只能尽量只贴出修改的代码了)

在setting.py中设定子弹类Bullet所需的参数:
#设置子弹属性
        self.bullet_width=2
        self.bullet_height=10
        self.bullet_speed=1
        self.bullet_color=(20,20,20)

根据参数名就能看出我们设定的是子弹的宽高颜色以及发射速度,然后我们就要创建Bullet类了,新建bullet.py:
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
    '''我们要在飞船所处的位置创建子弹对象'''
    def __init__(self,ai_settings,screen,ship):
        super(Bullet,self).__init__()  #此为2.7写法,适用于3,也可将括号中的参数去掉
        self.screen=screen
        
        #在原点处创建一个表示子弹的矩形,将其放在正确的位置
        self.rect=pygame.Rect(0,0,ai_settings.bullet_width,ai_settings.bullet_height)
        self.rect.centerx=ship.rect.centerx
        self.rect.top=ship.rect.top  #让子弹看起来是从飞船顶部发出的
        
        #存储子弹的位置,用小数表示子弹的y坐标,方便微调其速度
        self.y=float(self.rect.y)
        self.color=ai_settings.bullet_color
        self.speed=ai_settings.bullet_speed
    def update(self):
        self.y-=self.speed #更新子弹位置,子弹往屏幕上方走,即y坐标不断减小,而x坐标不变
        self.rect.y=self.y #更新表示子弹rect的位置
    def draw_bullet(self): #函数draw.rect()使用存储在self.color中的颜色填充表示子弹的rect占据的屏幕部分
        pygame.draw.rect(self.screen,self.color,self.rect)

Sprite称为精灵,通过使用它可将游戏中相关的元素编组,进而同时操作组中的所有元素;使用super()继承Sprite(Bullet类继承了Sprite类)
接下来就要在主程序中进行设置了,在原有的基础上添加相应的子弹属性:
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
from pygame.sprite  import Group
def run_game():
    pygame.init()  #初始化背景设置
    ai_settings=Settings()  #实例化
    screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height)) #调用属性设置屏幕的宽高
    pygame.display.set_caption("Alien Invasion")  #设置标题
    ship=Ship(screen,ai_settings)  #实例化Ship
    bullets=Group() #创建一个存储子弹的组
    while True:
        gf.check_events(ship,ai_settings,screen,bullets) #更改事件监听函数
        ship.update()  #每次循环都访问该函数,保证飞船的位置将在检测到键盘事件后(但在更新屏幕前)更新
        bullets.update() #将为组bullets中的每一颗子弹调用bullets.update()
        gf.update_screen(ai_settings,screen,ship,bullets)       
run_game()                        

相较于之前,我们导入了Group类,其类似于列表,但提供了有助于开发的额外功能。这里要注意一下主循环中的方法参数,传参时别整错了。

我们要实现按空格发射子弹的功能,需要修改game_function.py中的内容:
import sys
import pygame
from bullet import Bullet
def check_keydown(event,ship,ai_settings,screen,bullets):
    if event.key==pygame.K_RIGHT:
        ship.moving_right=True #若按下右箭头则使ship.rect.centerx加1
    elif event.key==pygame.K_LEFT:
        ship.moving_left=True #注意这里若同时按下左右箭头将检测到两个不同事件
    elif event.key==pygame.K_SPACE:
        new_b=Bullet(ai_settings,screen,ship)  #创建子弹
        bullets.add(new_b)  #将子弹加入到bullets中
def check_events(ship,ai_settings,screen,bullets):
    for event in pygame.event.get():  #检测键盘鼠标事件
            if event.type==pygame.QUIT:
                sys.exit() #退出程序
            elif event.type==pygame.KEYDOWN:
                check_keydown(event,ship,ai_settings,screen,bullets)
            elif event.type==pygame.KEYUP:
                check_keyup(event,ship)
def update_screen(ai_settings,screen,ship,bullets):
    screen.fill(ai_settings.bg_color)  #调用属性设置屏幕的填充颜色
    for bullet in bullets.sprites():  #对每个bullets中的小妖怪都调用draw_bullet()方法,重绘所有子弹
        bullet.draw_bullet()
    ship.blitme()  #显示飞船
    pygame.display.flip()  #是最近绘制的屏幕可见

我们不需要修改check_keyup(),因为当松开空格键时无需任何操作;这里还是要注意各个方法的参数,包括导入的类。

效果如下,飞船可以发射任意数量的子弹了:

Pygame实战之外星人入侵NO.4——射击



2020 jeepxie.net webmaster#jeepxie.net
10 q. 0.009 s.
京ICP备10005923号