【Flutter&Flame游戏 - 拾伍】粒子系统 P

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


前言

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

第一季完结,谢谢支持 ~


1. Flame 中的粒子系统

Flame 中,一切的呈现都依赖于构件,粒子系统也不例外。目前和粒子相关的有两个构件,其中 ParticleComponent 已经过时了,不推荐使用。所以 Flame 中的粒子系统主要使用的是 ParticleSystemComponent 构件。


首先说一下什么是粒子,举个观的例子:现实中烟花的爆炸,会生成大量细小的颗粒,维持短暂的时间后消失。像这样的大量的,有存在时间的显示物就可以通过粒子系统来呈现。Flame 的官方案例中有一些案例,但放在一块有些杂乱,这里将用 2 篇文章,由详细介绍一下 ParticleSystemComponent 的使用。

image-20220607121048917.png


2. 通过 ParticleSystemComponent 显示一个粒子

如下,使用 ParticleSystemComponent 构件,显示一个生命时长为 1 s 的圆形粒子:代码详见 【15/01】

使用 ParticleSystemComponent 有三个步骤:

  • 1. 创建 Particle 粒子对象
  • 2. 创建 ParticleSystemComponent 构件对象
  • 3. 将构建加入到树中,进行显示

其中 2、3 步骤非常简单,所以对于粒子系统而言,如何创建 Particle 对象是重中之重。这里显示一个圆形的粒子,可以使用 Particle 的衍生类 CircleParticle 。其中有三个入参:paint 表示粒子的绘制画板;radius 表示粒子的半径;lifespan 表示粒子的存在多少秒后消失。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dart复制代码void createParticle(){
// 创建 Particle 对象
Paint circlePaint = Paint()..color = Colors.white;
Particle particle = CircleParticle(
paint: circlePaint,
radius: 20,
lifespan: 1,
);
// 创建 ParticleSystemComponent 构件
final ParticleSystemComponent psc = ParticleSystemComponent(
particle: particle,
);
// 添加 ParticleSystemComponent 构件
add(psc);
}

3. 区分 ParticleSystemComponent 和 Particle

在进一步介绍粒子系统之前,有必要先认识一下 ParticleSystemComponentParticle 两个类之间的区别与联系。从如下 ParticleSystemComponent 源码中可以看出,它是一个 PositionComponent ,构造时必须传入 Particle 对象。另外构造时还可以指定一些 PositionComponent 的大小、位置、锚点等属性。


Particle 本身只是抽象类,不是 Component 的衍生类,它有自己的衍生体系。

如下,在 Flameparticles 包中定义了很多实现类以供使用:


瞄一下 CircleParticle 的源码可以看出,其实现还是非常简单的,就是画个圈而已。如果有需要的话,我们也可以根据需求来自己定义 Particle 。核心就是在 render 方法了进行绘制,有了 Canvas ,就可画万物。


4. 移动粒子 MovingParticle

Particle 的衍生类中可以看到有很多支持传入 child 的例子,这些实现类往往可以基于某个粒子,是些特点的功能。比如 MovingParticle 可以让粒子进行运动,如下所示:可以让粒子在 lifespan 时间内,按照 curve 的变化曲线,从起点移动到终点。 【15/02】

1
2
3
4
5
6
7
8
9
10
11
12
dart复制代码// 创建 Particle 对象
Paint circlePaint = Paint()..color = Colors.white;
Particle particle = MovingParticle(
lifespan: 3,
curve: Curves.easeIn,
from: Vector2.zero(),
to: Vector2(200,0),
child: CircleParticle(
radius: 20.0,
paint: circlePaint,
),
);

5.批量生成粒子

Particle 有个 generate 的方法可以生成多个粒子,下面是 Flame 官方的一个小例子,感觉挺有趣,这里来看一下。代码详见 【15/03】

这里通过 Particle.generate 生成多个粒子,其中 count 表示粒子生成粒子的数量,generator 是根据索引生成 Particle 的函数;再使用 MovingParticle 实现粒子的移动;另外使用 PaintParticle 通过调节 paintblendMode ,产生叠合效果。

其实这里不用 PaintParticle ,直接设置 CircleParticle#paintblendMode 也可以得到相同的效果。可能是案例想多介绍一种 Particle 吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
dart复制代码final List<Color> colors = [
const Color(0xffff0000),
const Color(0xff00ff00),
const Color(0xff0000ff),
];

final List<Vector2> positions = [
Vector2(-10, 10),
Vector2(10, 10),
Vector2(0, -14),
];

// 创建 Particle 对象
Particle particle = Particle.generate(
count: 3,
lifespan: 3,
generator: (i) => PaintParticle(
paint: Paint()..blendMode = BlendMode.difference,
child:MovingParticle(
curve: Curves.easeIn,
from: positions[i],
to: i == 0 ? positions.last : positions[i - 1],
child: CircleParticle(
radius: 20.0,
paint: Paint()..color = colors[i],
),
),
));

本问简单介绍了一下 ParticleSystemComponent 的使用,并了解了 CircleParticleMovingParticlePaintParticleParticle.generate 的使用。下一篇我们将进一步认识 Particle 一族,并结合随机数来完成某些粒子效果。那本文就到这里,明天见 ~

\

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%