Tutorial - Falling sand/Boulder dash rocks behaviour using image api

lwyzlwyz

  • Posts: 3
I saw quite a few posts asking how to do a falling sand/boulder dash behaviour when I was trying to figure it out for a game.
This is the way that me and my brother figured out how to do it in a step by step tutorial for anyone new to image API. Example behaviour at bottom.

Create a Scene Behaviour which I name "sand image behaviour".
Add a When Created event.
Add an attribute of type Image named "screen" and one of type Image Instance named "screen inst".

This gives you the canvas on which the action will occur. Use attach to layer if you don't want your sand to follow the camera in scenes bigger than the screen, or attach to screen if your scene is the size of the screen.
Create an attribute of type Number named "particle size".

This is the size of the sand particles. Really small sizes(smaller than 10) on a scene  of 640x480 or greater may cause lag. For a boulder dash game you'll want this size to be bigger.
Either way you should make sure that scene width and height are divisible by particle size to prevent truncated "tiles"
Create another attribute of type Image named "particle" and one of type Color named "particle color".

This gives you the sand particles you'll paint with which will get their movement later. We'll be drawing the sand particles directly onto the "screen" image, which is reflected in the "screen inst" image instance. Everything has to be drawn onto the same image for the collision checking.
Create yet another two Image attributes and one Color attribute named respectively "terrain",  "ground" and "terrain color".


These give you immovable particles to paint with and a layer at the bottom that prevents the sand from falling off screen. The "Add" drawing method causes problems with the particle movement, so I use "Normal" instead, I'm not sure what effect the other draw methods might have. If your particles are getting squashed this might be the cause.
Create another two Number attributes named "row number" and "column number".

This will make the loops start from the bottom. If the loops start from the top it will basically do all the movement at once, making the particles jump from their positions to the bottom of the screen instantly. The other number can stay at it's default(0) for now.
Create a Text attribute called "type of click".

This text attribute will serve to cycle between three states(particle, terrain, destroy) for painting your scene. We'll do that in the next two events.
Create a When Control is Pressed event(input - keyboard). I chose action2(default x key). Inside of it put these blocks.



This makes the cycling I mentioned earlier happen when you press the x key. Now to make that cycling actually do something.
Create a When Mouse is Pressed event(input - click).



With this when you click it does different things depending on the value of the Text attribute.
I'll explain some things.
The get pixel block returns a color in number format, 0 for transparent(empty). We're not using those numbers, that's the reason we created those Color attributes earlier.
The floor of (mouse/particle size) x particle size means that you're creating(or destroying) a particle at this "grid space" instead of the exact location of the mouse.
Now let's make it so that it only starts moving when we want. Create a Boolean attribute called "go".
Add another When Control is Pressed event, choose action 1(default z key).

Now it only starts the movement when you press z and you can pause it whenever you want.
Add a Do Every N Seconds event, 0.05 is a good number to make it go not too fast. You can later adjust this time to make it slower or faster, but remember that if it's too fast you'll get lag. Here we'll put in all that we need to actually make the particles act the way we want. First let's just make them fall down and stop when they touch the ground.

Some explanations: The If go means it only starts when "go" is true and we already have an event to change that at will. The two loops(repeat times) check every column at every row for particles.
So if at a specific column and row we have a particle and under that particle is empty space(checking with get pixel) we tell it to do something. Specifically we tell it to erase that particle and draw a new one on the row just under. Now the particles will fall, but to make it a good falling sands behaviour we need the particles to roll like they had physics.

Add this inside the first if get pixel below the second if get pixel. It should look like this.

Now if there is something other than empty space under a particle, it checks the two spaces to the left and right of the space under the particle and then if they're free it moves the particle(again erasing the drawing at it's position and drawing a new one in the intended position) diagonally down and either to the left or right.
If both spaces are free it uses a random number to determine whether to go left or right.
If only one side is free it moves to that side. The conditionals for "column number" inside these movements mean that the particles don't roll off screen when they're at the edges of the scene. And here is the finished behaviour.

Just save this image and on a stencyl project go to File - Import resource and you'll have a behaviour ready to attach to any empty scene. You'll need to modify it extensively to actually make a game out of it, but it should at least point you in the right direction.
Any suggestions on how to improve this behaviour or this tutorial are greatly appreciated.
If you need clarification on anything, please post your questions.

Edit: Updated the behaviour to show keys on the screen. Also forgot to mention you should have a When Drawing event.

I've also added it to the forge with the name "sand image behaviour".
And as mdotedot points out the When Mouse is event can be changed to draggedinstead of pressed.

« Last Edit: May 28, 2015, 10:26:14 am by lwyzlwyz »

mdotedot

  • Posts: 1654
Hello lwyzlwyz,

Thank you for your work. I played with it a little and I suggest you put this on StencylForge as well.

I know you put this information in the tutorial, but it would also help if you draw the action keys on the screen to make it simpeler to use the demonstration.

The demonstration became very cool when I changed the tile size from 10 to 1 or 4  in the 'when created' and changed the mouse press into a mouse drag.


Again thank you for your work and I might use it someday for a game!

Best regards from
M.E.

Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

lwyzlwyz

  • Posts: 3
Thank you for your suggestions, mdotedot. I'll  update this later today adding the keys to the draw event(and the draw event to the tutorial)and I´ll add the behaviour to the forge. You managed to use particle size 1 and 4 without lag? On my computer the fps drops to near 0 at those sizes. A big part of the credit should also go to my brother aizenmyoo, for helping me remove an unnecessary 2d array of lists that I was using at first.

dotacreepy

  • Posts: 15
Hi! This is an awesome resource, thanks so much. I have an idea for a game where the sand would fall down through point goals - is there a way to do hit detection, as in if I mark a spot on the stage, if a sand touches it they get points for it once? Then i'd like the sand to fall off screen and die so as not to consume computer resource. Forgive me for asking but is that possible? I appreciate your work regardless of if you have the time to help me out (a total noob)

lwyzlwyz

  • Posts: 3
Hi! This is an awesome resource, thanks so much. I have an idea for a game where the sand would fall down through point goals - is there a way to do hit detection, as in if I mark a spot on the stage, if a sand touches it they get points for it once? Then i'd like the sand to fall off screen and die so as not to consume computer resource. Forgive me for asking but is that possible? I appreciate your work regardless of if you have the time to help me out (a total noob)

First of all thanks for the kind words and sorry for the late reply.
Since I posted this I experimented a bit with Tile API and I'm currently using tiles instead of image instances in the game I'm currently developing. Just replace everything to do with Image API with the equivalent blocks from Tile API, create a small tileset with 10x10 tiles and make sure your scenes are setup with 10x10 tile size.(You can still use Image API if you want, tiles just simplify it a bit.)
Hit detection shouldn't be too hard to do. There is already a bit of hit detection in the posted behaviour to make the particles act like they're solid and hit and roll off one another.
You'd only need to further specify where the targets are and what happens when the particles are at or touching that spot. Also for falling off screen and vanishing you can add something to delete particles when their Y position is greater than scene height.
 For example in the part where you check for empty space or particles beneath your particle add extra ifs to check if the position is that of the target(adding points) and also if they're at the bottom of the screen just delete them and don't remake them. Hope this helps and if you need further elaboration, pm me on kongregate: user name LWYZLWYZ, it's easier to get ahold of me there.
I'm the guy who posted a shout about planet running master on stencyljam 2015 on your kong profile.