General question around walls and platforms

lodoss118

New member
Hi, I am making my own 2d engine to do similar things like openbor, but I am stuck on walls and platforms. Actually the word stuck is quite appropriate here, I have basic collision detection with rectangles and define these around obstacles, for wall collision I have used what is in the openbor to calculate the z plane left and right edges but not sure how to slide down.

So my my movement collision is like follows:

Code:
float dx = (velocity.x * delta);
float dz = (velocity.z * delta);

//This is general obstacle detection so basic rectangle shapes, no slopes on edges
boolean hasCollidedObstacleX = CM.collisionAt(this, dx, 0);

//Check static wall on vertical axis?
boolean hasCollidedWallX = CM.hitWall(100, 300, 100, 500, 1000, 600, 400, 5000, pos3d.x + dx, pos3d.z);

if (!hasCollidedObstacleX && !hasCollidedWallX) {
      pos3d.x += dx;
}

//This is general obstacle detection so basic rectangle shapes, no slopes on edges
boolean hasCollidedObstacleZ = CM.collisionAt(this, 0, dz);

//Check static wall on horizontal axis?
boolean hasCollidedWallZ = CM.hitWall(100, 300, 100, 500, 1000, 600, 400, 5000, pos3d.x, pos3d.z + dz);

if (!hasCollidedObstacleZ && !hasCollidedWallZ) {
      pos3d.z += dz;
}

Right now the using the below example, how would I slide down the left and right edges if I was moving towards that edge i.e. if i press up against the edge i will get stuck?
                                  ____________________
                                /                              /
            left side    /                                / .  right side
                            /-------------------------/

Maybe someone can point me to the openbor code that deals with this? I didn't see anything  any sliding against the left and right slopes?
 
The wall, hole and platform system is WAY too sophisticated and involved for me to describe how all of it works here. But I will give you the basic wall detection. When we want to know if an entity is within a wall, we get the entity's X and  Z position, then run an enumeration loop on all walls in the current level.

The loop sends each wall's index and X/Z coordinates we want to test to the function below. The function first runs a quick check to see if the Z coordinate falls within the wall's Z depth at all. If not, then it gets out. Otherwise as I wrote in the function's comments, it calculates a Cartesian coefficient for the left and right side. This gives us a pixel perfect mapping of where the wall's edge is along any given Z point no matter what angle the wall has. All we have to do from there is check to see if the X position falls with the left and right edge points, and we're done.

You'll also note this function doesn't test Y position vs wall height. That logic is elsewhere. Any given Y position is either above the wall's height or it isn't, so it's much more optimal to handle that separately.

Code:
/*
Calculates the coef relative to the bottom left point. This is done by figuring out how far the entity is from
the bottom of the platform and multiplying the result by the difference of the bottom left point and the top
left point divided by depth of the platform. The same is done for the right side, and checks to see if they are
within the bottom/top and the left/right area.
*/
int testwall(int wall, float x, float z)
{
    float coef1, coef2;

    if(z <= level->walls[wall].z && z >= level->walls[wall].z - level->walls[wall].depth)
    {
        coef1 = (level->walls[wall].z - z) * ((level->walls[wall].upperleft - level->walls[wall].lowerleft) / level->walls[wall].depth);
        coef2 = (level->walls[wall].z - z) * ((level->walls[wall].upperright - level->walls[wall].lowerright) / level->walls[wall].depth);
        if(x >= level->walls[wall].x + level->walls[wall].lowerleft + coef1 && x <= level->walls[wall].x + level->walls[wall].lowerright + coef2)
        {
            return 1;
        }
    }

    return 0;
}

HTH,
DC
 
Thanks Damon,

I have that similar check in CM.hitWall in the code I posted, now if you look at my diagram if I was going up the left edge but pressed down and right it will get stuck, what would openbor do in this case, will it go down/slide the edge path?
 
Your check must have a minor inaccuracy in it somewhere allowing the entity to get inside the wall but not out of it. So far as behavior is concerned that's really a separate concept compared to geometric verification. In OpenBOR, you don't "slide" diagonally along angled walls unless the entity is deliberately trying to move diagonally in the first place. Something is blocked from moving along a given plane or it isn't, just that simple. It's a design choice since that's how Streets of Rage worked, and authors can always override it with script. The wall checks would work the same either way.

DC

PS: I might add, do you really want objects to slide up and down by default? That might sound good at first, but you're opening yourself to a logistical nightmare. As one example: What happens when Ryu throws a Hadouken? Do you want it to slide down the wall too? Probably not. So now you need logic that differentiates projectiles from normal entities to prevent that from happening. As you add more and more of these little corrects, your wall and or movement code will get unwieldy and slow in short order. You are much better off looking at diagonal siding as an add on behavior and not the other way around.
 
Back
Top Bottom