《Python 飞机大战》(六)英雄飞机

英雄飞机的移动是通过鼠标或者键盘事件,即:

  1. 鼠标拖动英雄飞机,自动发射子弹
  2. 通过键盘控制飞机移动,按键发射子弹

我们这里实现第二种方式。这里需要注意:英雄飞机的移动是由按键事件驱动。

1. HeroPlane 类实现

英雄飞机是我们的主角,其基本实现的功能如下:

  1. top、bottom、left、right 4 个函数是飞机在不同方向上的移动函数
  2. shoot 用于发射子弹
  3. draw_element 绘制英雄飞机、以及英雄飞机发射出的子弹
  4. 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 中,并编写相应的键盘事件还控制飞机移动和发射子弹。

  1. W 向上
  2. S 乡下
  3. A 向左
  4. D 向右
  5. 按键 J 单列子弹发射
  6. 按键 K 三列子弹发射
  7. 按键 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)
未经允许不得转载:一亩三分地 » 《Python 飞机大战》(六)英雄飞机
评论 (0)

5 + 1 =