javascript - Detect which side of a rectangle is colliding with another rectangle -
i'm trying develop game using html5 canvas javascript , having problems detecting collisions without hard coding using (x,y) coordinates of 2 objects. in code based research, found out common algorithm in checking if 2 objects colliding is
object1 = 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 , developed other codes , works, detects collisions. have issue collisions, works condition in left side
when object1
goes top, bottom or right
of object2 goes object2's left side
. in other words, if object1 goes top/bottom or right goes left side. kind of appreciated.
function collide(object1, object2){ //object1 player this.x = object1.x; this.y = object1.y; this.w = object1.w; this.h = object1.h; //object2 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; } } }
this collision function tell side of rect2 collided rect1:
and of course, opposite side of rect1 collided rect2.
this function 2-pass test:
test1: check if 2 rectangle's centers close enough colliding
test2: if yes, check intersection depths determine side involved in 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 , 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 browser we're handling 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.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <h4>move mouse drag gold rect<br>any colliding side of gold rect highlight</h4> <canvas id="canvas" width=300 height=300></canvas>
Comments
Post a Comment