赞
踩
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 17 天,点击查看活动详情
这是一套 张风捷特烈 出品的 Flutter&Flame
系列教程,发布于掘金社区。如果你在其他平台看到本文,可以根据对于链接移步到掘金中查看。因为文章可能会更新、修正,一切以掘金文章版本为准。本系列源码于 【toly_game】 ,如果本系列对你有所帮助,希望点赞支持,本系列文章一览:
第一季完结,谢谢支持 ~
在上一篇中,我们知道了如何使用 ParticleSystemComponent
构建显示粒子。这篇文章将详细介绍一下 Flame
中内置的粒子种类。Particle
抽象类共有如下十几种实现类:
其中 SingleChildParticle
一族在构造时需要指定一个 Particle
,主要是为指定粒子进行动画变换,比如 移动
、旋转
、缩放
等。
另外,我们可以指定 Sprite
、 SpriteAnimation
、Image
等图片资源,作为粒子。也可以使用 ComponentParticle
将一个构建作为粒子,下面通过粒子来详细认识一下。
在 第七篇 中,我们实现了如下的点触序列帧播放,那时是通过自己维护 SpriteAnimationComponent
完成的。它在生成后,会在一定时间内消失,而且拖动时产生大量的单体,很适合通过粒子来处理。
如下,通过 SpriteAnimationParticle
携带 SpriteAnimation
,可以实现相同的效果。默认情况下 SpriteAnimationParticle
的生命时长和动画一致,也就是序列帧播放完毕就消失。代码详见 【16/01】
```dart void createIndicator(Vector2 position) { SpriteAnimation indicator = SpriteAnimation.spriteList( sprites, stepTime: 1 / 15, loop: false, );
// 创建 Particle 对象 Particle particle = SpriteAnimationParticle( animation: indicator, size: Vector2(30, 30), ); // 创建 ParticleSystemComponent 构件 final ParticleSystemComponent psc = ParticleSystemComponent( particle: particle, position: position, anchor: Anchor.center, ); // 添加 ParticleSystemComponent 构件 add(psc); } ```
下面来看一下 AcceleratedParticle
,它可以指定速度和加速度让粒子进行运动。比如下面,在点击时,随机产生 第一象限
的 Verctor2
作为速度和加速度。这样就会产生在第一象限产生随机的加速粒子。代码详见 【16/02】 注
: Y 轴正方向向下,所以视右下方位第一象限。
Vector2
的 random
方法,可以生成 (0, 0)
~ (1, 1)
的随机点位,如下的 randomVector
的作用是生成 (0, 0)
~ (300, 300)
的随机点位:
```dart final Random _random = Random();
Vector2 randomVector() { Vector2 base = Vector2.random(_random); return base * 300; } ```
如下 createParticle
方法中,通过 Particle.generate
一次生成 10
个加速粒子,并且速度和加速度随机:
```dart void createParticle(Vector2 position) { CircleParticle circleParticle = CircleParticle( radius: 1, paint: Paint()..color = Colors.white, );
Particle particle = Particle.generate( count: 10, lifespan: 1, generator: (i) => AcceleratedParticle( child: circleParticle, acceleration: randomVector(), speed: randomVector(), position: position), );
final ParticleSystemComponent psc = ParticleSystemComponent(particle: particle); add(psc); } ```
虽然粒子是随机的,但是我们也可以进行控制。比如如何让粒子四散,也就是速度和加速度的矢量可以随机在四个象限中出现。另外加了一点小优化,粒子颜色每次都随机生成:【16/03】
其实这是一道简单的数学题, base
在 (0, 0) ~ (1, 1)
,表示只能在第一象限取值。如下左图,浅蓝色是随机点位取值范围;其实只要简单地对取值范围平移一下,就可以取 (-0.5, -0.5) ~ (0.5, 0.5)
,也就是取值范围可以包含四个象限的坐标。
dart Vector2 randomVector() { Vector2 base = Vector2.random(_random); // (0, 0) ~ (1, 1) Vector2 fix = Vector2(-0.5,-0.5); base = base + fix; // (-0.5, -0.5) ~ (0.5, 0.5) return base * 200; }
如果只想生成 X 轴下方的矢量,向左偏移 0.5
即可:
dart Vector2 base = Vector2.random(_random); // (0, 0) ~ (1, 1) Vector2 fix = Vector2(-0.5,0); base = base + fix; // (-0.5, 0) ~ (0.5, 1) return base * 200;
SingleChildParticle
一族的使用方式非常类似,就是给一个例子添加变换的效果,这里就不一一介绍了。
粒子可以用在子弹消失时,产生爆炸效果。比如下面所示,可以在主角子弹打到怪物身上消失后,产生上面的爆炸粒子的效果:代码详见 【16/04】
代码实现很简单,如下 tag1
处,是主角子弹碰到怪物时的场景。通过 createParticle
创建粒子即可:
dart @override void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) { super.onCollision(intersectionPoints, other); if (type == BulletType.hero && other is Monster) { removeFromParent(); createParticle(position+Vector2(size.x/2,0)); // tag1 } if (type == BulletType.monster && other is HeroComponent) { removeFromParent(); } }
还有几个粒子源码比较简单,就直接看下它们的源码实现。ComponentParticle
中必须传入一个 Component
,前面说过 Particle
最核心的就是对绘制的实现。如下,在 render
方法中,直接使用 Component
的 render
方法:
ComputedParticle
源码更简单,它将 Canvas
作为 ParticleRenderDelegate
的回调参数,暴露给使用者,在 render
方法中触发回调。也就是说 ComputedParticle
可以通过 renderer
方法把绘制权交给使用者。
ComposedParticle
中必须传入 Particle
列表,在 render
、update
中遍历子粒子列表,执行绘制和更新。
可以看出,这三者的源码都非常简单,都是借用它物来完成自身的功能,相当于一层包裹,简化使用。
ImageParticle
也非常简单,就是绘制 ui 包中的 Image
对象而已:
总的来看 Particle
就是一个 单体
,它的核心是绘制方法。到这里,我们也对粒子系统有了较深的理解。粒子相对于构建来说,感觉更加轻量。比如一个 ParticleSystemComponent
可以渲染 100
个粒子,这对比与:把 100
个粒子都作为 Component
加入场景中,高低立判。那本文就到这里,明天见 ~
@张风捷特烈 2022.06.11 未允禁转
我的 公众号: 编程之王
我的 掘金主页
: 张风捷特烈我的 B站主页
: 张风捷特烈我的 github 主页
: toly1994328\
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。