View Full Version : "Collision" Contact
nolachrymose
06-29-2002, 06:33 PM
I was wondering if someone could help me out and create a function that would return a boolean value of whether two elements (that are passed as parameters to the function) are touching each other based on their positions. I've tried many variations but cannot get it right. Any help is greatly appreciated.
Happy coding! :)
Roelf
06-29-2002, 07:27 PM
what kind of elements are we talkin about?
adios
06-29-2002, 07:44 PM
Might need more than a function...
Try this for inspiration:
http://www.scottandrew.com/dhtml/docs/collide.html
nolachrymose
06-29-2002, 09:55 PM
I'm just talking about regular elements such as images, divs, etc.
Happy coding! :)
I wrote this function for a video game I'm making in javascript. It tests if the objects are overlapping in any way, left over right or top over bottom. The parameters, target & target1, are references to style sheets.
/* target is a reference to an objects style sheets */
function collide(target,target1) {
var Ttop = target.posTop, Tleft = target.posLeft;
var Tbottom = parseInt(target.height), Tright = parseInt(target.width);
Tbottom = Ttop + Tbottom, Tright = Tleft + Tright;
var Btop = target1.posTop, Bleft = target1.posLeft;
var Bbottom = parseInt(target1.height), Bright = parseInt(target1.width);
Bbottom = Btop + Bbottom, Bright = Bleft + Bright;
if ((Bbottom>Ttop && Btop<Tbottom) &&
(Bleft<Tright && Bright>Tleft))
return true;
else return false;
}
So check if that works, okay? Good luck.
nolachrymose
06-30-2002, 12:05 AM
It didn't work. It always returned false unless the object coordinates matched exactly.
Since you're dealing with rectangular objects, you need to check for a few things. I'm just gonna use a few self-explanatory variables:
function isTouching(node1, node2) {
/* pretending variables node1Left, node1Top, node1Width, node1Height, and equivalent variables for node2 are defined properly */
var isIn = false;
// check for vertical coordinates
if (node1Left >= node2Left && node1Left <= node2Left + node2Width) {
// vertical looks good, check for horizontal
isIn = (node1Top >= node2Top && node1Top <= node2Top + node2Height);
}
if (!isIn) {
// here's the trick to shortcut this:
isIn = isTouching(node2, node1);
// reverse the args
}
return isIn;
}
I *think* something like that would work - I'm gonna clean it up and provide real working code in a bit.
Just realized that would cause massive recursion problems. :D
Anyway, here is some code I wrote for Mozilla. Should easily be ported over to IE, just replace some conveniences with methods, and have a function that accepts 2 arguments instead of one:
HTMLElement.prototype.__defineGetter__('absoluteCoordinates', function() {
var refNode = this.parentNode;
var coords = {x: parseInt(this.offsetLeft), y: parseInt(this.offsetTop)};
while (typeof refNode.offsetLeft != 'undefined') {
coords.x += parseInt(refNode.offsetLeft);
coords.y += parseInt(refNode.offsetTop);
refNode = refNode.parentNode;
}
return coords;
});
HTMLElement.prototype.isTouching = function(node) {
var thisOffset = this.absoluteCoordinates;
var nodeOffset = node.absoluteCoordinates;
return (thisOffset.x >= nodeOffset.x && thisOffset.x <= nodeOffset.x + parseInt(node.offsetWidth) && thisOffset.y >= nodeOffset.y && thisOffset.y <= nodeOffset.y + parseInt(node.offsetHeight)) || ((arguments.callee.caller == HTMLElement.prototype.isTouching) ? false : node.isTouching(this));
}
To get around the recursion issues, I essentially said:
if thecalling function equals thisfunction:
arguments.callee.caller == nameOfThisFunction
then return false, because it short circuited past the touching test again, and if not, call itself with the other node. :)
The short-circuit validation might be a little confusing combined with the ternary operator though, if you're not too familiar with Javascript...
nolachrymose
06-30-2002, 03:15 PM
OK - I've got that part working. Now I have a new problem. I've changed the functions so that they can be used in IE, and that works fine. The problem is with my keydown event handler. I'm getting this error in NS 7:
Error: invalid assignment left-hand side
Line: 34
else if(e.which==rightKey||e.keyCode=rightKey) node.style.left=nodePos.x+5;
I'm getting this error in IE 6:
Line: 34
Char: 39
Error: Syntax error.
Neither of these debugging reports are of help because I have "scavengered" my code to see any error that would match in my code and couldn't find one. Any help is greatly appreciated. Code is below.
<html>
<head>
<title>Collision Objects</title>
<script type="text/javascript">
var loaded=false;
var leftKey=37,upKey=38,rightKey=39,downKey=40;
function absCoords(node) {
var refNode = node.parentNode;
var coords = {x: parseInt(node.offsetLeft), y: parseInt(node.offsetTop)};
while (typeof refNode.offsetLeft != 'undefined') {
coords.x += parseInt(refNode.offsetLeft);
coords.y += parseInt(refNode.offsetTop);
refNode = refNode.parentNode;
}
return coords;
}
function collision(node1,node2) {
var thisOffset = absCoords(node1);
var nodeOffset = absCoords(node2);
return (thisOffset.x >= nodeOffset.x && thisOffset.x <= nodeOffset.x + parseInt(node2.offsetWidth) && thisOffset.y >= nodeOffset.y && thisOffset.y <= nodeOffset.y + parseInt(node2.offsetHeight))
} window.onload=new Function("loaded=true");
document.onkeydown=movePos;
function movePos(evt) {
if(loaded) {
var node=document.getElementById('c1');
var nodePos=absCoords(node);
var e=evt||event;
if(e.which==leftKey||e.keyCode==leftKey) node.style.left=nodePos.x-5;
else if(e.which==upKey||e.keyCode==upKey) node.style.top=nodePos.y-5;
else if(e.which==rightKey||e.keyCode=rightKey) node.style.left=nodePos.x+5;
elseif(e.which==downKey||e.keyCode=downKey) node.style.top=nodePos.y+5;
alert(collide(node,document.getElementById('c2')));
}
}
</script>
</head>
<body>
<div id="scrollarea" style="position:absolute;left:300px;top:200px;width:200px;height:200px;color:white;background:black;">
<div id="c1" style="position:absolute;left:100px;top:100px;">you</div>
<div id="c2" style="position:absolute;left:100px;top:150px;z-index:1;">enemy</div>
</div>
</body>
</html>
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.