How do I make pushable blocks that move on a grid in a top down game?

Hello, I’m making a top down game and I have blocks that you can move. I made a system where the blocks move 32 pixels at a time in whatever direction you push them in. This way the blocks always end up lining up in a 32x32 pixel grid like when you push blocks in top down Zelda games. However I only want a block to move if it isn’t being beside another block or wall. How do I let the block detect if there is something on a particular side of it. For example, if there is another block directly to the right of the first block, then you shouldn’t be able to push the block right.

I made some objects that I called “detectors” that follow the blocks around on each side of them. These will be invisible. See the attached picture. I also made some object variables for each block that can be set to 0 or 1. The variables are canblockmoveup, canblockmovedown, canblockmoveright, and canblockmoveleft. I was trying to figure out a way to make the detectors around each block tell the block whether it can move in each direction or not but I couldn’t make it work. For example if the detector on the right side of the block is touching an obstacle, the the variable canblockmoveright should become 1 (meaning it can’t move right) and when you try to push it in that direction nothing happens. I just don’t know how to make the detectors of each block change the variables of each block. Hopefully my question isn’t too confusing. Screen Shot 2021-12-31 at 6.20.06 AM

You can use the ID variable. Give each detector and block an identical ID. For example, the block’s ID is 1 so the detector’s ID will also be 1. Then while pushing the block (when the detector detects), you will just push the block that matches the ID of the detector.

Another way would be to link those two objects. At the beginning of the scene, pick the nearest block and detector and link them. Then push the block that is linked with the detector.

Thanks. I tried linking the objects but I couldn’t make it work. Would you mind posting an example of what the events would look like for either of the methods you mentioned?

I’d use user defined points on the block, and check that the particular point for the push direction is within an obstructing object (in the snip below, the blue points are the added ones):

Ok, so how do make the events in such a way that it knows which block you are talking about. For example maybe your event says you can push a block up if the defined point on the top of the block is not touching a block or an obstacle. Then if one of the other blocks that you are not pushing is touching an obstacle above it, you wouldn’t be able to push any of the blocks up, right?

@MrMen’s idea is something like this:


[edit]
updated

I was thinking more that you use the points to determine if there is an object blocking the other side to the push. There’s no reason to check that the point is within the player :

and then subevents for moving the player and block (using tweens maybe?).

You can’t invert the condition, because the point will be outside of most of the other blocks, and so will register as true every time, even if the point is within a block.

Hello, I tried this technique and it works for stopping blocks when they hit walls. However, it doesn’t seem to work for blocks bumping into each other. If you have more than one block in the room, when you push a block into another block the block you are pushing doesn’t get stopped. How do I make the blocks stop each other as well?

Either :

  1. add an extra condition that checks if the point is within a block, or

  2. put all crate stoppers into an object group and check if the point is with the object group

All the 2nd option will do is find all objects the point lies in, and check whether any of those objects are in the crate stoppers object group. This is probably the better way, as you can then add or remove further crate stoppers is you need from the group without adding extra event conditions.

Adding the extra condition that checks if the point is on a block is not working. Here are events I have for pushing blocks:


What happens is if you push a block into the wall it stops but if you push a block into a block it just overlaps the other block instead of stopping.

Yes. That is correct. You need to understand how GDevelop works. In this screen snip :

image

the repeat event goes though one block at a time. GDevelop’s list of eligible block2 is just one object. In the last event of the screen snip, it checks if the point is within a block2. But GDevelop only has one block2 it’s working with at this point - it doesn’t take in all block2 objects, just the filtered list.

And the point will never be within the block it belongs to. So the actions to set the object’s variable never get processed.

The only way I see around this (for block on block collision) is to make a hitbox object with the 4 check points. Make this hitbox object the same size & shape as block2, and place it on the block2 the player is moving. Then check whether the points are within a block2 - remember this has to be done outside of the repeat block, otherwise you’ll be checking with only one block2 and it will fail. It will require a bit of code refactoring, and the use of a variable to indicate whether or not a block2 is in the way.

1 Like