• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker Particle system depth error

MeltingCat

Member
Hi!
I'm trying to fix an error occurring in a particle system I created. The system is bound to an object and is destroyed on room end. It is a particle system to create a rain effect with a parallax motion.

The issue is this: it works fine when I first enter the room. It keeps working fine if I go into another room containing the rain object. If I enter a room without rain and go back to the one that had rain on it, the depth is underneath the player (not where I want), and the positioning is also slightly off. The rooms are persistent, but the particle system and emitters are being destroyed on every room end and recreated on room start. The object and system is not referenced in any other object.

Any ideas are appreciated!

Here is the code:

GML:
//Create event

RainSystem = noone
RainEmitter = noone

RainStrength = 5

RainAngle = -20

MoveRate = -0.23

// Raindrop
Rain = part_type_create();
part_type_sprite(Rain, s_Rain, false, false, false);
part_type_size(Rain, 1.7, 2.0, -0.05, 0)//0.7, 1.1, 0, 0);
part_type_scale(Rain, 1, 1.2);
part_type_orientation(Rain, RainAngle+90, RainAngle+90, 0, 0, 0);
part_type_color3(Rain, c_white, c_white, c_white);
part_type_alpha2(Rain, 0.08, 0.3)//0.2, 0.2);
part_type_blend(Rain, true);
part_type_life(Rain, 50, 60);
part_type_speed(Rain, 9, 11, 0, 0)//10, 13, 0, 0);
part_type_direction(Rain, 270+RainAngle , 270+RainAngle, 0, 0);

alarm[0] = 2 //initializing stuff
GML:
//alarm[0]

/// @description init

Width = o_Camera.Width
Height = o_Camera.Height

RainSystem = part_system_create()

if layer_exists("Rain") {
depth = layer_get_depth("Rain")
    part_system_layer(RainSystem, "Rain")
}
//I have tried all sorts of things here, including using part_system_create_layer and part_system_depth

if ! part_emitter_exists(RainSystem, RainEmitter) {
    RainEmitter = part_emitter_create(RainSystem)
}

part_emitter_stream(RainSystem, RainEmitter, Rain, RainStrength)
GML:
//Room start
alarm[0] = 2
GML:
//Room end
if part_emitter_exists(RainSystem, RainEmitter) {
    part_emitter_destroy(RainSystem, RainEmitter)
}
if part_system_exists(RainSystem) {
    part_system_clear(RainSystem)
    part_system_destroy(RainSystem)
}
GML:
//step event

var _CamX = o_Camera.x
var _CamY = o_Camera.y


x = _CamX - (( _CamX ) * MoveRate)
y = _CamY - (( _CamY ) * MoveRate)



if part_system_exists(RainSystem) {

    part_emitter_region(RainSystem, RainEmitter, x - (Width/2), x + (Width/2) + 150, y - (Height/2) - 100, y - 40, ps_shape_rectangle, ps_distr_linear )
    part_system_position(RainSystem, _CamX* MoveRate, _CamY* MoveRate)
    
}

//probably unrelated, but it's there. creates additional splash particles on the ground.

GML:
if RainStrength < 3 {

    var _Rain = RainStrength/3

    if Chance(_Rain) { //3

        var _Partx1 = irandom_range(_CamX - (Width/2), _CamX + (Width/2) )

        var _Party1 = irandom_range(_CamY - (Height/2), _CamY + (Height/2) )

        part_particles_create(global.PlayerPSystem, _Partx1, _Party1, global.Splash, choose(2, 3, 3, 4));

        if part_system_exists(global.WaterSystem) {

            part_particles_create(global.WaterSystem, _Partx1, _Party1, global.WaterSplash, 1)

        }

    }

} else {


    repeat round(RainStrength/3) { //3

        var _Partx1 = irandom_range(_CamX - (Width/2), _CamX + (Width/2) )

        var _Party1 = irandom_range(_CamY - (Height/2), _CamY + (Height/2) )

        part_particles_create(global.PlayerPSystem, _Partx1, _Party1, global.Splash, choose(2, 3, 3, 4));

        if part_system_exists(global.WaterSystem) {

            part_particles_create(global.WaterSystem, _Partx1, _Party1, global.WaterSplash, 1)

        }

    }

}



Thank you for reading!
 

Nidoking

Member
My first question would be why you're destroying and recreating the particle system each time. Have you considered destroying just the emitters, but letting the system persist and just recreating the emitters in it each time you need them?

My second question would be whether the depth of the "Rain" layer might be different between different rooms where you apply the effect. You're conditionally calling part_system_layer if the "Rain" layer exists but not setting the layer at all if it doesn't. Maybe that has something to do with the issue.
 

Cameron

Member
Easiest way to handle this issue is to set the part system depth at creation of the part system.
GML:
part_system_depth(_part_system_name, new_depth );
 

MeltingCat

Member
Easiest way to handle this issue is to set the part system depth at creation of the part system.
GML:
part_system_depth(_part_system_name, new_depth );
I have tried this. The same issue persists, it works the first time I enter the room, it is off next time I come back.
 

MeltingCat

Member
My first question would be why you're destroying and recreating the particle system each time. Have you considered destroying just the emitters, but letting the system persist and just recreating the emitters in it each time you need them?

My second question would be whether the depth of the "Rain" layer might be different between different rooms where you apply the effect. You're conditionally calling part_system_layer if the "Rain" layer exists but not setting the layer at all if it doesn't. Maybe that has something to do with the issue.
I'm recreating it because 99% of the game is without rain and does not need the system. So I thought it would be more efficient if it wouldn't be there when not needed.

The "Rain" layer is slightly different in the rooms, but the problem I have is that the particles are definitely not on this layer. And the layer exists, I have checked for it with debugging and all. I made the layer specifically because I started having this issue, and the RainSystem used to be on another layer which contained another particle system and I thought maybe that is the issue. But now that it is on a separate layer I ran out of ideas.
 

MeltingCat

Member
Now.... I fixed it!
The bad news is that I can't really tell how.
I realized that if I change the depth of the system on a button press, it takes a whole different particle system with it... Somehow I felt that it seemed to have the same "ID" or something like that (I know, that sounds like someone who totally doesn't know what's going on, which is true), so what I did was make sure that I staggered the alarms in which the systems are created so it doesn't happen at the same frame.
After that I still had to stagger another alarm to fix the depth AGAIN but after doing all these things now it's working.
A little annoying is why all that was necessary but seeing that it's fixed now I'm happy ;)
Thanks for all your help!
 
Top