持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 10 天,点击查看活动详情
前言
这是一套 张风捷特烈 出品的 Flutter&Flame 系列教程,发布于掘金社区。如果你在其他平台看到本文,可以根据对于链接移步到掘金中查看。因为文章可能会更新、修正,一切以掘金文章版本为准。本系列文章一览:
- 【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 游戏 - 贰贰】菜单、字体和浮层
- 【Flutter&Flame 游戏 - 贰叁】 资源管理与国际化
- 【Flutter&Flame 游戏 - 贰肆】pinball 源码分析 - 项目结构介绍
- 【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading
- 【Flutter&Flame 游戏 - 贰陆】pinball 源码分析 - 游戏主菜单界面
- 【Flutter&Flame 游戏 - 贰柒】pinball 源码分析 - 角色选择与玩法面板
- 【Flutter&Flame 游戏 - 贰捌】pinball 源码分析 - 游戏主场景的构成
- 【Flutter&Flame 游戏 - 贰玖】pinball 源码分析 - 视口与相机
第一季完结,谢谢支持 ~
1. Component 的树形结构
通过前面八篇的尝鲜,或说预热,我们可以感知到无论是主角、怪兽、文字、子弹、触点都是 Component 。它是游戏的基本构建模块,可以表示任何需要被渲染、更新的内容。
下面是 Component 类的部分结构,可以看出 Component 是一个普通类。其本身会持有父级构件,以及子级构件集合。也就是说 Component 本身是一个树形结构的节点类,认识到这一点至关重要。
正是由于树形结构的特点,Component 类有添加和 移除 构件的能力。如下所示,可以通过 add 方法添加子级构件,也可以通过 addToParent 方法,将自身添加到父级构件中。
前面介绍过子弹、怪物消失,使用的是 removeFromParent 方法。如下源码中可以看出,是调用父级构件 _parent 的移除方法,把当前构件对象从父级节点上移除:
1 | dart复制代码---->[Component#removeFromParent]---- |
2. Component 生命周期状态
Component 中有一个 _state 属性,其类型为 LifecycleState 枚举,用于表示构件的状态:
其中有如下 6 种状态,初始状态是 uninitialized ,表示未初始化,也就是构件实例化时的默认状态。前面知道构件中有个 onLoad 的异步方法用于加载资源,在执行异步方法的前一刻就是 loading 状态。该状态会持续到异步方法执行完毕,变成 loaded 状态。
1 | dart复制代码enum LifecycleState { |
Component 是树形结构的节点,当某个 Component 添加到父节点上后,就会变成 mounted 状态。相关代码如下所示:
另外当父级执行 remove 方法时,入参的子构件非 removing 状态时,会被加入到 lifecycle._removals 列表中,等待下帧触发时移除。此时该子构件的状态为 removing 。当构件被从父节点上移除后,其状态为 removed ,就变成了孤魂野鬼,等待被 GC 回收。
如下图是六种状态的转换示意图,其实还是比较清晰的。了解这六种状态,在下篇介绍 Component 生命周期方法时,就会更好理解。
另外 Component 中关于生命周期状态有三个 get 方法,这里介绍一下:
- isLoaded:非
uninitialized且非loading状态,表示异步加载任务是否已经完成。 - isMounted:
mounted或removing状态,表示构件依然在树上。 - shouldRemove:
removing状态,表示构件已被收集到移除列表中,将在下一帧中被移除。
1 | dart复制代码---->[Component]---- |
3. Component 的衍生类
在 Flame 的 components 包中的文件,是对 Component 的衍生。其中一些 mixin ,比如 Draggable 、Hoverable 、Tappable 等都是依赖于 Component ,情理上来说也算是 Component 的衍生产物。
Component 大致可分为三大类,支持定位和变换的 PositionComponent 、附加效果的 Effect 、以及直接继承自 Component 的少数构建。
其中群体最庞大的是 PositionComponent ,这一族引入了 尺寸 、锚点、位置 、旋转 、缩放 等属性,决定了该族构件将非常实用:
我们之前用的 SpriteComponent 、TextComponent 、SpriteAnimationComponent 等都是 PositionComponent 一族的。另外,自定义的子弹、主角、怪兽,也都是 PositionComponent。
另外,Effect 一族定义在 effects 包中,我们在前面用到的 MoveEffect 就是这类的构件。在之后的学习中我们再深入认识其他的效果,或者自定义 Effects 。
4. 自定义 Component
前面的案例中我们也尝试过自定义 Component ,比如 Adventurer 、Monster 、TouchIndicator 等。其实自定义 Component 和 Flutter 中自定义 Widget 的功效类似,都是为了把一些通用的构成逻辑进行封装,以便复用和管理。
比如通过下面的 Monster 类,可以生成多个怪兽对象:可以定义不同的帧序列和生命值,它们对于玩家来说就是两个不同的怪兽。对于编程者而言它们都是通过 Monster 构建类实例化的对象,本质没有什么区别。代码详见 【09/01】
1 | dart复制代码class Monster extends SpriteAnimationComponent with Liveable { |
另外,通过自定义构件类,可以覆写 Component 的相关回调方法,监听相关状态,处理逻辑。这里先对 Component 认识到这里,下一章我们将信息探讨一下 Component 的生命周期回调。那时你就会对 Component 有一个更深的认知,那么本文就到这里,明天见 ~
@张风捷特烈 2022.06.03 未允禁转我的 公众号: 编程之王我的 掘金主页: 张风捷特烈我的 B站主页: 张风捷特烈我的 github 主页: toly1994328
\
本文转载自: 掘金