i'm trying to develop a game using HTML5 canvas with javascript and I am having problems detecting collisions without hard coding it using the (x,y) coordinates of the two objects. In my code based from research, found out the mon algorithm in checking if the two objects are colliding which is
Object1 = a moving player
Object2 = fixed (x,y) points. Non movable object
(object1.x < object2.x + object2.width && object1.x + object1.width > object2.x &&
object1.y < object2.y + object2.height && object1.y + object1.height > object2.y)
I tried it and developed it with other codes and it works, it detects the collisions. But I have an issue with the collisions, it works with the condition in the left side
but when the object1
goes to the top, bottom or right
of the object2 it goes back to the object2's left side
. In other words, if the object1 goes to the top/bottom or right it goes back to the left side. Any kind of help would be much appreciated.
function collide(object1, object2){
//object1 player
this.x = object1.x;
this.y = object1.y;
this.w = object1.w;
this.h = object1.h;
//object2 any object
this.x2 = object2.x;
this.y2 = object2.y;
this.w2 = object2.w;
this.h2 = object2.h;
//collisions
var isCorrect = false;
var side = 0;
if ((this.x < this.x2 + this.w2) && (this.x + this.w > this.x2)
&& (this.y < this.y2 + this.h2) && (this.h + this.y > this.y2)){
isCorrect = true;
}
if (this.x + this.w > this.x2){
//left check
side = 1;
}else if (this.x < this.x2 + this.w2){
//right check
side = 2;
}else if (this.y + this.h > this.y2){
//bottom check
side = 3;
}else if (this.y < this.y2 + this.h2){
//top check
side = 4;
}
if (isCorrect){
if ((this.x + this.w > this.x2) && side == 1){
playerObj.x -= 5;
}else if ((this.x < this.x2 + this.w2) && side == 2){
playerObj.x += 5;
}else if ((this.y + this.h > this.y2) && side == 3){
playerObj.y += 5;
}else if ((this.y < this.y2 + this.h2) && side == 4){
playerObj.y -= 5;
}
}
}
i'm trying to develop a game using HTML5 canvas with javascript and I am having problems detecting collisions without hard coding it using the (x,y) coordinates of the two objects. In my code based from research, found out the mon algorithm in checking if the two objects are colliding which is
Object1 = a moving player
Object2 = fixed (x,y) points. Non movable object
(object1.x < object2.x + object2.width && object1.x + object1.width > object2.x &&
object1.y < object2.y + object2.height && object1.y + object1.height > object2.y)
I tried it and developed it with other codes and it works, it detects the collisions. But I have an issue with the collisions, it works with the condition in the left side
but when the object1
goes to the top, bottom or right
of the object2 it goes back to the object2's left side
. In other words, if the object1 goes to the top/bottom or right it goes back to the left side. Any kind of help would be much appreciated.
function collide(object1, object2){
//object1 player
this.x = object1.x;
this.y = object1.y;
this.w = object1.w;
this.h = object1.h;
//object2 any object
this.x2 = object2.x;
this.y2 = object2.y;
this.w2 = object2.w;
this.h2 = object2.h;
//collisions
var isCorrect = false;
var side = 0;
if ((this.x < this.x2 + this.w2) && (this.x + this.w > this.x2)
&& (this.y < this.y2 + this.h2) && (this.h + this.y > this.y2)){
isCorrect = true;
}
if (this.x + this.w > this.x2){
//left check
side = 1;
}else if (this.x < this.x2 + this.w2){
//right check
side = 2;
}else if (this.y + this.h > this.y2){
//bottom check
side = 3;
}else if (this.y < this.y2 + this.h2){
//top check
side = 4;
}
if (isCorrect){
if ((this.x + this.w > this.x2) && side == 1){
playerObj.x -= 5;
}else if ((this.x < this.x2 + this.w2) && side == 2){
playerObj.x += 5;
}else if ((this.y + this.h > this.y2) && side == 3){
playerObj.y += 5;
}else if ((this.y < this.y2 + this.h2) && side == 4){
playerObj.y -= 5;
}
}
}
Share
Improve this question
edited Apr 25, 2015 at 6:27
markE
105k11 gold badges170 silver badges183 bronze badges
asked Apr 25, 2015 at 4:42
John SantosJohn Santos
511 silver badge3 bronze badges
2
- you need to log the positions of your elements as they are being animated and find out where your if's don't catch the collision – nicholaswmin Commented Apr 25, 2015 at 4:44
- What do you mean, sir? – John Santos Commented Apr 25, 2015 at 5:10
1 Answer
Reset to default 18This collision function will tell you which side of rect2 collided with rect1:
And of course, the opposite side of rect1 collided with rect2.
This function is a 2-pass test:
Test1: Check if the 2 rectangle's centers are close enough to be colliding
Test2: If yes, check the intersection depths to determine which side was most involved in the collision.
The collision function
function collide(r1,r2){
var dx=(r1.x+r1.w/2)-(r2.x+r2.w/2);
var dy=(r1.y+r1.h/2)-(r2.y+r2.h/2);
var width=(r1.w+r2.w)/2;
var height=(r1.h+r2.h)/2;
var crossWidth=width*dy;
var crossHeight=height*dx;
var collision='none';
//
if(Math.abs(dx)<=width && Math.abs(dy)<=height){
if(crossWidth>crossHeight){
collision=(crossWidth>(-crossHeight))?'bottom':'left';
}else{
collision=(crossWidth>-(crossHeight))?'right':'top';
}
}
return(collision);
}
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
var rects=[];
var rect1={ x:100,y:100,w:85,h:85,fill:'red'}
var rect2={ x:10,y:10,w:40,h:60,fill:'gold'}
$("#canvas").mousemove(function(e){handleMouseMove(e);});
draw();
function collide(r1,r2){
var dx=(r1.x+r1.w/2)-(r2.x+r2.w/2);
var dy=(r1.y+r1.h/2)-(r2.y+r2.h/2);
var width=(r1.w+r2.w)/2;
var height=(r1.h+r2.h)/2;
var crossWidth=width*dy;
var crossHeight=height*dx;
var collision='none';
//
if(Math.abs(dx)<=width && Math.abs(dy)<=height){
if(crossWidth>crossHeight){
collision=(crossWidth>(-crossHeight))?'bottom':'left';
}else{
collision=(crossWidth>-(crossHeight))?'right':'top';
}
}
return(collision);
}
function draw(){
ctx.clearRect(0,0,cw,ch);
ctx.fillStyle=rect1.fill;
ctx.fillRect(rect1.x,rect1.y,rect1.w,rect1.h);
ctx.fillStyle=rect2.fill;
ctx.fillRect(rect2.x,rect2.y,rect2.w,rect2.h);
var side=collide(rect1,rect2);
ctx.fillStyle='green'
if(side=='top'){ ctx.fillRect(rect2.x,rect2.y,rect2.w,3); }
if(side=='right'){ ctx.fillRect(rect2.x+rect2.w,rect2.y,3,rect2.h); }
if(side=='bottom'){ ctx.fillRect(rect2.x,rect2.y+rect2.h,rect2.w,3); }
if(side=='left'){ ctx.fillRect(rect2.x,rect2.y,3,rect2.h); }
}
function handleMouseMove(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
rect2.x=mouseX;
rect2.y=mouseY;
draw();
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis./ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Move the mouse to drag the gold rect<br>Any colliding side of gold rect will highlight</h4>
<canvas id="canvas" width=300 height=300></canvas>