Web Analytics Made Easy -
StatCounter "Collision" Contact - CodingForum

Announcement

Collapse
No announcement yet.

"Collision" Contact

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • "Collision" Contact

    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!

  • #2
    what kind of elements are we talkin about?
    I am the luckiest man in the world

    Comment


    • #3
      Might need more than a function...

      Try this for inspiration:

      Comment


      • #4
        I'm just talking about regular elements such as images, divs, etc.

        Happy coding!

        Comment


        • #5
          a collision function

          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.
          If at first you don't succeed, spend more time online researching javascript!
          Beck

          Comment


          • #6
            It didn't work. It always returned false unless the object coordinates matched exactly.

            Comment


            • #7
              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.
              jasonkarldavis.com

              Comment


              • #8
                Just realized that would cause massive recursion problems.

                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:

                PHP Code:
                HTMLElement.prototype.__defineGetter__('absoluteCoordinates', function() {
                    var 
                refNode this.parentNode;
                    var 
                coords = {xparseInt(this.offsetLeft), yparseInt(this.offsetTop)};

                    while (
                typeof refNode.offsetLeft != 'undefined') {
                        
                coords.+= parseInt(refNode.offsetLeft);
                        
                coords.+= parseInt(refNode.offsetTop);
                        
                refNode refNode.parentNode;
                    }

                    return 
                coords;
                });

                HTMLElement.prototype.isTouching = function(node) {
                    var 
                thisOffset this.absoluteCoordinates;
                    var 
                nodeOffset node.absoluteCoordinates;
                    return (
                thisOffset.>= nodeOffset.&& thisOffset.<= nodeOffset.parseInt(node.offsetWidth) && thisOffset.>= nodeOffset.&& thisOffset.<= nodeOffset.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...
                Last edited by jkd; Jun 29, 2002, 08:43 PM.
                jasonkarldavis.com

                Comment


                • #9
                  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.

                  Code:
                  <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>

                  Comment

                  Working...
                  X