1
\$\begingroup\$

So I am having issues with my platformer that I am developing. I can detect collisions fine when there are a line of parralel blocks or even single blocks. The issue I have is when blocks form an L shape. [] for example.
[]

When my character runs into the wall, he sort of just squeaks through and gets zoomed out. I've tried using an else statement that just sends him back a couple pixels back, but it doesn't work because I don't think it accounts for one of the two blocks. Each block is it's own object.

Any help?

This collision code is in my Player class. This is the only detection I have so far in the game. I attempted to use and adjust code from a breakernoid tutorial I found somehwere, and I realized that the code doesn't totally work for what I am doing.

public void checkYCollisions(block[] platforms)
    {


        if (position.Y >= 700)
            grounded = true;
        else
            grounded = false;

        float Xradius = Width / 2;
        float Yradius = Height / 2;
        block collidedPlatform = null;

        foreach (block p in platforms)
        {
            if ((position.X > (p.position.X - p.Width / 2 - Xradius )) &&
                (position.X < (p.position.X + p.Width / 2 + Xradius )) &&
               (position.Y > (p.position.Y - p.Height / 2 - Yradius )) &&
                (position.Y < (p.position.Y + p.Height / 2 + Yradius)))

            {
                collidedPlatform = p;
                break;
            }
        }
        //collisions work for all side of blocks. 
        if (collidedPlatform != null)
        {
            if ((position.Y <
                (collidedPlatform.position.Y - collidedPlatform.Height / 1.5 /*+ radius*/)))
            {

                grounded = true;

            }

            else if ((position.Y   >
                (collidedPlatform.position.Y + collidedPlatform.Height / 2 )))
            {
                if(y_vel < 0)
                    y_vel *= -1;
                //player1.direction.Y = -1.0f * player1.direction.Y;
            }


            else
            {
                x_vel *= -2;
            }
        }

I am guessing the issue is because I only have one collided block selected at any time. So I don't really know how to fix it that I can have two blocks selected. Note, once again, this code works for all blocks that are by themselves, or just a horizontal(same x position) line of blocks. It's just that L situation where I run into a corner.

\$\endgroup\$
1
\$\begingroup\$

Instead of checking a single block for collision, you could keep a list of blocks and then iterate through the list and perform collision responses for each block in the list. Like this:

public void checkYCollisions(block[] platforms)
{
    if (position.Y >= 700)
        grounded = true;
    else
        grounded = false;

    float Xradius = Width / 2;
    float Yradius = Height / 2;
    List<block> collidedPlatforms = new List<block>();

    foreach (block p in platforms)
    {
        if ( /* p contains position */ )
        {
            collidedPlatforms.Add(p);
        }
    }

    foreach (block b in collidedPlatforms)
    {
        // perform collision responses
    }
}

One thing I would recommend is looking into the Rectangle structure. It contains methods for testing if points or other rectangles intersect or are contained within the rectangle itself.

\$\endgroup\$
  • \$\begingroup\$ You think that is a better way to do collision detection than my way? \$\endgroup\$ – taytay Jul 27 '14 at 3:32
  • \$\begingroup\$ No problem! Since I assume you're referring to the Rectangle suggestion, then it's completely up to you. The whole point of XNA/MonoGame is to provide boilerplate code for games so that you don't have to write things yourself. Plus using it may make your code more readable if you ever need to come back to it at a later point in time. \$\endgroup\$ – fastinvsqrt Jul 27 '14 at 3:38
0
\$\begingroup\$

Here's my pseudo-code:

  1. When the player updates, get the position he wants to go. If it doesn't change, do nothing.

  2. Get the nearest blocks for that position, store them in an array or something.

  3. Go through that list / array, check for collisions
  4. If it collides, tweak the player's position until it doesn't collide with the block. For example, the player glitches through the block by 5 pixels, you just subtract the 5 pixels.
  5. Make that tweaked position the players position.

You can just skip step 2, but sometimes doing step 2 is easier.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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