英雄飞机的移动是通过鼠标或者键盘事件,即:
- 鼠标拖动英雄飞机,自动发射子弹
 - 通过键盘控制飞机移动,按键发射子弹
 
我们这里实现第二种方式。这里需要注意:英雄飞机的移动是由按键事件驱动。
1. HeroPlane 类实现
英雄飞机是我们的主角,其基本实现的功能如下:
- top、bottom、left、right 4 个函数是飞机在不同方向上的移动函数
 - shoot 用于发射子弹
 - draw_element 绘制英雄飞机、以及英雄飞机发射出的子弹
 - calc_position 计算英雄飞机、以及英雄飞机发射子弹的坐标
 
import pygame
from BulletForHero import BulletForHero
from Config import *
class HeroPlane:
    def __init__(self, scene):
        # 游戏主场景
        self.scene = scene
        # 英雄飞机资源
        self.image = pygame.image.load(f'source/plane/hero.png')
        # 英雄飞机边框
        self.bbox = self.image.get_rect()
        # 初始化飞机位置
        self.bbox[0] = SCENE_W / 2 - self.bbox[2] / 2
        self.bbox[1] = SCENE_H - self.bbox[3] - 10
        # 初始化弹夹
        self.bullets = BulletForHero(scene)
        # 移动速度
        self.speed = 4
    def top(self):
        if self.bbox[1] <= 0:
            return
        self.bbox.move_ip(0, -self.speed)
    def bottom(self):
        if self.bbox[1] >= SCENE_H - self.bbox[3]:
            return
        self.bbox.move_ip(0, self.speed)
    def left(self):
        if self.bbox[0] <= 0:
            return
        self.bbox.move_ip(-self.speed, 0)
    def right(self):
        if self.bbox[0] >= (SCENE_W - self.bbox[2]):
            return
        self.bbox.move_ip(self.speed, 0)
    def shoot(self, num):
        shoot_x = self.bbox[0] + self.bbox[2] / 2
        shoot_y = self.bbox[1]
        self.bullets.shoot(shoot_x, shoot_y, num)
    def draw_element(self):
        self.scene.blit(self.image, self.bbox)
        self.bullets.draw_element()
    def calc_position(self):
        self.bullets.calc_position()
测试 HeroPlane 类:
if __name__ == '__main__':
    pygame.init()
    window = pygame.display.set_mode([512, 768])
    clock = pygame.time.Clock()
    # 初始化英雄飞机
    hero = HeroPlane(window)
    actions = [hero.left, hero.right, hero.top, hero.bottom]
    index = 0
    action_index = 0
    while True:
        # 清空窗口
        window.fill((0, 0, 0))
        # 计算坐标
        hero.calc_position()
        # 绘制图像
        hero.draw_element()
        # 发射子弹
        hero.shoot(3)
        # 随机选择方向
        actions[action_index]()
        index += 1
        if index > 50:
            action_index = random.randint(0, 3)
            index = 0
        pygame.event.get()
        pygame.display.update()
        clock.tick(60)
2. 键盘事件处理
这一步我们需要创建飞机对象并将其添加到 MainScene 中,并编写相应的键盘事件还控制飞机移动和发射子弹。
- W 向上
 - S 乡下
 - A 向左
 - D 向右
 - 按键 J 单列子弹发射
 - 按键 K 三列子弹发射
 - 按键 L 五列子弹发射
 
import random
import pygame
from Config import *
from GameMap import GameMap
from HeroPlane import HeroPlane
from EnemyTroops import EnemyTroops
# 主场景
class MainScene(object):
    # 初始化主场景
    def __init__(self):
        # 初始化组件
        pygame.init()
        # 初始化时钟
        self.clock = pygame.time.Clock()
        # 初始化游戏窗口
        self.scene = pygame.display.set_mode((SCENE_W, SCENE_H))
        # 设置窗口标题
        pygame.display.set_caption("飞机大战-v1.0 作者: 孟宝亮")
        # 初始化游戏元素
        self.init_elements()
    # 初始化游戏元素
    def init_elements(self):
        # 初始化游戏地图
        self.map = GameMap(self.scene)
        # 初始化英雄飞机
        self.hero = HeroPlane(self.scene)
    # 计算坐标
    def calc_position(self):
        # 计算地图坐标
        self.map.calc_position()
        # 计算英雄弹夹坐标
        self.hero.calc_position()
    # 绘制元素
    def draw_elements(self):
        # 绘制滚动地图
        self.map.draw_element()
        # 绘制英雄飞机
        self.hero.draw_element()
    # 处理事件
    def handle_events(self):
        # 点击窗口关闭按钮
        events = pygame.event.get()
        for event in events:
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        # 获得当前按下的键
        keys = pygame.key.get_pressed()
        # 射击
        if keys[pygame.K_j]:
            self.hero.shoot(1)
        if keys[pygame.K_k]:
            self.hero.shoot(3)
        if keys[pygame.K_l]:
            self.hero.shoot(5)
        # 上
        if keys[pygame.K_w]:
            self.hero.top()
        # 下
        if keys[pygame.K_s]:
            self.hero.bottom()
        # 左
        if keys[pygame.K_a]:
            self.hero.left()
        # 右
        if keys[pygame.K_d]:
            self.hero.right()
    # 碰撞检测
    def detect_conlision(self):
        pass
    # 主循环
    def run(self):
        while True:
            # 碰撞检测
            self.detect_conlision()
            # 计算元素坐标
            self.calc_position()
            # 绘制元素图片
            self.draw_elements()
            # 处理事件
            self.handle_events()
            # 刷新显示
            pygame.display.update()
            # 控制帧率
            self.clock.tick(60)


 冀公网安备13050302001966号