pdiddles03 Posted October 13, 2016 Share Posted October 13, 2016 I need to determin which side was hit when collision is performed. I for some reason never can figure it out. It only returns two sides regardless of where it hits. please help! I have been stuck on this forever! function collision(obj1, obj2){ if( obj1.x + (obj1.width/2) > obj2.x - (obj2.width/2) && obj1.x - (obj1.width/2) < obj2.x + (obj2.width/2) && obj1.y + (obj1.height/2) > obj2.y - (obj2.height/2) && obj1.y - (obj1.height/2) < obj2.y + (obj2.height/2) ){ if( obj1.prev_y + (obj1.height/2) >= obj2.y - (obj2.height/2) && obj1.x + (obj1.width/2) > obj2.x - (obj2.width/2) && obj1.x - (obj1.width/2) < obj2.x + (obj2.width/2) ){ return 'bottom'; } else if( obj1.prev_y - (obj1.height/2) <= obj2.y + (obj2.height/2) && obj1.x + (obj1.width/2) > obj2.x - (obj2.width/2) && obj1.x - (obj1.width/2) < obj2.x + (obj2.width/2) ){ return 'top'; } else if( obj1.prev_x + (obj1.width/2) > obj2.x - (obj2.width/2) && obj1.y + (obj1.height/2) > obj2.y - (obj2.height/2) && obj1.y - (obj1.height/2) < obj2.y + (obj2.height/2) ){ return 'right'; } else if( obj1.prev_x - (obj1.width/2) < obj2.x + (obj2.width/2) && obj1.y + (obj1.height/2) > obj2.y - (obj2.height/2) && obj1.y - (obj1.height/2) < obj2.y + (obj2.height/2) ){ return 'left'; } } } Quote Link to comment Share on other sites More sharing options...
Inky Cricket Posted October 15, 2016 Share Posted October 15, 2016 Here's something I whipped up. I haven't tested it, so I don't know for certain if it works. Might also malfunction if the objects move at high speeds. function collision(obj1, obj2) { if( obj1.x + (obj1.width/2) > obj2.x - (obj2.width/2) && obj1.x - (obj1.width/2) < obj2.x + (obj2.width/2) && obj1.y + (obj1.height/2) > obj2.y - (obj2.height/2) && obj1.y - (obj1.height/2) < obj2.y + (obj2.height/2) ) { //I haven't tested this. //I forget if positive y is up or down. I might have gotten that backwards. //Get the horizontal and vertical distance between the objects. //You'll have to do some funny math with this if you want it to work with objects that are taller or wider. var xDistance = Math.abs(obj1.x-obj2.x) var yDistance = Math.abs(obj1.y-obj2.y) if(xDistance > yDistance) { if(obj1.x < obj2.x) { return "right" } else { return "left" } } else if(yDistance > xDistance) { if(obj1.y < obj2.y) { return "bottom" } else { return "top" } } else//if it is in a perfectly diagonal direction or at the same spot as the first object...do what? { return "insanity" } } } Quote Link to comment Share on other sites More sharing options...
waechtertroll Posted November 5, 2016 Share Posted November 5, 2016 I thought: Better late than never. Inky cricket's solution works well for square elements. Here is a solution for rectangles of any shape. The corner collision is not 100% perfect at extreme cases that way; the correct/best solution would be to step back time and advance in smaller steps until the corner collision is solved by one of the two unseparated cases, but it works. Again, depending on your axis orientation you might want to swap 'top' and 'bottom'. The solution uses the separation axis theorem (which is a fancy way of looking at the borders, at least for rectangles) to check for simple collisions: if two axes were separated before the collision but are no longer separated after collision, then movement among them caused the collision. For collision around corners (both axes were separated before collision) the simple detection might not be enough, so the objects' relative velocity is compared to their distance before the collision, to see if the collision was caused by the objects' x- or y-movement. function unseparated(x1, d1, x2, d2) { // test for normal axis separation return (x1 <= x2 && x2 <= x1 + d1) || (x2 <= x1 && x1 <= x2 + d2); }; function collision(a, b) { if (unseparated(a.x, a.width, b.x, b.width) && unseparated(a.y, a.height, b.y, b.height)) { // collision vx = (b.x - b.prev_x) - (a.x - a.prev_x); // relative x-velocity vy = (b.y - b.prev_y) - (a.y - a.prev_y); // relative y-velocity if (unseparated(a.prev_x, a.width, b.prev_x, b.width)) { // x-dir overlapped before -> collision in y-direction return (vy > 0) ? 'top' : 'bottom'; } else if (unseparated(a.prev_y, a.height, b.prev_y, b.height)) { // y overlapped before -> collision in return (vy > 0) ? 'left' : 'right'; } else { // diagonal-ish collision near corners dx = b.prev_x - a.prev_x; // x-distance before collision dy = b.prev_y - a.prev_y; // y-distance before collision if (Math.abs(vx) >= Math.abs(dx) && // x-speed was enough to collide dx * dy > 0){ // x-velocity was in x-direction return (vx > 0) ? 'right' : 'left'; } else { // x-speed was not enough to collide => y-collision return (vy > 0) ? 'top' : 'bottom'; } } } }; Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.