Remote collision detection (for games)

Hello all, so I have been pretty active on the “create games” front but not so much for blogging, sorry about that… So I come to you now with a Pen that razed over 1500+ views on codepen and 14 hearts so far…

It’s my implementation of a remote collision detection system that uses degrees instead of bounding boxes. This works well for games where you want to calculate the position of the shoot but the “cannon/lazer/fazer/tower” is not near the target, so instead of creating long bounding-boxes. We just calculate the degrees between the source (cannon) and the target(enemy). And when the cannon is rotated on those degrees it can fire.

Here I will show how a tank can “detect” the enemy. Here’s a quick example and the code will follow:

See the Pen Remote collision detection by Michael Dobekidis (@netgfx) on CodePen.

First of all let us create our HTML

<div id="tank">
  <div id="cannon"></div>
</div>

quite minimal right?


Now onwards for some css

body{
  margin:0px;
  padding:0px;
  background-image:url('http://i221.photobucket.com/albums/dd22/djmid71/desert1_zps2de2be66.png');
}

#tank{
  left:50%;
  width:100px;
  height:50px;
  top:100px;
  margin-left:-50px;
  position:relative;
  overflow:visible;
}

#cannon{
   left:10px;
   top:13px;
}

This creates the tank object and the background. Notice that cannon and tank are two separate objects.


Now the javascript part

First we declare some images as variables for ease of use:

var tankImg = "http://i221.photobucket.com/albums/dd22/djmid71/tank2b-shadow_zps83fb730c.png";

var cannonImg = "http://i221.photobucket.com/albums/dd22/djmid71/tank2c_zpsbef20208.png";

var targetImg = "http://i221.photobucket.com/albums/dd22/djmid71/tank3damaged_zpse8155303.png";

var bulletImg = "http://i221.photobucket.com/albums/dd22/djmid71/bullet_zps08a7ecb6.png";

You can find these nice textures and tank images here: Textures pack


Now we create all of our entities as Images

$(document).ready(function(){
 
  var tank = new Image();
  tank.style.left = "0px";
  tank.style.top  = "0px";
  tank.onload = function(){
   
    $("#tank").append(tank);
   
  };
 
  tank.src = tankImg;
 
  //////////////
 
  var cannon = new Image();
  cannon.style.left = "10px";
  cannon.style.top  = "13px";
  cannon.style.position = "absolute";
  cannon.style.marginRight = "100%";
  cannon.style.overflow    = "visible";
  cannon.onload = function(){
   
    $("#cannon").append(cannon);
   
  };
 
  cannon.src = cannonImg;
 
  ////////////////
 
  var target = new Image();
  target.style.left = getRandom($(document).width()-50,50)+"px";
  target.style.top  = getRandom(300,50)+"px";
  target.style.position = "absolute";
  target.id = "target";
  target.onload = function(){
   
    $("body").append(target);
    scan();
  };
 
  target.src = targetImg;

* getRandom is a typical random function

function getRandom(max, min) {
    return Math.floor(Math.random() * (1 + max - min) + min);
}

Here we loaded all our entities and appended them to DOM, as you see when the target(enemy) is created we call a function scan()
Let’s see that and what it does:

function scan() {
var angle =  checkAngle();
    TweenMax.to("#cannon>img",5,{rotation:360,transformOrigin:9+"px "+7+'px',onUpdate:function(){
     
      var element = this.target;
      var _angle = Math.round(element[0]._gsTransform.rotation);
     
      console.log(_angle,"----",angle);
      if(_angle === angle || (angle<=_angle+5 && angle>=_angle-5) ){
       
        this.pause();
      }
     
    }});
}

What we do here is to rotate the cannon and on every frame we check the angle of the cannon upon the angle of the target, and if the angles match (+-5pixels) then we pause the rotation and the target has been detected.
The last part is the checkAngle() function which looks like this:

function checkAngle(){
 
 var targetX = $("#target").offset().left+25;
 var targetY = $("#target").offset().top+25;
 var targetW = $("#target").width();
 var targetH = $("#target").height();
 
  var angleY = (targetY-(targetH/2)) - $("#tank").offset().top;
    var angleX = (targetX-(targetW/2)) - $("#tank").offset().left;
    var angle = Math.round(Math.atan2(angleY, angleX) * 180 / Math.PI) + 90;// in degrees
       
    angle = angle - 90; // minus the tank angle, otherwise the cannon aligns to the front
 
  if(angle < 0){
    angle = 360 - Math.abs(angle); // converting negative angle to its counterpart
  }
 
  console.log(angle);
 
  return angle;
}

Here we use simple math to calculate the angle between the target(enemy) and the source(tank)

I hope you enjoyed this little tutorial. For any questions or remarks please leave me a comment.

Enjoy!

Facebooktwittergoogle_pluspinterestlinkedin
linkedin

Leave a Reply

Your email address will not be published. Required fields are marked *