前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Flutter&Flame游戏 - 拾贰】探索构件 | 角色管理

【Flutter&Flame游戏 - 拾贰】探索构件 | 角色管理

作者头像
张风捷特烈
发布2022-06-19 16:22:08
4340
发布2022-06-19 16:22:08
举报

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 13 天,点击查看活动详情


前言

这是一套 张风捷特烈 出品的 Flutter&Flame 系列教程,发布于掘金社区。如果你在其他平台看到本文,可以根据对于链接移步到掘金中查看。因为文章可能会更新、修正,一切以掘金文章版本为准。本系列文章一览:


1. 管理怪兽

前面把 Monster 全写在 TolyGame 中,看起来很杂乱。一个场景中可能存在多个怪兽,比如下面六个小怪和一个 Boss 。我们可以通过自定义一个 MonsterManager 构件对这些怪兽进行管理:代码详见【12/01】


MonsterManager 中通过入参将小怪和 Boss 的序列帧传入,这样可以中使用时自定义序列帧:

class MonsterManager extends PositionComponent with HasGameRef {
  final SpriteSheet bossSpriteSheet;
  final SpriteSheet stoneSpriteSheet;
  MonsterManager({
    required this.bossSpriteSheet,
    required this.stoneSpriteSheet,
  }):super(anchor: Anchor.center);
复制代码

onLoad 方法中,通过 createBoss 方法创建并添加 Boss 构件,然后通过 createStoneMonster 方法在左右分别遍历三个小怪。创建和添加 Monster 的方式和前面是一样的,这里就不赘述了,详见源码。

@override
Future<void> onLoad() async {
  createBoss();
  int lineCount =3;
  double step = gameRef.size.y/lineCount ;
  for(int i=1;i<=lineCount;i++){
    final double pY = i*step- 30;
    final double pX = gameRef.size.x - 200;
    createStoneMonster(Vector2(pX, pY));
  }
  for(int i=1;i<=lineCount;i++){
    final double pY = i*step- 30;
    final double pX = 150;
    createStoneMonster(Vector2(pX, pY));
  }
}
复制代码

2. 怪兽发射子弹

现在怪物站在那傻乎乎的被打很不公平,下面看看如何让怪兽发射子弹。这里用来两个序列帧动画作为子弹的资源,如下图所示:代码详见【12/02】

https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0c9134cee93348878ce1426d40c6ec5a~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

其实本质上,怪物发射子弹和主角发射子弹本质上是一样的。不同点在于,主角子弹发送是用户控制的,怪物一般是定时发射子弹。另外,要区分一下子弹的类型,是怪物发射的,还是主角发射的。之前角色的弓箭是静态图片,这里可以定义一个 AnimBullet 来支持序列帧的子弹:

enum BulletType{
  hero,
  monster
}

class AnimBullet extends SpriteAnimationComponent {
  double speed = 200;
  final double maxRange;
  final BulletType type;
  final bool isLeft;

  AnimBullet({
    required SpriteAnimation animation,
    required this.maxRange,
    required this.type,
    required this.speed,
    this.isLeft = true,
  }) : super(animation : animation);
  
  // 略同...
复制代码

然后看一下如何通过 Timer 来定时不断发射子弹,这里的 TimerFlame 中封装的,不是 Flutter 自带的。如下 Monster 的各个生命周期中对 Timer 进行相关处理:onLoad 方法中初始化 _timer 对象,隔 3 s 钟触发一次 addBullet 方法添加子弹。onMount 方法中开启 _timeronRemove 中停止 _timer

---->[Monster]----
late Timer _timer;

@override
Future<void> onLoad() async {
  _timer = Timer(3, onTick: addBullet, repeat: true);
}

@override
void onMount() {
  super.onMount();
  _timer.start();
}

@override
void update(double dt) {
  super.update(dt);
  _timer.update(dt);
}

@override
void onRemove() {
  super.onRemove();
  _timer.stop();
}
复制代码

如下是 addBullet 方法,和之前主角发射子弹的逻辑基本一致:

// 添加子弹
void addBullet() {
  AnimBullet bullet = AnimBullet(
    type: BulletType.monster,
    animation: bulletSprite,
    maxRange: attr.attackRange,
    speed: attr.attackSpeed,
    isLeft: isLeft,
  );
  bullet.size = bulletSize;
  bullet.anchor = Anchor.center;
  bullet.priority = 1;
  priority = 2;
  bullet.position = position - Vector2(0, size.y/2);
  gameRef.add(bullet);
}
复制代码

3.怪兽发射的命中

如下所示,在怪物发射的子弹命中主角时,主角也会受到伤害。生命值降低,并且显示伤害数值:代码详见【12/03】

https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e1348ff37c1a45bbbcb478475a0f3e57~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

目前仍是校验 矩形域中心点 的包含关系来判定是否命中。如下,在 update 中通过 _checkAttackHero 校验是否命中,命中时 player 触发 loss 方法掉血。

---->[TolyGame#update]----
@override
void update(double dt) {
  super.update(dt);
  _checkAttackMonster();
  _checkAttackHero();
}
  
void _checkAttackHero() {
  final Iterable<AnimBullet> bullets = children
      .whereType<AnimBullet>()
      .where((AnimBullet e) => e.type == BulletType.monster);
  for (AnimBullet bullet in bullets) {
    if (bullet.shouldRemove) {
      continue;
    }
    if (player.containsPoint(bullet.absoluteCenter) ||
        bullet.containsPoint(player.absoluteCenter)) {
      bullet.removeFromParent();
      player.loss(bullet.attr);
      break;
    }
  }
}
复制代码

到这里,我们已经完成了 主角怪物 间的基本交互,也基本上对 Component 有了较深的理解。接下来将进一步探讨 碰撞检测 相关的知识,毕竟现在靠的是 矩形域中心点 的包含关系,并不是非常准确。那本文就到这里,明天见 ~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 1. 管理怪兽
  • 2. 怪兽发射子弹
  • 3.怪兽发射的命中
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档