持续创造,加快生长!这是我参加「日新方案 6 月更文应战」的第 26 天,点击检查活动详情


前言

这是一套 张风捷特烈 出品的 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 游戏 – 贰贰】菜单、字体和浮层
  • 【Flutter&Flame 游戏 – 贰叁】 资源办理与国际化
  • 【Flutter&Flame 游戏 – 贰肆】pinball 源码剖析 – 项目结构介绍
  • 【Flutter&Flame 游戏 – 贰伍】pinball 源码剖析 – 资源加载与 Loading
  • 【Flutter&Flame 游戏 – 贰陆】pinball 源码剖析 – 游戏主菜单界面
  • 【Flutter&Flame 游戏 – 贰柒】pinball 源码剖析 – 人物选择与玩法面板
  • 【Flutter&Flame 游戏 – 贰捌】pinball 源码剖析 – 游戏主场景的构成
  • 【Flutter&Flame 游戏 – 贰玖】pinball 源码剖析 – 视口与相机

第一季完结,谢谢支撑 ~


1. 加载界面在哪里

pinball 在游戏开端时,会显现资源加载的界面,是一个加载的进展条,如下所示。那问题来了,怎么定位这个界面在源码中的位置。这样才干有时机剖析资源加载的代码:

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


从一些外在表征去定位源码,是一个十分有用手段,比方在资源文件中能够看出 loading_game 的文件夹,其间包含着 io_pinball.png 的图片。这就阐明只需找到什么地方运用了 io_pinball.png,就能够发现相关视图处理的代码逻辑

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


全局查找一下,就不难发现,该图片称号在 lib/gen/assets.gen.dart 中被运用:

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading

点进去能够看到该文件是经过工具主动生成的资源办理代码,ioPinball 代表这个图片资源:

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


然后 顺藤摸瓜 ,就能够找到图片资源运用的场景,这就像根据头绪来探查本相。现在知道一开端加载的界面的代码在 lib/assets_manager/views/assets_loading_page.dart 中。这样咱们就能经过源码来剖析一下界面完成的逻辑,包括界面怎么布局,进展怎么改变等。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


2. 加载界面 – 布景与图片

加载中的布局主要右四个部分组成,分别是 布景 图片Loading 文字以及 进展条

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading

在上面能够看出,图片自身布景是通明的,所以布景中的横线条纹在源码中一定有其出处:从界面组件 AssetsLoadingPage 的完成中能够看出,布景是经过 CrtBackground 装修进行绘制的。其实这儿的 Container 没有运用其他特点完全能够换成 DecoratedBox 组件,愈加简便:

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading

这儿的选择是自界说子类集成自 BoxDecoration,感觉并没有太大的必要性。直接运用 BoxDecoration 指定 gradient 参数就行了,不过也无伤大雅。

class CrtBackground extends BoxDecoration {
  /// {@macro crt_background}
  const CrtBackground()
      : super(
          gradient: const LinearGradient(
            begin: Alignment(1, 0.015),
            stops: [0.0, 0.5, 0.5, 1],
            colors: [
              PinballColors.darkBlue,
              PinballColors.darkBlue,
              PinballColors.crtBackground,
              PinballColors.crtBackground,
            ],
            tileMode: TileMode.repeated,
          ),
        );
}

这儿的图片组件是经过 ioPinball 目标调用 image() 办法获取的,其实这就是主动生成的代码给的一个方式语法糖

Padding(
  padding: const EdgeInsets.symmetric(horizontal: 20),
  child: Assets.images.loadingGame.ioPinball.image(),
),

ioPinball 类型为 AssetGenImage ,是一个 ImageProvider ,也就是 Image 组件在需求传入的 image 参数类型。该类中的 image 办法,提供了结构 Image 所需的可选特点,回来 Image 组件。并将自身作为结构 Image 组件的 image 入参:

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading

也就是说,下面的两种写法是等价的,只不过上面在的写法不需求嵌入在 Image 组件下罢了。本质上没有什么区别,仅仅简化书写方式罢了:

Assets.images.loadingGame.ioPinball.image()
等价于
Image(image:Assets.images.loadingGame.ioPinball)

3. 加载界面 – 加载中文字与指示器

如下所示: Loading 文字三个点会顺次出现,是个循环动画。另外加载进展经过下面的指示器来显现,整个加载中界面的 事务逻辑 只有一个: 加载进展值的核算。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


Loading... 的循环动画是经过 AnimatedEllipsisText 组件完成的,这个组件感觉挺有用。假如以后有需求,能够直接复制曩昔用,这就是 Flutter 组件化的好处。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading

简略瞄一眼源码,这儿 ... 不断运动的动画,是经过 Timer.periodic 周期触发定时器完成的,每 500 ms 触发一次更新。由于这儿是独自抽离的 AnimatedEllipsisText ,所以 setState 也仅仅部分的组件更新,不会影响触发外界组件的从头构建。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


最终,是加载页最核心的事务逻辑,该项目是经过 flutter_bloc 来进行状况办理的。这儿运用 AssetsManagerCubit 来保护加载资源的逻辑,其间状况数据是 AssetsManagerState ,该状况量能够获取加载的进展。这儿经过 BlocBuilder 来监听状况的改变来构建组件。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading

从代码中能够看出,这个像素风格的进展条,经过 PinballLoadingIndicator 组件进行显现。结构中传入进展值,赤色的区域就会占有相应的百分比。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


PinballLoadingIndicator 组件的源码完成中能够看出,这个像素风格的进展条是经过六个 _InnerIndicator 组件进行显现的。仔细数一下上图,就会发现整体是由六个细条,从上到下排列的而构成的。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


4. 资源加载的事务逻辑

上面咱们知道,资源加载的核心逻辑以及过程中的进展状况数据,是由 AssetsManagerCubit 进行保护的。如下,在 lib/assets_manager 文件夹中办理着资源加载的 bloc 事务逻辑和 views 视图:

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading

下面咱们就进入 AssetsManagerCubit ,来看一下资源是怎么加载的,以及进展状况的产出。AssetsManagerCubit 结构时需求传入如下两个目标,其间只有一个 load 异步办法,自身仍是比较简略的。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


这个 load 办法,会在 AssetsManagerCubit 结构时被立刻触发:

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


load 办法在有一个小细节,一开端延迟了一秒钟才开端真正加载,这是由于加载是个贵重的操作,先给出 1s 的时间,让 UI 先展示出来,然后再真正进行加载资源。这儿加载资源的异步使命经过 loadables 列表进行保护:

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


异步操加载资源的使命,被界说在个个模块中。比方 _game.preLoadAssets() 办法,会回来一切构件图片资源加载的异步办法,其他几个也是相似。当你看到源码的这么多资源加载的异步办法,就会理解为什么这个 load 会是贵重的。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


然后经过 _triggerLoad 部分函数目标,分三波顺次触发这些异步使命。每次异步使命完成时,都会产出新的状况,让已加载的资源数加一。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading


这样状况数据中的进展值 progress 就会改变,整个加载的小体系就得以运转,从事务逻辑到视图更新展示,能够领会一下,bloc 在其间的人物,品味一下状况办理的价值。

【Flutter&Flame 游戏 - 贰伍】pinball 源码分析 - 资源加载与 Loading

到这儿,pinball 初次进入时资源加载,以及进展的显现流程就介绍完毕了。那本文就到这儿,明天见 ~

  • @张风捷特烈 2022.06.21 未允禁转
  • 我的 大众号: 编程之王
  • 我的 主页 : 张风捷特烈
  • 我的 B站主页 : 张风捷特烈
  • 我的 github 主页 : toly1994328

\