Suggestion for rain system?

N

Nathaniel

Guest
I implemented a basic rain system for my game, which, every step, spawns 30 rain drop objects, multiplied by the intensity of the rain (global variable). As the drips fall, they also move sideways, depending on the strength of the global wind variable. This looks pretty cool, but they drop my fps by 600. Yes, my fps goes from 700 to 100 as soon as the rain starts. So I need a new system that doesn't rely on hundreds/thousands of objects. I've considered particles, but before I get into that, does the particle system allow the sideways direction to vary based on wind? and does it allow the drips to create splashes when they hit the ground? Also, my game is a kinda top-down view, so the drips randomly hit the ground anywhere on the screen, creating the splash. My current system assigns them a death coordinate when they spawn. As soon as they reach the death coordinate, they create a splash and die. But this is expensive, can the particle system accomplish that too? Thanks in advance.
 

obscene

Member
Particles can do this, but you have a few limitations. When you create the particle, it needs to be going in the direction you want it, and it needs to have the correct life variable (the number of steps it will exist) so that it disappears at the correct time and appears to hit the ground. You can give them a death particle which is created when they die and would simulate a splash.

This would all work assuming you don't need to simulate height at which point it will get trickier.
 

kburkhart84

Firehammer Games
Another thing to consider(whether you use particles or keep what you have), is that you can actually have maybe a few images that have several drops each, and draw those instead. This will get you much less objects and if you have a few different images and overlay them in variation you won't notice the duplication.

One more thing to consider, maybe make your own version of the particle system. Instead of spawning a bunch of objects, just have one object. It would store all the rain drop information in data structures or arrays, animate them, and draw them all at once. You will still have the overhead of drawing all of that, but you will avoid all those separate objects, executing all those unneeded events. And, you can actually combine this with my first suggestion above too. I'd bet heavily that the issue isn't with drawing those objects, rather having all those separate instances.
 

NightFrost

Member
Particles would definitely be a more FPS friendly choice, but be aware that besides setting their lifetime, you cannot control where individual particles will die (and the particle system's region, of course). Otherwise it has all the tools you need to create the rain you need. Just googling for some particle rain tutorials should give you a good start.
 
N

Nathaniel

Guest
Ah, well I make them also spawn at varying points as well. Because if they all spawn at the top of the screen, there aren't many drips if you walk down. So they are spawning at complete random within the view. Is that going to be a problem?
 

NightFrost

Member
Ah, well I make them also spawn at varying points as well. Because if they all spawn at the top of the screen, there aren't many drips if you walk down. So they are spawning at complete random within the view. Is that going to be a problem?
You can define the area where particles spawn.
 

CMAllen

Member
If you want more control than your typical particle system will permit (like depth sorting), you could think about maybe using a ds_list of 1d arrays.

The 1d arrays store the information required to animate and draw each drop, so you iterate through the list, update each drop's position based on each drop's individual animation properties (what sprite, what image_index, how fast it animates, how fast it moves along the x, y, and z axis, etc), until its z value reaches zero (ie it hit the ground), at which point you remove that array entry from the list or convert it from the base drop sprite to a splash sprite (and clear its movement values). Then, since you have each drop's y and z values, you have calculable values to use to sort each drop's depth in the room.
 
H

Hatsharmaveth Bheeka

Guest
Hello everyone... I guess I am in the right place finally.
I have used a particle rain system and have used the shape of line but when I run the game to test...there are displayed these squares... eventually when I have used effect create below or above for ef_smoke...the smoke is displayed as squares... can anyone please help to fix this problem? Would very much appreciate it. Thank you.
 

obscene

Member
Don't use the built-in effects... They are kind of useless. Just Google particle systems, using part_type_create. Make your own custom sprites for it. Sorry I'm on my phone and I can't type well enough to make an example.
 
I consider GM's particle system pretty limited. For instance, if you change the wind direction while rain is falling, the particles already spawned won't be effected. Sure rain particles don't stick around long, but it is noticeable, and just one of many downsides to use the particle system. If you plan to implement slow-motion to the game, you also can't effect particles in any way, unless you manually step them less, which will make them jumpy.

However objects are bloated with tons of built-in variables and take long to create. I'm currently using objects for the rain in my game, and I'm going to change it to use my own particle system that I have yet to make, but maybe you can make it, and see if it works, lol.

So if particles are limited, and objects are slow, what do we do?

Basically just use one rain controller object that handles all the rain. Create a list/array and populate it with information on every rain particle
ex. x, y, xspeed, yspeed, duration

So like, an array would be rain[0] = x, rain[1] = y... etc
Then once it gets to rain[5], we're looking at a different rain drop.
So you can loop through the drops like: for (var i = 0; i < array_length_1d(rain); i += 5)

In the step event, loop through the drops and update their position. Efficient way to do wind would be to check if the wind has changed from last frame, and only update the particles xspeed/yspeed if it has. Also, decrease their duration by 1.
In the draw event, loop through the drops and use the data to call a draw_sprite function.

If you want to have splashes when they hit the ground, you could use the same draw loop as above, and just check if the duration is <= 0 and draw a different sprite at that location. You would also have to keep it from moving, so in the step event, stop having it increment the x and y.
If the splashes do some kind of animation, which they probably should, you gotta be an extra smarty pants.

If the particles hit the ground, it's duration is 0. But as long as you're still decreasing the duration value, it will go into the negatives. You can then use this value to tell the particle which image index to use when it draws the spash.

Creating new drops would basically mean just recycling drops that are done splashing. When it's done with the splash animation, reset it's duration/x/y.

Hopefully this makes sense. If it doesn't, I'll be happy to clarify.
 
H

Hatsharmaveth Bheeka

Guest
Don't use the built-in effects... They are kind of useless. Just Google particle systems, using part_type_create. Make your own custom sprites for it. Sorry I'm on my phone and I can't type well enough to make an example.
Thanks. I just used a sprite today and it worked out well. I was wondering...is there a way to make those particles collide with a wall or floor and do something after colliding or just destroy after the collision?
 
H

Hatsharmaveth Bheeka

Guest
I consider GM's particle system pretty limited. For instance, if you change the wind direction while rain is falling, the particles already spawned won't be effected. Sure rain particles don't stick around long, but it is noticeable, and just one of many downsides to use the particle system. If you plan to implement slow-motion to the game, you also can't effect particles in any way, unless you manually step them less, which will make them jumpy.

However objects are bloated with tons of built-in variables and take long to create. I'm currently using objects for the rain in my game, and I'm going to change it to use my own particle system that I have yet to make, but maybe you can make it, and see if it works, lol.

So if particles are limited, and objects are slow, what do we do?

Basically just use one rain controller object that handles all the rain. Create a list/array and populate it with information on every rain particle
ex. x, y, xspeed, yspeed, duration

So like, an array would be rain[0] = x, rain[1] = y... etc
Then once it gets to rain[5], we're looking at a different rain drop.
So you can loop through the drops like: for (var i = 0; i < array_length_1d(rain); i += 5)

In the step event, loop through the drops and update their position. Efficient way to do wind would be to check if the wind has changed from last frame, and only update the particles xspeed/yspeed if it has. Also, decrease their duration by 1.
In the draw event, loop through the drops and use the data to call a draw_sprite function.

If you want to have splashes when they hit the ground, you could use the same draw loop as above, and just check if the duration is <= 0 and draw a different sprite at that location. You would also have to keep it from moving, so in the step event, stop having it increment the x and y.
If the splashes do some kind of animation, which they probably should, you gotta be an extra smarty pants.

If the particles hit the ground, it's duration is 0. But as long as you're still decreasing the duration value, it will go into the negatives. You can then use this value to tell the particle which image index to use when it draws the spash.

Creating new drops would basically mean just recycling drops that are done splashing. When it's done with the splash animation, reset it's duration/x/y.

Hopefully this makes sense. If it doesn't, I'll be happy to clarify.
Hello. I had tried using objects to make the rain but after moving here and there for some time there was a great lag...i don't know how far this is true but i am currently not experiencing the lag with particle system... i will try to follow what you have suggested and see if it works.
 
H

Hatsharmaveth Bheeka

Guest
Just use an instance for each rain drop, like me. Feel the power! :'D
Could you give me an example please? I am new to this rain stuff and still learning how to make a rain that looks good and at the same time not having lags. Thank you.
 

obscene

Member
I use instances for snowflakes actually as I need them to randomize Direction on their fall as well as interact with lights. I found that if you don't use the step event, recycle them instead of creating and destroying new ones all the time, and staggering their codes so they're not all executing at the same time it's pretty efficient. 200 flakes that only run code every eight frames is really only a dozen objects at a time.

I once tried to do the same with an array system and found the objects were faster.
 
Top