Page 2 of 2

Re: Platformer Collision Help

Posted: Fri Dec 24, 2010 9:31 am
by dandymcgee
eatcomics wrote:
dandymcgee wrote:
thejahooli wrote:
N64vSNES wrote:I think I understand, Are you saying that if the player hits a wall in mid air then as he comes down it detects a collision from the ground and lets him stand?.....I think thats what you said correct me if I'm wrong ;)
Yes, as he comes down he detects a collision with the wall, but thinks it's the ground as it is colliding vertically.
How do you collide vertically with a wall? :shock:
vertically with the ground you mean? most walls are vertical
No, I said what I meant.

Re: Platformer Collision Help

Posted: Fri Dec 24, 2010 11:09 am
by N64vSNES
Just to confirm this is how the collision is acting?
Image

EDIT: Just a thought but are you updating collision and then updating players position, or updating the players position and then collision?

Re: Platformer Collision Help

Posted: Sun Jan 09, 2011 5:13 pm
by sk1v3r
I know this thread is kindof old and you have probably fixed it by now, but as in my eyes it came to no clear conclusion, I would like to say that once had this problem as my tiles were smaller than my player(the player itself wasn't tile-based so there weren't exact collision detection and he would float by the sides of walls)
So my fix to it was if the tile above the tile that you are testing collision for is solid( e.g., you an collide with it) then there is no way that there has been a collision with the ground on that specific tile.
Hope This Helps anyone who comes across this :)

Re: Platformer Collision Help

Posted: Sun Jan 09, 2011 5:22 pm
by XP - SAI
What do you use C++ :|

Re: Platformer Collision Help

Posted: Sun Jan 09, 2011 5:39 pm
by sk1v3r
I use c++ but the theory is the same for everything :)

Re: Platformer Collision Help

Posted: Sun Jan 09, 2011 7:09 pm
by thejahooli
Sorry that I didn't show how I fixed it. I'll post a description and then my code in spoiler tags so that you can see the code

First I found the outer tile positions that the object will be touching when only moved by it's x velocity. Then, depending on which direction the object is moving, check the collisions for all the tiles it could be touching using the outer tile positions I found out, starting from whichever tiles it would hit first for the direction in which it is moving (left side when moving right and right side when moving left). If the tile is solid, I set the objects position to outside the tile and it's x velocity to 0, and stop performing collision detection for this section.

Then I repeat this, but with the position only being changed along the y axis and the variables used changed accordingly. As well as this, I set a boolean variable called 'isOnGround' to false each frame and, if there is a collision detected when moving downwards, I set it to 'true'. Each frame when the object is updated, a gravity value is added to the y velocity so that there is still a collision downwards when just standing on the ground.

Sorry if this is not very clear, I'm not very good at explaining things. If you have any further questions just ask.

Edit:
Click here to see the hidden message (It might contain spoilers)
Here is some pseudo code in case it helps.

Code: Select all

yVelocity += gravityAmount;

// Gets the border tile positions in their array index form
leftSideTilePosition = ((xPosition + xVelocity) - ((xPosition + xVelocity) % tileWidth)) / tileWidth;
rightSideTilePosition = ((xPosition + xVelocity + width) - ((xPosition + xVelocity + width) % tileWidth)) / tileWidth;
topSideTilePosition = (yPosition - (yPosition % tileHeight)) / tileHeight;
bottomSideTilePosition = ((yPosition + height - 1) - ((yPosition + height - 1) % tileHeight) / tileHeight;

collisionHandled = false;

if(xVelocity > 0)
{
for x = leftSideTilePosition to rightSideTilePosition
{
for y = topSideTilePosition to bottomSideTilePosition
{
if(tileArray[x][y].IsSolid != true) break;

xPosition = (x * tileWidth) - width;
xVelocity = 0;

collisionHandled = true;
break;
}
if(collisionHandled) break;
}
}
else if(xVelocity < 0)
{
for x = rightSideTilePosition to leftSideTilePosition
{
for y = topSideTilePosition to bottomSideTilePosition
{
if(tileArray[x][y].IsSolid != true) break;

xPosition = (x * tileWidth) + tileWidth;
xVelocity = 0;

collisionHandled = true;
break;
}
if(collisionHandled) break;
}

topSideTilePosition = ((yPosition + yVelocity) - ((yPosition + yVelocity) % tileHeight)) / tileHeight;
bottomSideTilePosition = ((yPosition + yVelocity + height) - ((yPosition + yVelocity + height) % tileHeight)) / tileHeight;
leftSideTilePosition = (xPosition - (xPosition % tileWidth)) / tileWidth;
rightSideTilePosition = ((xPosition + width - 1) - ((xPosition + width - 1) % tileWidth) / tileWidth;

collisionHandled = false;

isOnGround = false;

if(yVelocity > 0)
{
for y = topSideTilePosition to bottomSideTilePosition
{
for x = leftSideTilePosition to rightSideTilePosition
{
if(tileArray[x][y].IsSolid != true) break;

yPosition = (y * tileHeight) - height;
yVelocity = 0;

isOnGround = true;

collisionHandled = true;
break;
}
if(collisionHandled) break;
}
}
else if(yVelocity < 0)
{
for y = bottomSideTilePosition to topSideTilePosition
{
for x = leftSideTilePosition to rightSideTilePosition
{
if(tileArray[x][y].IsSolid != true) break;

yPosition = (y * tileHeight) + tileHeight;
yVelocity = 0;

collisionHandled = true;
break;
}
if(collisionHandled) break;
}
If someone could tell me how to do tabs, this would probably be a lot easier to read.