HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Collision detection accuracy

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
accuracycollisiondetection

Problem

How do you guys think I can improve the code for collision detection on my website asteroidfield.eu5.org? The current code is

var dx = Math.abs(c1.getcx() - c2.getcx());
var dy = Math.abs(c1.getcy() - c2.getcy());
var dist = Math.sqrt((dx * dx) + (dy * dy));
if (dist - (c1.getR() + c2.getR()) <= 0) {
  if (done === false && invinc !== true) {
    game_over = true;
    done = true;
  }
}


C1 refers to the player sprite, and C2 is the enemy sprite. Getcx is essentially collecting the X location of the edge of what is essentially a collision detection circle, and gety does the same, but collects the Y location. GetR returns the radius of the collision detection circle.

Solution

One thing you can improve on is the getting of the absolute value. In some browsers, bitwise absolute is faster than Math.abs. But it depends on the browser's implementation.

//bitwise absolute
function abs(n){
  return (n^(n>>31))-(n>>31);
}


You could also factor this part out into a variable for readability. The result of this is a boolean. The explanation will be in the next part:

//foo true if less than or equal to 0, false if greater
var foo = dist - (c1.getR() + c2.getR()) <= 0;


Also, in this bit of code, since done and invinc are boolean, there's no point comparing them to true and false. You can use them directly in the condition.

if (done === false && invinc !== true) //when false, and not true (false)

if (!done && !invinc)                  //when not true (false) and not true (false)


In JS, assignment operations "spill left". You can do the following, assigning true to done and "spill" the same value over to game_over.

game_over = done = true;


Also, due to the structure of the code, the previous only happens when our condition assigned to foo is less than or equal to zero or true. So let's modify the condition to this:

if(foo && !done && !invinc) game_over = done = true;


So in the end, your code will look like this:

var dx = Math.abs(c1.getcx() - c2.getcx());
var dy = Math.abs(c1.getcy() - c2.getcy());
var dist = Math.sqrt((dx * dx) + (dy * dy));
var foo = dist - (c1.getR() + c2.getR()) <= 0;

if (foo && !done && !invinc) game_over = done = true;

Code Snippets

//bitwise absolute
function abs(n){
  return (n^(n>>31))-(n>>31);
}
//foo true if less than or equal to 0, false if greater
var foo = dist - (c1.getR() + c2.getR()) <= 0;
if (done === false && invinc !== true) //when false, and not true (false)

if (!done && !invinc)                  //when not true (false) and not true (false)
game_over = done = true;
if(foo && !done && !invinc) game_over = done = true;

Context

StackExchange Code Review Q#26382, answer score: 3

Revisions (0)

No revisions yet.