【Flutter&Flame 游戏 - 贰陆】pinball 源码分析 - 游戏主页

8,101 阅读5分钟

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


前言

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

第一季完结,谢谢支持 ~


1.主界面视图

上一篇介绍了 pinball 中的资源加载逻辑以及 Loading 界面的布局结构。当加载完成之后,就会进入到如下的主菜单界面,有个大大的 Play 按钮。

可以看到此时两个吉祥物是在运动的,而且背景中也会显示排行榜的信息。这说明目前就已经进入了游戏的世界,通过源码可以看得更加清楚。如下所示:当资源加载完毕时,会显示 PinballGameLoadedView 组件:


通过源码可以看出 PinballGameLoadedView 主要有 3 个部分,通过 Stack 进行叠放。其中最下层是 GameWidget<PinballGame> ,也就是 Flame 的游戏场景:


2. 分数面板: _PositionedGameHud

下面来看另外两个组件, _PositionedGameHud分数面板 对于的组件。如下是_PositionedGameHud 的源码,可以看出只有在游戏处于 isPlaying 并且 !isGameOver 的状态下,才会显示分数面板。


另外可以 注意到,这里使用了两个 Bloc 中的数据: StartGameBlocGameBloc 来获取当前游戏状态。其中 StartGameState 中只维护了 StartGameStatus 状态数据。

如下 StartGameStatus 表示游戏开始前的状态,包括四种:initial 表示初始状态;selectCharacter 表示进入选择角色面板的状态;howToPlay 表示弹出 如何玩 面板时的状态。play 表示游戏开始的状态。

enum StartGameStatus {
  initial, /// Initial status.
  selectCharacter,/// Selection characters status.
  howToPlay, /// How to play status.
  play,  /// Play status.
}

GameBloc 中维护的状态数据比较多,比如当前的总分数 totalScore、倍率 multiplier 、小球所有奖励的历史信息 bonusHistory 等。

目前 _PositionedGameHud 中使用的是 GameStatus 状态:默认状态是 waiting 状态;游戏开始是 playing 状态;游戏结束是 gameOver 状态:

enum GameStatus {
  waiting,
  playing,
  gameOver,
}

也就是说,左上角的分数面板通过两个 Bloc 中的状态值,保证只在游戏进行中才会显示:


3. info 图标:_PositionedInfoIcon

最后一个是 _PositionedInfoIcon 组件,如下代码在可以看出,它只是一个显示在左上角的 IconButton ,点击时执行 showMoreInformationDialog 方法。另外通过 BlocBuilder 中的构建逻辑可以看出,只有当游戏状态是 isGameOver ,才会显示。


界面显示如下,在游戏结束后,点击左上角按钮,会弹信息框对该项目进行介绍:

提示框对应的组件,可以详见源码在的 MoreInformationDialog ,这和游戏本身关系不大,就不赘述了。到这里,我们就对 pinball 界面结构有了整体的认知。


4. 游戏中的浮层

《【Flutter&Flame 游戏 - 贰贰】菜单、字体和浮层》中介绍过浮层在 Flame 游戏场景中的使用。这里刚好可以通过实际的场景来加深理解。如下 GameWidget 中有三个浮层:

其中 PlayButtonOverlay 就是开始菜单中的 Play 按钮。在点击时,通过 StartGameBloc 触发 PlayTapped 事件来通知游戏开始。


其中 ReplayButtonOverlay 结束游戏中的 Replay 按钮。在点击时,通过 GameBloc 触发 GameStarted 来重置游戏状态;通过 StartGameBloc 触发 PlayTapped 事件来通知游戏开始。


最后是 MobileControls,可以看出只有在移动端,才会添加这个浮层。原因也很简单,因为移动端一般不会外接键盘,所以通过 MobileControls 来模拟按键,触发事件。


另外,从中我们能学到一个非常实用的小知识:在移动端通过 Game 对象可以发送按下键盘的事件。这样在移动端,可以通过按扭的事件,来发送键盘事件,这样在游戏中只需要考虑键盘事件即可。如下的 MobileDpad 组价是一个透明层,左右两侧的点击分别对应按键的左右:


本文我们分析了 pinball 主界面的布局,以及相关组件的显示逻辑,并且认识了 StartGameBlocGameBloc 两个维护游戏状态的Bloc 。下一篇我们将继续分析 pinall 的源码,看一下如何选择角色、如何弹出 how to play 的信息面板。那本文就到这里,明天见 ~

\