The problem

The problem lies in your method of collision resolution. Your method goes as follows:


Move the player.
Check for collision.
Determine the shortest collision depth.
Resolve collision.


The problem with this, is that it can easily move the player in the wrong direction. You can see how this might happen in the image below:



Because the player is moving down to the right, and is above the ground, you would expect the player to land on top of the ground (by the green box). But instead, it gets pushed out of the ground to the left (represented by the red box). This can be a problem if the player is trying to jump from one platform to another, because the player may end up falling to his death due to bad collision code.

The solution

The solution to this problem is actually pretty simple. Instead of using the above method, you resolve collision like so:


Move the player along the X axis.
Check for colliding tiles.
Resolve X collision.
Move the player along the Y axis.
Check for colliding tiles.
Resolve Y collision.


Now I hope that you didn't throw your depth check code away, because you are still going to need it for steps 3 and 6.

To resolve collision between tiles on either of the two axes (after moving the player), you first get the depth of the collision. You then take the depth of the collision, and subtract that from the axes that you are currently checking for collision. Note that the depth should be negative if you are moving to the left, so that the player moves in the right direction.

Using this method, you will not only not have to worry about collision bugs like the one in the scenario in the above image, but this method also can handle collision with multiple tiles.

Example code:

void move(velocity)
{
    top = player.y / TILE_HEIGHT;
    bottom = top + (player.height / TILE_HEIGHT);
    left = player.x / TILE_WIDTH;
    right = left + (player.width / TILE_WIDTH);

    // Check X

    player.x += velocity.x;
    player.updateAABB();
    for(int tx = left - 1; tx &lt;= right + 1; tx++)
    {
        for(int ty = top - 1; ty &lt;= bottom + 1; ty++)
        {
            aabb = world.getTileAABB(tx, ty);
            if(aabb.collidesWith(player.aabb))
            {
                depth = player.aabb.getXDepth(aabb);
                player.x -= depth;
            }
        }
    }

    // Now check Y

    player.y += velocity.y;
    player.updateAABB();
    for(int tx = left - 1; tx &lt;= right + 1; tx++)
    {
        for(int ty = top - 1; ty &lt;= bottom + 1; ty++)
        {
            aabb = world.getTileAABB(tx, ty);
            if(aabb.collidesWith(player.aabb))
            {
                depth = player.aabb.getYDepth(aabb);
                player.y -= depth;
            }
        }
    }

    player.updateAABB();
}


2D AABBs and resolving multiple collisions
My question is different from this previous question: Does repeating one word to form a password result in a similar pattern in its encrypted format?. I'm specifically wondering about brute force attacks. Based on my experiences with John The Ripper, I doubt that repeating a pattern in a password would shorten the time to successfully brute force a password like f00B@rf00B@rf00B@r as opposed to a random string of equal length. However, my doubt is based on the fact that, according to the documentation, JTR does not include a specific attack mode for repeating patterns. JTR, and presumably other brute force tools, can be customized for any arbitrary attack mode. But we can't know how often attackers bother to customize attacks in this way. So then the question becomes mathematical. Please forgive the awkward pseudo mathematical notation. 

T = brute force cracking time

PL = pattern of characters of length L

N = number of times PL is repeated

R(LN) = string of random characters of length (L times N)


Would it be true that

T(PL*N)= T(R(LN))


If true, then a repeating pattern password would not affect brute force cracking time. But is it true?
