Push out of the way of falling blocks

D

Dibidoolandas

Guest
I'm struggling a bit to come up with a good solution for how to push my player out of the way of a falling block so that they don't get stuck in a wall when it lands on them.

I originally just had code to kill the player in place if this happened, but if I could enable some kind of push to the side I think it would be a better experience. I've attached an illustration of the problem.



Currently I've added some code to say that if the block falls on the player's head, then it checks if the player's x is to the right or left of the block's x, and whichever side he's closest to, push his x value out of the block. This works, however as you'll see in the illustration, if my player was butted up against a wall and this code ran, it would push him straight into the wall and he'd be immobilized. So in theory I'd like it to know which side of the block will have clear space when it lands, and push the player in that direction. If there's no clear space (such as in a pit the same size as the block), then I would just kill the player.

Has anyone dealt with this before? I've looked around a little and not seen much... If there are any resources for dealing with this I'd appreciate it.
 
Z

Zefyrinus

Guest
Can't you just use um, what's it called? instance_position? To check whether there is a wall object a certain amount of pixels to the right or left of the player.
 
Simple psuedoishcode:

Step A: When the falling block detects a downward collision with the player, scan to the right so that the left edge of the player is one pixel to the right of the left edge of the box. If the player can fit into this space with no collisions, record the direction as "right" and go to Step C, else, continue to Step B.

Step B: Since the Right direction is blocked, you now check left by scanning the space where the right edge of the player is one pixel left of the left edge of the box. If the player can fit into this space with no collisions, record the directions as "left" and continue to Step C, else, your player is in what we'll call an "unwinnable" situation and cannot be moved out of the path of the box. We'll talk about the Unwinnable Situation below.

Step C: move the player to the appropriate side of the box, thus freeing the space for the box to continue falling.

The Unwinnable Situation: No matter how much you try to design your levels to avoid the Unwinnable Situation, these is always the possibility of an industrious player managing to get themselves caught in said situation. Therefore, I suggest adding code to deal with this scenario. A good example is what you have now, killing the player. You can, of course, have something else happen. If you don't wish to kill the player in this situation, you can instead push the player up through the block to place them on top. It's all up to you really.

Do note, the above pseudoishcode assumes all blocks are the same width or smaller then the player. Larger falling blocks could cause the code to skip over other solids and teleport the player where they aren't supposed to be, but this will give you a start.
 
D

Dibidoolandas

Guest
Just to clarify, when you say scan to the right, would you mean something like this?

if !(place_meeting(x+105,y,par_collide) //If there is no collision object within 105 pixels to the right of the falling block
{
push_right = true; //Push our player to the right
}
else //Carry out steps B and C

And et cetera from there as you described it. 70 is my player width and 35 is half the width of the block, so this would essentially be checking if there is a collide-able wall within the player's width to the right of the block. I think that would work! Let me know if you see any holes though, I'll have to check when I get home.
 
It would be roughly like that, yes, but you shouldn't hard code the values, as that would assume the player and the block are dead center to each other. You may want to look into the manual and research the bbox_* variables. It's hard to direct you exactly what to calculate for finding these values, as they depend a lot on where the sprite origins are.
 
Top