英雄飞机的移动是通过鼠标或者键盘事件,即:
- 鼠标拖动英雄飞机,自动发射子弹
- 通过键盘控制飞机移动,按键发射子弹
我们这里实现第二种方式。这里需要注意:英雄飞机的移动是由按键事件驱动。
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号