gamemakerstudio2 粒子系统超详细详解

分类栏目:gamemaker教程

184

粒子系统是一种增强视觉效果的利器。

它可以模拟一些诸如烟花、爆炸、火焰、雪花、下雨、灰尘、云雾、轨迹等等抽象的视觉效果。


那么,做一种粒子分为几步?

一、定义粒子属性。

二、释放粒子。


对,就这么简单。


一.定义粒子属性:

1.创建粒子系统和粒子类型:

a=part_system_create()//创建粒子系统
b=part_type_create()//创建粒子类型

我们创建了a,b两个变量,分别是粒子系统和粒子类型。(一个粒子系统可以有多个粒子类型,比如a粒子系统有b,c,d···等等个粒子类型)


2.定义粒子属性:

2.1:我们先要定义粒子长什么样,可以选择引擎自带的形状,也可以选择我们自己的精灵。

下面两个函数选其一

part_type_shape(b, pt_shape_XXXX)//定义粒子基础形状

如果用自带的形状,就用这个函数,

第一个参数写之前定义好的粒子类型b,

第二个参数需要写引擎自带的常量,他们分别代表了不同形状:

part_type_sprite(b, sprite, animate, stretch, random)//使用精灵图像定义粒子形状

如果使用我们自己的精灵图像,使用这个函数,

第一个参数还是写之前定义好的粒子类型b,后面不再赘述。

第二个参数写精灵的名字,

第三个参数,是否播放精灵的动画,是写1,否就写0(1=true,0=fasle,本质是一样的,写数字更省事)

第四个参数,是否延长精灵的动画以匹配粒子寿命,是写1,否就写0。(我猜它是把精灵的整个动画延长到整个粒子寿命,粒子死亡的那一刻正好播放完最后一帧,我没有实际使用过,暂时用不上)

第五个参数:是否随机选择一个精灵子图像。(这样我们可以把很多不同的基础形状放在同一个精灵的不同帧里面,在生成的时候随机选择,有很奇妙的效果)


2.2:定义粒子大小和缩放比

part_type_size(ind, size_min, size_max, size_incr, size_wiggle)//定义粒子大小

第二和第三个参数分别定义粒子的初始大小的最小值和最大值,如果它们是一样的,那么粒子初始大小永远就是那个值,如果不一样,就是在两个值中间随机的生成,

第四个参数,每帧增加多少或者减少多少,粒子渐渐变大或者渐渐变小的效果就是从这里来的,不变的话就写0,

第五个参数,每帧随机的增加多少或者减去多少,如果你想添加一些“动感”元素,在这里写一个合适的值,不想要的话就写0。

part_type_scale(ind, xscale, yscale)//定义粒子缩放比

这个很好理解,缩放比嘛。


2.3:定义粒子运动和方向

part_type_speed(ind, speed_min, speed_max, speed_incr, speed_wiggle)//定义粒子速度
part_type_direction(ind, dir_min, dir_max, dir_incr, dir_wiggle)//定义粒子运动方向
part_type_orientation( ind, ang_min, ang_max, ang_incr, ang_wiggle, ang_relative )//定义粒子角度

这仨函数和定义粒子大小的函数基本一样,

第二、三个参数是最小最大值,

第四个每帧增加多少或者减少多少,

第五个每帧随机增加多少或者减少多少,

在应用中,比如火焰的火花粒子,是往上飘,越来越快,左右摇摆方向不定,越来越小,那么我们就可以在part_type_size中设为每帧-0.05,在part_type_speed中设为每帧+0.05,在part_type_direction中每帧随机的加或减去30,这样就拥有了火花的这些属性,但是否形象,可能需要调一下值。

至于part_type_orientation的第六个参数,可以选择是否让粒子方向朝向它的运动方向,请想象一堆小蝌蚪游泳,它们就是你的粒子,想象它们的头的角度,就是这个参数表达的意思。

part_type_gravity(ind, grav_amount, grav_direction)//定义粒子重力方向和强度

如果写了这个函数,那么我们的粒子就会受到“引力”,我们可以定义“引力”的方向和强度,

第二个参数是强度,第三个参数是方向。


2.3:定义粒子颜色、透明度、是否混合以及深度

part_type_colour1( ind, colour1 )//定义粒子颜色
part_type_colour2( ind, colour1, colour2 )//定义粒子颜色
part_type_colour3( ind, colour1, colour2, colour3 )//定义粒子颜色

我们一般选择这三个函数来定义颜色,

第一个函数是只有一个颜色,

第二个函数是从颜色1到颜色2均匀变化,

第三个函数是从颜色1变化到颜色2再变化到颜色3,

根据不同的需求选择不同的函数。


part_type_alpha1(ind, alpha1)//定义粒子透明度
part_type_alpha2(ind, alpha1, alpha2)//定义粒子透明度
part_type_alpha3(ind, alpha1, alpha2, alpha3)//定义粒子透明度

眼不眼熟?

同上。

在实际应用中,我们想让粒子渐渐的消失,就可以用part_type_alpha2(b,1,0),

想让粒子渐渐的出现再渐渐的消失就可以用part_type_alpha3(b,0,1,0)。


part_type_blend(ind, additive)//定义粒子是否混合

第二个参数,是否启用混合模式,

这里的混合模式是默认的增加模式(Add),它增加了每一个粒子重叠的亮度值,使光的颜色会逐渐变亮(直到出现白色),当它们重叠时,深色变得越来越透明,黑色几乎看不见,在制作火焰效果时,会让火焰更加的明亮。


part_type_colour_mix
part_type_colour_rgb
part_type_colour_hsv

在颜色设置上其实还有这三个函数,它们有两个共同点:不可控和随机。

第一个函数是把两种颜色随机混合,

第二个函数是把红黄蓝随机的混合,虽然可以控制最大最小值,但依然很乱,不条理,

第三个函数是把色调、饱和度、明度随机的混合,其实这个函数还是有点用的,对于对色彩要求很高的朋友可以用它来调色调、饱和度、明度,

这三个函数如果没有明确的目的性就不要用了,容易瞎- -。


part_system_depth( ind, depth )//定义粒子深度

比如我们想搞一屏幕雪花粒子,效果好点的话就会有远景雪花和近景雪花,那么远景的雪花深度肯定是要高的,近景则会低。

注意:此函数的第一个参数是粒子系统a,意味着想达成不同深度的粒子就要有不同的粒子系统。


2.4:定义粒子寿命

part_type_life(ind, life_min, life_max)//定义粒子寿命

第二和第三个参数分别定义粒子初始生命的最小值和最大值,如果它们是一样的,那么粒子初始寿命永远就是那个值,如果不一样,就是在两个值中间随机的生成。

part_type_step(ind, step_number, step_type)

这个函数很有意思(但是很耗资源),它可以让你粒子1在创建之后每一帧都生成粒子2,如果你愿意还能让粒子2再生成粒子3·····粒子n-1生成粒子n。

第二个参数每一步生成多少个新粒子,比如写10,那么每一帧都会生成10个新粒子,也可以写负数,比如-10,那么每一帧都会有1/10的几率生成1个。

第三个参数是新粒子的类型变量名称。

注意,不要用相同的粒子类型,你的游戏会boom的。

part_type_death(ind, death_number, death_type)

这个函数类似于part_type_step,只不过它是当粒子死亡时才会触发。

再次注意,不要用相同的粒子类型,你的游戏会boom的。


二、释放粒子。

释放粒子有两种方式,1是根据条件状态直接释放,2是创建粒子发射器,发射器就会不停的“喷”出粒子。

1.直接释放:

part_particles_create(ind, x, y, parttype, number)

这里我们就要用到一开始定义的变量a了。

第一个参数写定义粒子系统时的变量,我们这里写a,

第二和第三个参数是生成粒子的位置,我们既可以写固定的位置,比如100,100也可以写一个大概的范围比如irandom(50,100),irandom(250,300),

第四个参数写定义粒子类型时的变量,我们这里写b,

第五个参数是生成数量,想要多少写多少!

其实相比粒子发射器,这个函数是更加简单实用的,比如子弹碰撞到敌人时生成火花粒子,直接在碰撞事件里写这个函数就完事了,比如我们想每5帧生成一个残影,在计时器里写这个函数就完事了。

part_particles_create_colour(ind, x, y, parttype, colour, number)

还有这个函数,相比上一个多了个color,我不知道它有什么卵用,我颜色都定义好了你还要我写颜色- -。

2、使用粒子发射器释放粒子:

粒子发射器适用于大规模的粒子生成,它的本质就是个粒子控制台,它和直接释放最大的不同就是粒子发射器可以设定生成范围的分布模式,如图:

粒子发射器的发射范围,矩形/圆/菱形/线性,其实手写也可以做的到

粒子发射器的分布模式,均匀/高斯分布(中间更多)/反高斯模式(边缘更多),这是发射器的优势

在定义完粒子属性后,我们来定义粒子发射器:

c=part_emitter_create(a)//定义粒子发射器c

a是粒子系统,b是粒子类型,c是粒子发射器,不要搞混。

当然变量名称是随意写的,为了好记好区分,你可以写成ps(particle system) , pt(particle type) , pe(particle emitter) ,这里只是方便理解写abc。


part_emitter_region(ps, ind, xmin, xmax, ymin, ymax, shape, distribution)//定义粒子发射器范围

此函数定义发射器的生成范围

第一个参数写粒子系统a,

第二个参数写粒子发射器c,

第三、第四个参数是x的最小最大值,

第五、第六个参数是y的最小最大值,3456参数定义了范围,

第七个参数是分布形状,就是上图 矩形/圆/菱形/线性 中幸福四选一,从下面的常量中选择写入:

第八个参数是分布模式,就是从上图均匀/高斯分布(中间更多)/反高斯模式(边缘更多)中幸福三选一,从下面的常量中选择写入:


part_emitter_stream(ps, ind, parttype, number)//粒子发射器启动!

粒子发射器启动!

第一个参数写粒子系统a,

第二个参数写粒子发射器c,

第三个参数写粒子类型b,

第四个参数每帧生成多少个粒子。


part_emitter_destroy( ps, ind );//销毁一个特定的粒子发射器
part_emitter_destroy_all( ps );//销毁所有的粒子发射器

吃完喝完得打扫啊,用完内存得释放啊,不能占着坑不拉屎啊- -。


三、其他

没错!还有三!还有一些特定的、不常用的粒子功能函数,这里挂个函数名,有需要的朋友请去F1查询。

part_system_exists
part_system_create_layer
part_system_get_layer
part_system_clear
part_system_position
part_system_destroy
part_particles_clear
part_particles_count
part_system_automatic_update
part_system_automatic_draw
part_system_update
part_system_drawit
part_system_draw_order
part_emitter_exists
part_emitter_clear
part_emitter_burst

以上就是GMS2粒子系统的详解,下面我们来实际操作,玩一把火:

火可以分成两部分:火光和火花,

火光晃动,速度慢,慢慢变小,

火花晃动,速度稍快,也是慢慢变小,

颜色就设为从黄变橙再变红,透明度差不多看着调试,

好了,开工!

粒子发射器和直接释放最大的不同就是粒子发射器可以设定分布模式。

代码:

create事件:

ps_1=part_system_create();//创建粒子系统ps_1
pt_1=part_type_create();//创建粒子类型pt_1
part_type_shape(pt_1, pt_shape_sphere);//定义粒子形状sphere-火光
part_type_size(pt_1, .8, 1.2, -.005, .01);
part_type_speed(pt_1,1,2,-.005,0.1);
part_type_direction(pt_1,90,90,0,0);
part_type_colour3(pt_1, c_yellow, c_orange, c_red);
part_type_alpha3(pt_1, .5, 1, .5);
part_type_blend(pt_1,1);//混合模式的开启可以让火光更加明亮
part_type_life(pt_1,100,150);

ps_2=part_system_create();//创建粒子系统ps_2
pt_2=part_type_create();//创建粒子类型pt_2
part_type_shape(pt_2, pt_shape_square);//定义粒子形状sphere-火花
part_type_size(pt_2, .1, .2, -.0005, .01);
part_type_speed(pt_2,1,2,.001,0.1);
part_type_direction(pt_2,75,105,0,10);
part_type_colour3(pt_2, c_yellow, c_orange, c_red);
part_type_alpha2(pt_2, 1, .2);
part_type_life(pt_2,100,150);

pe_1=part_emitter_create(ps_1)//创建粒子发射器pe_1
pe_2=part_emitter_create(ps_2)//创建粒子发射器pe_2

step事件:

//定义粒子发射器pe_1的分布形状和分布方式
part_emitter_region(ps_1,pe_1,room_width/4*3-50,room_width/4*3+50,
room_height/2-5,room_height/2+5,ps_shape_ellipse,ps_distr_gaussian);
//粒子发射器pe_1启动!
part_emitter_stream(ps_1,pe_1,pt_1,3);
//定义粒子发射器pe_2的分布形状和分布方式
part_emitter_region(ps_2,pe_2,room_width/4*3-50,room_width/4*3+50,
room_height/2-5,room_height/2+5,ps_shape_ellipse,ps_distr_invgaussian);
//粒子发射器pe_2启动!
part_emitter_stream(ps_2,pe_2,pt_2,3);

//直接创建粒子pt_1和pt_2
part_particles_create(ps_1,irandom_range(room_width/4-50,room_width/4+50),
irandom_range(room_height/2-5,room_height/2+5),pt_1,3)
part_particles_create(ps_2,irandom_range(room_width/4-50,room_width/4+50),
irandom_range(room_height/2-5,room_height/2+5),pt_2,3)