Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I posted this question two weeks ago: 2D platformer corner collision and I implemented NoobsArePeople2's solution.

Problem is, when player intersects two rectangles that are inside each other, he starts jittering. I don't know how to describe it so I made a video: http://www.youtube.com/watch?v=2AYUGeuxM0c

In the first 4 or so seconds, you can see that when he collides with two rectangles that arent in each other or touching each other, everything works fine, but in the rest of the video, you can see that when player touches side, he starts to jitter (please note that because of fraps, my game was running at quarter of FPS I normaly have, so without fraps the jitter is much faster)

To give you idea how my collision rectangles look now, here is debug mode (each rectangle is randomly colored) enter image description here

I have couple of algortihms in place that merge rectangles into one (still need to do some work on that), but some simply cannot be merged. One example is the C object on the right. Right now it is made of 7 rectangles (will be 3 after I complete my algorithm) and when player slides on side of it, he starts to jitter.

I suspect problem is in my gravity, but Im not sure. I've spent 5 days on trying to fix this and Im lost.

Heres my code (slighty modified from platformer sample):

        for (int i = 0; i < playerCollisionRectangles.Count; i++)
        {
            Vector2 depth = Collision.GetIntersectionDepth(player.PlayerRectangleInWorld, playerCollisionRectangles[i]);
            if (depth != Vector2.Zero)
            {
                float absDepthX = Math.Abs(depth.X);
                float absDepthY = Math.Abs(depth.Y);

                // Resolve the collision along the shallow axis.
                if (absDepthY < absDepthX)
                {
                    // Resolve the collision along the Y axis.
                    player.PlayerPositionY += Convert.ToInt32(depth.Y);
                }
                else  
                {
                    // Resolve the collision along the X axis.
                    player.PlayerPositionX += Convert.ToInt32(depth.X);
                }
            }
        }

And here is my gravity code (very very simple):

        if (Gravity)
        {
            //for camera
            position.Y += 2;
            //position in world
            playerPositionY += 2;
        }

And lastly here is one of my methods to move player (i have similiar methods to move him left and up):

    public void MoveRight()
    {
        animate.Enabled = true;
        animate.Row = 0;
        position.X += speed;
        playerPositionX += speed;
    }
share|improve this question
    
In what order are you handling input, applying gravity and doing collision detection? Should be in that order. –  David Gouveia Jan 3 '12 at 16:08
    
And when you change player.PlayerPositionX/Y inside the collision code, is the player.PlayerRectangleInWorld reflecting the change too? –  David Gouveia Jan 3 '12 at 16:11
    
Yes to both of those questions. –  xerwin Jan 3 '12 at 16:32
    
Hmm, and if you suspect gravity, have you tried disabling it to verify if it still occurs? –  David Gouveia Jan 3 '12 at 16:40
    
Just tried it, problem still persist. –  xerwin Jan 3 '12 at 16:49
show 2 more comments

1 Answer

up vote 1 down vote accepted

I think the problem is that when you are iterating through your collisions (playerCollisionRectangles) -- you are adjusting the position of your player more than once. This would explain the correct behavior when you are passing over single rectangles. When you are passing over more than one rectangle, the depth correction is being fired multiple times, causing jitter.

share|improve this answer
    
That was it. All I had to add was break; to stop the for cycle. –  xerwin Jan 3 '12 at 17:45
    
Congrats on fixing it ;) –  Jon Jan 3 '12 at 18:29
    
This is a bit puzzling. The original platformer sample iterates over all colliding blocks without jitter - in fact it does so purposely in order to resolve multiple collisions. And even though you were adjusting the position more than once, these adjustments were all done in the same update iteration so the played would never see any of the intermediate state. My gut instinct can't help but think that breaking early might turn up causing problems for other corner cases where the player needs to be pushed out of more than one colliding block. But I still can't figure out what's different. –  David Gouveia Jan 3 '12 at 19:38
    
I think what needs to be done, is verify if there is still a collision after the player's position has been adjusted. If there is, then continue processing the collisions and if not, then you can break out. –  Jon Jan 3 '12 at 20:13
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.