【Flutter&Flame 游戏 - 贰壹】视差组件 | ParallaxComponent


theme: cyanosis

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


前言

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

第一季完结,谢谢支持 ~


1. 什么是 Parallax

Parallax 译为 视差 。可以想想一下,在你做火车时,旁边的树会飞速向后退,而远处的云却在缓慢运动,这就是由于物体距观察者距离不同,而产生的 视差 。在某些游戏中我们也希望模拟这种视觉感受,这就是 ParallaxComponent 存在的意义。

首先 ParallaxComponent 的特点是会以某个基础速度 运动,其次它支持多以不同速度运动的图层。没找到什么好的图片素材,Flame 官方的这个案例还不错,就直接拿来看了。如下选中的五张图片分别是从内向外依次是:

  • bg.png :背景
  • mountain-far.png : 远山
  • mountains.png : 近山
  • trees.png :远树
  • foreground-trees.png : 近树

通过 ParallaxComponent 进行叠合运动,就可以产生如下的效果:远处的图层运动慢,近处的图层运动快:代码详见 【21/01】

如下是代码实现,通过 loadParallaxComponent 方法加载 ParallaxComponent 对象。其中需要传入图层对于的图片数据,索引靠后的图层在前方。另外 baseVelocity 是图层运动的基础速度;velocityMultiplierDelta 是前一层和后一层的速度之比,也就相当于视差的倍率。

```dart class BasicParallaxExample extends FlameGame {

final _imageNames = [ ParallaxImageData('parallax/bg.png'), ParallaxImageData('parallax/mountain-far.png'), ParallaxImageData('parallax/mountains.png'), ParallaxImageData('parallax/trees.png'), ParallaxImageData('parallax/foreground-trees.png'), ];

@override Future onLoad() async { final ParallaxComponent parallax = await loadParallaxComponent( _imageNames, baseVelocity: Vector2(20, 0), velocityMultiplierDelta: Vector2(1.4, 1.0), ); add(parallax); } } ```


2. 指定某层视差速度

通过 loadParallaxComponent 直接加载多个层,有个缺点:每层间的速度比值是恒定的。如果想要动态指定每层的速度该怎么办呢?我们可以通过创建一个个的层来指定不同的速度比:代码见 【21/02】


通过 loadParallaxLayer 方法,可以加载一个 ParallaxLayer 对象。如下通过 formLayerByMap 方法,把 Map 对象,转化成 ParallaxLayer 列表。

```dart final _layersMeta = { 'parallax/bg.png': 1.0, 'parallax/mountain-far.png': 1.5, 'parallax/mountains.png': 2.3, 'parallax/trees.png': 3.8, 'parallax/foreground-trees.png': 6.6, };

Future > formLayerByMap(Map data) async{ List result = []; for(String image in data.keys){ ParallaxLayer layer = await loadParallaxLayer( ParallaxImageData(image), velocityMultiplier: Vector2(data[image]!, 1.0), ); result.add(layer); } return result; } ```


ParallaxComponent 组件中,传入 Parallax 对象,该对象构造时,需要指定 ParallaxLayer 列表。这样就可以指定不同层的速度比值,更精确地控制视差的效果。

dart @override Future<void> onLoad() async { List<ParallaxLayer> layers = await formLayerByMap(_layersMeta); final parallax = ParallaxComponent( parallax: Parallax( layers, baseVelocity: Vector2(20, 0), ), ); add(parallax); }


3. 加载序列帧资源

如下在最外层添加一个序列帧动画,可以看出此时由于背景在向后运动,所以序列帧所在的层保持静止即可。在视觉上会有一种飞机在向前飞的错觉,这就是相对的参考系。代码见 【21/03】

如下是创建一个序列帧层的方式,使用 ParallaxAnimationData 加载。ParallaxLayer 创建完毕之后,添加到上面的 layers 列表中即可。

dart final ParallaxLayer airplaneLayer = await loadParallaxLayer( ParallaxAnimationData( 'parallax/airplane.png', SpriteAnimationData.sequenced( amount: 4, stepTime: 0.2, textureSize: Vector2(320, 160), ), ), repeat: ImageRepeat.noRepeat, velocityMultiplier: Vector2.zero(), fill: LayerFill.none, alignment: Alignment.center, );

这里说明一下:只是介绍一下如何在 ParallaxComponent 中加入序列帧图层,像小人这种主角,一般还是作为一个 Component 加入游戏场景中的,这样方便操作。


4. 简单射击

结合前面学的知识,完成一个简单的设计场景应该不在话下,代码见 【21/04】

另外, ParallaxComponent 也可以抽离出来,单独作为一个构建来使用,没必要把太多逻辑写在 Game 实现类中。如下,通过 Background 构件加载 Parallax ,实现视差的背景效果。


接下来大家可以自己拓展一下,比如添加敌人、射击击中的检测、得分显示,和之前的小案例是一样的,这里就不过多引申了。其实对于游戏而言, UI 的资源也是一个很大的瓶颈。有些好想法,但由于设计素材缺乏,也很难实现。那本文就到这里,明天见 ~


番外: Flame 1.2.0 更新内容:

Falme 最近更新了一个版本,到了 1.2.0 ,我们来看一下目前进行了哪些变化:

首先,Compoment 的一个属性发生了变化:

dart Compoment#shouldRemove ==> bullet.isRemoving


对比 1.1.11.2.0 可以发现,新版本中对 text 进行了优化:之前文字通过一个 text.dart 文件进行实现,现在多了一个 text 的包,并且提供了 SpriteFontRenderer 来渲染精灵图字体。但目前源码看来并不是很好用,需要指定的参数非常麻烦,特别是 GlyphData ,感觉需要和特定的工具结合,加上解析才能用。


另外 1.2.0 中增加了 utils 包,其中有两个贝塞尔曲线相关的工具函数:


另外,对 Component 的事件支持做了优化,提供了 events 包:关于构件的事件通过 XXXCallback 进行处理,这是为了替换掉以前的 XXXable ,这点还是比较赞的。


effects 中提供了 AnchorEffect 可以对构件的锚点进行特效处理:


components/input 包中增加了 KeyboardListenerComponent ,这样监听键盘事件可以更方便了:


components/mixin 中增加了三个混入类 :

components 中增加了两个显示 fps 相关的构件:

最后 assets 包并入了 cache 包中:


\

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值