前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Flutter&Flame 游戏 - 贰捌】pinball 源码分析 - 游戏主场景的构成

【Flutter&Flame 游戏 - 贰捌】pinball 源码分析 - 游戏主场景的构成

作者头像
张风捷特烈
发布2022-09-09 10:27:10
4800
发布2022-09-09 10:27:10
举报
文章被收录于专栏:Android知识点总结

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


前言

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


1. 游戏主界面的构成

通过前面四篇,我们分析了 pinball 项目的整体结构,以及资源加载、主菜单、角色选择和玩法介绍等面板。最后剩下最重要的一块,就是游戏的主界面,主要包括六个部分:背景发射器轨道小球碰撞得分物 以及底部 摆动挡板 ,其中最复杂的是各种碰撞体角色。


上面提及的游戏主界面构件,基本上都定义在 pinball_components 中。这也是 pinball 项目中文件最多,结构最复杂的包。

对游戏主界面的构成分析,也就是看这些构件以什么类型,如何分布在游戏场景中。下面我们就来一一介绍场景中的几个部分。


2.背景构件

主界面最吸引人的是表面有一定的 透视感深度感 ,这样就形成了一个视觉上的立体空间。其实看到资源图片就会知道,这只是图片本身的效果,并非真正的 3D 模型。


如下是背景图片资源,可以看出,图片本身就是带有透视效果的。另外背景图片的边缘是比较随意的,因为它只是一个背景,在其周围会有相关的覆盖物。


对资源进行定位,很容易知道背景图的使用场景,如下是资源管理工具会生成 boardBackground 方法应用获取背景图片:

接下来继续追踪,可以看到在 board_background_sprite_component 文件中使用到了背景资源。在分析代码时,根据细微的线索去追踪有价值信息,是一件非常有趣的事。我们面对复杂的源码体系,寻找合适的切入点非常重要,没有必要一开始就硬啃核心代码处理逻辑。从周边入手,一层层剥离外围,找出线索,逐步深入,是一个很好的研究方式。


如下,就定位到了背景所对应的构件 BoardBackgroundSpriteComponent 。其中在 onLoad 方法中通过背景图片资源,为 sprite 成员赋值,并且尺寸是原图的十分之一。


紧接着,可以继续追踪 BoardBackgroundSpriteComponent 的使用场景。如下,它在 PinballGameonLoad 方法中被加入到场景中:


2. 地板构件和小球构件

在背景的底层,可以看到有个 ArcadeBackground 组件,它对应的就是最底层的地板。我们上一篇说过,这个地板会随着选择的角色而变化,这里就来看一下其中的原因。

另外有一个小细节,在移动端是没有地板的,整个视口都是游戏面板。毕竟移动端是竖屏的,没有空间显示更多内容。


如下所示,主要显示的内容由 ArcadeBackgroundSpriteComponent 觉得,他会监听 ArcadeBackgroundState 的变化。在新状态产出时,会更新 sprite 成员对应的图像。

可以看出,这里的地板的图片资源是定义在 CharacterTheme 中的,每个实现类都有相关的资源图片。比如下面是 android 对应的资源,这样就不难理解为什么角色的变化,会让地板图片产生变化。


接下来,最后一个问题,选择角色主题的逻辑是由 CharacterThemeCubit 完成的,产出的是 CharacterThemeState。而这里源码是监听的是 ArcadeBackgroundState 状态,对应的是 ArcadeBackgroundCubit ,这显然是两个不同的 Bloc 。那这两者是如何产生关联的呢?也就是说选择角色时,CharacterThemeState 的变化如何通知到 ArcadeBackgroundCubit

ArcadeBackgroundCubit#onCharacterSelected 事件为线索,不难定位到:在 CharacterSelectionBehavior 中,会监听 CharacterThemeState 的变化,来触发 ArcadeBackgroundCubit 的事件,产出新的 ArcadeBackgroundState ,从而促使地板进行切换图片资,这个逻辑搭建可以梳理一下。


另外,从上面代码可以发现,小球 Ball 构件,也会受到角色主题的影响。仔细观察也不难发现,不同的角色主题,对应的小球颜色是不同的:

dash

android

sparky

通过查看 BallSpriteComponent 中逻辑的,可以知道小球构件会监听 BallState 的状态,来更新图片资源,而该资源就是定义在主题类中的。

比如 dash 主题对应的是小蓝球:

当用户选择某个角色主题,在 CharacterSelectionBehavior 中触发 onNewState 。如下红框在会寻找 Ball 对应的 BallCubit 来触发 onCharacterSelected 事件,产出新状态。从而更新小球的图片资源,这和地板的资源变化是一个道理。


3. 边界构件: Boundaries

在背景的上面是 Boundaries 构件:

从构件的定义中,很容易看出三个部分分别对应 boundary 文件夹中的三个图片。可以发现 pinall 项目无论是对 Flutter 中的组件,还是 Flame 中的构件,抽离分层的处理还是很细致和到位的。


通过图片资源可以看出,Boundaries 就是对背景之上的边界进行处理。比如左图的外框,中间是镂空的透明色,将背景图叠在其下,就可以遮住上面背景四周的部位。这样在视觉上就能营造出一种立体效果。


4.发射台构件:Launcher

Launcher 构件主要包括三个部分:发射杆发射台轨道 。如下是三个部分的示意:

从资源中可以看出,发射台轨道挡板 这些都是独立的资源。通过在主界面上拼接,进行组合,呈现的整体视觉效果。

如下 Launcher 构件在有四个子构件, LaunchRamp 是轨道、Plunger 是发射杆、RocketSpriteComponent 是发射台。另外 Flapper 构件用于处理边界,限制小球在外壁之内,试了一下,如果把下面的 Flapper 注释掉,小球就会飞出边界之外。 对于可以运行的代码,当我们不提明白一处的作用,可以将其屏蔽掉,看一下前后的差异,从而认识某个模块的作用。


5. 碰撞体

另外还有很多小的障碍物,用于碰撞后得分,这里就不一一细看了。在处理上都比较类似,可以根据资源中的图片来定位到相关的构件。


比如右侧中间的小恐龙,在游戏中会一直动,这对应的资源是 dino/animatronic 下的序列帧:


可以根据资源名称,追踪到 DashAnimatronic 构件,它是一个 SpriteAnimationComponent 。其中序列帧的资源使用的就是上面的图片:


底部可以摆动的两个挡板资源图片在 flipper 文件夹下,对应的构件是 BottomGroup ,包含左右两个_BottomGroupSide 构件。

整个游戏主界面的结构就介绍到这里,另外关于小球碰撞的相关处理,pinball 中使用的是 flame_forge2d ,我目前还没有研究,就先不分析了。下一篇,我们来看一下 Flame 中视口和相机的概念,并结合 pinball 中对相机的使用来实际体会相机的作用。那本文就到这里,明天见 ~

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 1. 游戏主界面的构成
  • 2.背景构件
  • 2. 地板构件和小球构件
  • 3. 边界构件: Boundaries
  • 4.发射台构件:Launcher
  • 5. 碰撞体
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档