【Flutter&Flame游戏 - 拾捌】构件特效 | ComponentEffect 一族

2022-06-19 16:40:41 浏览数 (1)

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


前言

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

  • 【Flutter&Flame 游戏 - 壹】开启新世界的大门
  • 【Flutter&Flame 游戏 - 贰】操纵杆与角色移动
  • 【Flutter&Flame 游戏 - 叁】键盘事件与手势操作
  • 【Flutter&Flame 游戏 - 肆】精灵图片加载方式
  • 【Flutter&Flame 游戏 - 伍】Canvas 参上 | 角色的血条
  • 【Flutter&Flame 游戏 - 陆】暴击 Dash | 文字构件的使用
  • 【Flutter&Flame 游戏 - 柒】人随指动 | 动画点触与移动
  • 【Flutter&Flame 游戏 - 捌】装弹完毕 | 角色武器发射
  • 【Flutter&Flame 游戏 - 玖】探索构件 | Component 是什么
  • 【Flutter&Flame 游戏 - 拾】探索构件 | Component 生命周期回调
  • 【Flutter&Flame 游戏 - 拾壹】探索构件 | Component 使用细节
  • 【Flutter&Flame 游戏 - 拾贰】探索构件 | 角色管理
  • 【Flutter&Flame 游戏 - 拾叁】碰撞检测 | CollisionCallbacks
  • 【Flutter&Flame 游戏 - 拾肆】碰撞检测 | 之前代码优化
  • 【Flutter&Flame 游戏 - 拾伍】粒子系统 | ParticleSystemComponent
  • 【Flutter&Flame 游戏 - 拾陆】粒子系统 | 粒子的种类
  • 【Flutter&Flame 游戏 - 拾柒】构件特效 | 了解 Effect 体系
  • 【Flutter&Flame 游戏 - 拾捌】构件特效 | ComponentEffect 一族
  • 【Flutter&Flame 游戏 - 拾玖】构件特效 | 了解 EffectController 体系
  • 【Flutter&Flame 游戏 - 贰拾】构件特效 | 其他 EffectControler
  • 【Flutter&Flame 游戏 - 贰壹】视差组件 | ParallaxComponent
  • 【Flutter&Flame 游戏 - 贰贰】菜单、字体和浮层
  • 未完待续 ~

1. ComponentEffect 一族特效的特点

上一节介绍了 移动旋转缩放移除 的特效,它们都是 Effect 的直接子类,施加一些变换效果。本文来看一下 ComponentEffect 一族,它们如何使用、有什么特点。


如下是 ComponentEffect 抽象类的源码实现,从中可以很清楚地看出 ComponentEffect 的特点。它可以支持一个 Component 类型的泛型,并且持有该类型的成员 target 。这个 target 对象使用 late 声明,会在 onMount 方法中被赋值。

从红框中的逻辑可以看出,会寻找上级第一个非 Effect 的构件,且该构件的类型是指定的 T 类型。也就是找到宿主构件为 target 成员赋值,注意如果宿主类型和指定的 T 类型会抛异常。


2. 尺寸特效:SizeEffect

同样 SizeEffect 也有 byto 两个构造由于表示尺寸增加了多少,和尺寸变化到多少。如下,为了更方便演示操作,在左侧给出相关按键的效果信息,图中的是按下 89 的效果,更改宿主的尺寸。

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

在使用方式上合前面也是一样的,给出变化数据和控制器即可:

代码语言:javascript复制
void addSizeEffectBy(){
  Effect effect = SizeEffect.by(
    Vector2(5,5*(37/50)),
    EffectController(duration: 0.5),
  );
  player.add(effect);
}

void addSizeEffectTo(){
  Effect effect = SizeEffect.to(
    Vector2(50, 37),
    EffectController(duration: 0.5),
  );
  player.add(effect);
}
复制代码

这里可能会有人感觉 SizeEffect 似乎和 ScaleEffect 很像,都能实现把构件变大和变小。其实本质上还是有很大区别的。ScaleEffect 是变换,针对整体的图形变换,构件是被整体缩放的。可以用下面 ScaleEffect 效果对比一下,可以看出变换 ScaleEffect 也会波及其子构件。


SizeEffect 只是针对角色的 size 进行更改,不涉及变换,如下所示:


SizeEffect 的源码也能清楚地看出,本质是对 target 成员,也就是宿主构件的 size 属性进行变化:


3. 透明度效果: OpacityEffect

同样 OpacityEffect 也有 byto 两个构造由于表示透明度增加了多少,和透明度变化到多少,注意透明度在 0~1 之间。下图中的是按下 qw 的效果,更改宿主的透明度,其中 q 按键使用 by 每次增加 -0.1 透明度,w 按键将透明度变化到 1


代码语言:javascript复制
 void addOpacityEffectBy(){
   Effect effect = OpacityEffect.by(
     -0.1,
     EffectController(duration: 0.5),
   );
   player.add(effect);
 }

 void addOpacityEffectTo(){
   Effect effect = OpacityEffect.to(
     1,
     EffectController(duration: 0.5),
   );
   player.add(effect);
 }
复制代码

另外 OpacityEffect 中还有 fadeInfadeOut 两个构造方法,本质上是基于 _OpacityToEffect 实现的。fadeIn 表示渐变到 1 而淡入,fadeOut 表示渐变到 0 而淡出。只是一个语义化的封装,没有什么特别之处,了解一下即可。


4. 颜色效果: ColorEffect

该效果可以为构件施加颜色滤镜,比如下面所示,在 1.5 s 之内,用蓝色颜色滤镜逐渐加到 40% 。这作为一个简单的冰冻效果还是不错的。

代码语言:javascript复制
void addColorEffect(){
  final effect = ColorEffect(
    Colors.blue,
    const Offset(0.0, 0.4),
    EffectController(duration: 1),
  );
  player.add(effect);
}
复制代码

什么的 Offset 对象表示颜色滤镜的程度变化范围,其中 0 表示不施加;1 表示把构建颜色完全变为该颜色。比如下图是取 1 的情况。


5. 沿路径运动: MoveAlongPathEffect

彩虹岛,是我童年的珍贵回忆,不知道大家有没有玩过。其中的小人可以发射一个彩虹桥,然后在弧线上走。这是一个 沿路径运动 的好场景。


如下,指定一条简单的二次贝塞尔曲线,通过添加 MoveAlongPathEffect 就可以让构件沿路径运动。另外关于 Path 对象,是绘制中一个非常重要的话题,在 《Flutter 绘制指南 - 妙笔生花》 小册中有详细的介绍,感兴趣的可以学习一下。

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

代码语言:javascript复制
Path path = Path()..quadraticBezierTo(50, -50, 100, 0);

void addMoveAlongPathEffect() {
  final Effect effect = MoveAlongPathEffect(
    path,
    EffectController(duration: 1.5),
  );
  player.add(effect);
}
复制代码

简单瞄一眼 MoveAlongPathEffect 的源码,可以看出本质上还是通过 PathMetric 进行计算的,所以万变不离其宗。渲染的本质总是和绘制相关,路径、色彩、图像、变换的基本知识在哪里都是通用的。


本文介绍了一下 ComponentEffect 一族的特效,该族特点是会持有一个 Componemt 类型的 target 对象,在 onMount 中初始化。各个特效的实现类,本质上就是对 target 构建属性的补间变化,产生动画效果。下一篇,我们将认识一下 EffectController ,如何对动画特效进行控制。那么本文就到这里,明天见 ~

  • @张风捷特烈 2022.06.13 未允禁转
  • 我的 掘金主页 : 张风捷特烈
  • 我的 B站主页 : 张风捷特烈
  • 我的 github 主页 : toly1994328

0 人点赞