Help finding time of collision

Posted by WannaBe on Game Development See other posts from Game Development or by WannaBe
Published on 2014-07-22T21:29:22Z Indexed on 2014/08/22 10:28 UTC
Read the original article Hit count: 464

Filed under:
|
|

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 Picture One showing the problem

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

Picture 2 Recreate in JSFiddle

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.

© Game Development or respective owner

Related posts about 2d

Related posts about collision-detection