I am working on a platformer 2D, and i am currently focusing on collision. I have the actual rectangle(class: Rect) and i can detect if the player-model is intersepting it. However, when it comes from the side, that is when the problems appear: i can prevent it from going down after the interseption but i cant prevent it if it intersepts with the edges. how can I make a better collision system?
EDIT:
I have worked a little on a system, but it doesnt work. Help me improve this:
for(Platform p : game.platforms){
if(Rect.intersects(getBounds(), p.getBounds())){
coll = true;
int px = p.x;
int py = p.y;
if((x + 100) >= px && (x + 100) <= px + 10){
x = px - 101;
y += 100;
Toast.makeText(game.c, "if(x + 100) >= px && (x + 100) <= px + 10)", Toast.LENGTH_LONG).show();
} else if(y <= (py + 1) && y >= py + p.height + 10){
y = 0;
Toast.makeText(game.c, "if8y <= (py + 1) && y >= py + p.height + 10)", Toast.LENGTH_LONG).show();
} else if(y >= py ){
y = py - 100;
Toast.makeText(game.c, "if(y >= py", Toast.LENGTH_LONG).show();
}
}
}
if(!coll){
y += 6;
}else{
heightJumped = 0;
canJump = true;
isInAir = false;
jumping = false;
}
coll = false;
}
Answer
This is my perfectly working 2d collision system (C++). Maybe it helps. I have also had the problem with wrong colliding from sides but finally solved it.
So, I have a rectangle of player with 64px width and height.
"posX" and "posY" are its center coordinates.
The parameters of the "colCheck" function are the sides of the rectangle which we want to check if colliding.
float difference = 0; //final difference between player and object (inside)
short Player::colCheck(float left2, float top2, float right2, float bottom2)
{
short _returnVal = 0; //Return value
float left1 = posX-32; //Player Left
float right1 = posX+32; //Player Right
float top1 = posY-32; //Player Top
float bottom1 = posY+32; //Player Bottom
if(left1 < right2 && right1 > left2 && top1 < bottom2 && bottom1 > top2)
{
if(right1 > left2 && left1 < left2 && right1-left2 < bottom1-top2 && right1-left2 < bottom2-top1)
{
difference = right1-left2;
_returnVal = 1;
//Player collides from left side of the object
}
else if(left1 < right2 && right1 > right2 && right2-left1 < bottom1-top2 && right2-left1 < bottom2-top1)
{
difference = right2-left1;
_returnVal = 2;
//Player collides from right side of the object
}
else if(bottom1 > top2 && top1 < top2)
{
difference = bottom1-top2;
_returnVal = 3;
//Player collides from top side of the object
}
else if(top1 < bottom2 && bottom1 > bottom2)
{
difference = bottom2-top1;
_returnVal = 4;
//Player collides from bottom side of the object
}
}
return _returnVal;
}
//Parameter 'cols' (=collisions): cols [index] [side]
//cols[x][0] -> left side
//cols[x][1] -> top side
//cols[x][2] -> right side
//cols[x][3] -> bottom side
//Parameter 'size': count of the collisions
void Player::colReact(std::vector> cols, unsigned int size)
{
for(unsigned int i = 0; i < size; i++)
{
short ret = colCheck(cols[i][0], cols[i][1], cols[i][2], cols[i][3]); //check if collides and get the return value
if(ret > 0) //if is colliding
{
float changeX; //variable to add to players X coord.
float changeY; //variable to add to players Y coord.
if(ret == 1) //collides from left
{
changeX = -difference;
changeY = 0;
}
else if(ret == 2) //collides from right
{
changeX = difference;
changeY = 0;
}
else if(ret == 3) //collides from top
{
changeX = 0;
changeY = -difference;
}
else if(ret == 4) //collides from bottom
{
changeX = 0;
changeY = difference;
}
posX += changeX; //add the -difference value to players x coord.
posY += changeY; //add the -difference value to players y coord.
}
}
}
Hope it's a helpful source.
No comments:
Post a Comment