Help finding time of collision
- by WannaBe
I am making a simple game right now and am struggling with collision response. My goal is to someday be able to turn it into a 2D platformer but I have a long way to go. I am currently making this in JavaScript and using the canvas element so (0,0) is in the top left and positive X is to the right and positive Y is down.
I read a helpful post on StackExchange that got me started on this but I can't seem to get the algorithm 100% correct. How to deal with corner collisions in 2D?
I can detect the collision fine but I can't seem to get the response right. The goal is to detect which side the player hit first since minimum displacement doesn't always work. The X response seems to work fine but the Y only works when I am far from the corners. Here is a picture showing what happens
Here is the code
var bx = box.x;
var by = box.y;
var bw = box.width;
var bh = box.height;
var boxCenterX = bx + (bw/2);
var boxCenterY = by + (bh/2);
var playerCenterX = player.x + player.xvel + (player.width/2);
var playerCenterY = player.y + player.yvel + (player.height/2);
//left = negative and right = positve, 0 = middle
var distanceXin = playerCenterX - boxCenterX;
var distanceYin = playerCenterY - boxCenterY;
var distanceWidth = Math.abs(distanceXin);
var distanceHeight = Math.abs(distanceYin);
var halfWidths = (bw/2) + (player.width/2);
var halfHeights = (bh/2) + (player.height/2);
if(distanceWidth < halfWidths){
//xcollision
if(distanceHeight < halfHeights){
//ycollision
if(player.xvel == 0){
//adjust y
if(distanceYin > 0){
//bottom
player.y = by + bh;
player.yvel = 0;
}else{
player.y = by - player.height;
player.yvel = 0;
}
}else if(player.yvel == 0){
//adjust x
if(distanceXin > 0){
//right
player.x = bx + bw;
player.xvel = 0;
}else{
//left
player.x = bx - player.width;
player.xvel = 0;
}
}else{
var yTime = distanceYin / player.yvel;
var xTime = distanceXin / player.xvel;
if(xTime < yTime){
//adjust the x it collided first
if(distanceXin > 0){
//right
player.x = bx + bw;
player.xvel = 0;
}else{
//left
player.x = bx - player.width;
player.xvel = 0;
}
}else{
//adjust the y it collided first
if(distanceYin > 0){
//bottom
player.y = by + bh;
player.yvel = 0;
}else{
player.y = by - player.height;
player.yvel = 0;
}
}
}
}
}
And here is a JSFiddle if you would like to see the problem yourself. http://jsfiddle.net/dMumU/
To recreate this move the player to here
And press up and left at the same time. The player will jump to the right for some reason.
Any advice? I know I am close but I can't seem to get xTime and yTime to equal what I want every time.