One way platforms

Mar 4, 2010 at 2:52 AM
Edited Mar 4, 2010 at 5:08 AM

Hello everybody I am creating a platformer!

Like most platforming games I am making a platform where my player can jump through but then he can land on it! AMAZING.
It's as if the platform enables and disables collision based on the player position!

Now here's the dilemma:

Currently I run a simple check for my player if the Y velocity is positive or negative. Based on this data the collisions for platform tiles are enabled and disabled.

foreach (Platform tile in platformPool)
            {
                if (playerBody.LinearVelocity.Y <= 0) tile.geom.CollisionEnabled = false;
                else tile.geom.CollisionEnabled = true;
            }

However in my game, the player is able to control his jump from a short hop to a high jump depending on how long our player holds the button down. This is created by a series of declining impulses within 1/2 a second.
This means that the player (who is just a giant rectangle) can almost go through a platform but then start falling. This causes the collisions to become enabled while the player is within a platform tile.

The possible solutions that I have come up with (but not yet enabled) are these:

1. Check the Y position of the character's feet and the Y position of the tile's surface and turn the collisions on and off when the player is "above" the tiles. HOWEVER! This would mean that all of my platforms must have completely flat surfaces. That is extremely lame. My game is not a bunch of squares. That is not how a complex physics engine should be enabled.

2. Use the current check + check if he is colliding against a geometry with collisionEnabled set to false. Then exactly when our player is above the tile, the collisionEnabled is set to true. This seems like dream code in my opinion. I have no idea how to enable this.

3. Use SAT narrowphasecollision (to prevent getting stuck within other geometries) and sacrifice all concave geometries within my game. I would also have to use small geoms on our player's feet and the platforms in my game should be thin so collisions of geometry overlapping are minimal.

Thoughts :(?

 

Mar 4, 2010 at 5:43 PM

I've been looking at solving this issue myself but I haven't had time to come up with a viable solution. I think an interesting solution is probably similar to your #2. Once you reverse velocities and begin to move downward, run checks to see which geometry is colliding. Set the player to ignore collision with all gemoetries that meet that criteria and store them in a list. Now in the OnSeparated event, every time you separate from a collision check if the geometry your separating from is in the list of ignored geometries. If so, re-enable collision. Wala!

Mar 7, 2010 at 11:02 PM

        public bool OnCollision(Geom geom1, Geom geom2, ContactList list)
        {

            if (geom2.Body.LinearVelocity.Y >= 1)
            {
                geom2.Body.ApplyImpulse(new Vector2(0, -100));
                return true;
            }
            else
            {
                return false;
            }

}

Mar 8, 2010 at 11:35 AM

I'm currently using:

private bool PlatformCollision(Geom geom1, Geom geom2, ContactList contacts)
        {
            if (playerBody.LinearVelocity.Y > 0) return true;
            return false;
        }

 

And it's basically exactly the same- and it doesn't work =(.

The problem is that when I start falling when I am within a platform- I get wonky physics.

Mar 8, 2010 at 11:47 AM
Edited Mar 8, 2010 at 11:47 AM

You can;'t have 0. You need to have atleast 0.1f otherwise even when you are going up it will trigger.

Mar 8, 2010 at 12:22 PM

I don't understand why you argue when it should be clearly obvious that I would test out both bits of code and yield nearly identical results.

 

Mar 8, 2010 at 10:24 PM
Edited Mar 8, 2010 at 10:29 PM

Are you sure that you added PlayerGeom.OnCollision += PlatformClass.OnCollision;

 

If you still cannot figure it out, I would be happy to look at your code for you and help figure it out. My email: drakeshe(at)hotmail.com

Apr 16, 2010 at 10:56 PM

An easy fix I've seen other people do is to have the platform geometry only be a thin strip of platform along the top edge. It works well if you want the rest of the object to be non-interactive. This would reproduce mario-style results like the colored boxes in Mario 3. Also, boxes like that only change if you are falling  AND you are higher than the platform (if you are falling and your feet are below the platform  you should fall through), the the if would look like: if (playerBody.LinearVelocity.Y > 0 && playerBody.Position.Y - playerHeight / 2 > platformBody.Y + platformHeight  / 2) ...

Apr 16, 2010 at 10:59 PM

Ooh, this sounds legit.
Will try it when I get the chance.

Much thanks.