6️⃣

# Ch. 6 Collision Detection

## Collision Class

For this class all we need to add a constructor to add values to the constants that we declared at the beginning of the code.
``````class Collision {
constructor(game_obj1, game_obj2) {
this.obj1 = game_obj1;
this.obj2 = game_obj2;
this.has_collided = false;
this.direction = new Vector2d(0, 0); // Direction of penetration
this.magnitude = Number.NEGATIVE_INFINITY; // Shortest distance of penetration
}
}``````

## getSATCollision Function

Uses Separating Axis Test to get the direction and magnitude of any possible collision between given two objects. https://en.wikipedia.org/wiki/Hyperplane_separation_theorem Objects can have any convex shape. Circles are a special case. The next thing that we want to add are 2 functions, these are not in a class because we want the ability use these from anywhere in the code without having a constructor.

To create the function:
``````function getSATCollision(game_obj1, game_obj2) {
// code
}``````

We will add some constants to this function that we will use in some of the if statements.
``````var obj1 = game_obj1;
var obj2 = game_obj2;
let temp_pos1 = obj1.pos.clone();
var d_origins = temp_pos1.subtract(obj2.pos).get_magnitude();
var collision = new Collision(game_obj1, game_obj2);
collision.has_collided = false;
var verts1 = game_obj1.get_verts();
var verts2 = game_obj2.get_verts();
var pos1 = game_obj1.pos.clone();
var pos2 = game_obj2.pos.clone();``````

This first if-statement is for optimization to make the game run smoothly, don’t edit it please.
``````if (d_origins > MAX_DIST_FOR_COLLISIONS * CELL_SIZE) {
// Optimization: Skip further checks for distant objects
return collision;
}``````

We will add a for loop that our code will run though all the if statement if we call this function.
``````for (var i = 0; i < verts1.length + verts2.length; i++) {
// code
}``````

This will calculate next axis by taking the normal of a side of one object
``````if (i < verts1.length) {
var vert = verts1[i];
if (i < verts1.length-1) var next_vert = verts1[i+1];
else var next_vert = verts1;
}
else {
var vert = verts2[i - verts1.length];
if (i < verts1.length+verts2.length-1) var next_vert = verts2[i+1 - verts1.length];
else var next_vert = verts2;
}
var side = next_vert.clone().subtract(vert).get_unit_vector();
var axis = side.get_right_normal();``````

This will get minimum and maximum projections on axis from center of obj1
``````var min_dist1 = verts1.get_dot_product(axis);
var max_dist1 = min_dist1;
for (var j = 1; j < verts1.length; j++) {
var distance = verts1[j].get_dot_product(axis);
if (distance < min_dist1) min_dist1 = distance;
else if (distance > max_dist1) max_dist1 = distance;
}``````

Get minimum and maximum projections on axis from center of obj2
``````var min_dist2 = verts2.get_dot_product(axis);
var max_dist2 = min_dist2;
for (var j = 1; j < verts2.length; j++) {
var distance = verts2[j].get_dot_product(axis);
if (distance < min_dist2) min_dist2 = distance;
else if (distance > max_dist2) max_dist2 = distance;
}``````

This will calculate the distance between objects and flip axis if necessary, and the gaps between objects projected along axis, and the negative gap means that there is a collision on this axis.
``````var d = new Vector2d(pos2.x - pos1.x, pos2.y - pos1.y).get_dot_product(axis);

var gap1 = d - max_dist1 + min_dist2;
var gap2 = - d - max_dist2 + min_dist1;
if (gap1 >= -EPSILON || gap2 >= -EPSILON) {
// No collision on this axis - these objects cannot be colliding!
collision.has_collided = false;
return collision;
}
if (gap1 > gap2 && gap1 > collision.magnitude) {
collision.magnitude = gap1;
collision.direction = axis;
}
if (gap2 > gap1 && gap2 > collision.magnitude) {
collision.magnitude = gap2;
collision.direction = axis.get_inverted();
}
}
collision.has_collided = true;
return collision;
}``````

## GetCollisions Function

Creating the `GetCollisions` function:
``````function GetCollisions(obj) {
// code
}``````

The point of this function is to check collisions given gameobject and all other gameobjects.
``````var ign1 = obj.ignored_collision_objs;
var collisions = [];
for (obj_ind in GAME_OBJECTS) {
var other_obj = GAME_OBJECTS[obj_ind];
var ign2 = other_obj.ignored_collision_objs;
if (ign1.indexOf(other_obj) === -1 && ign2.indexOf(obj) === -1) {
var collision = getSATCollision(obj, other_obj);
if (collision.has_collided === true) {
collisions.push(collision);
}
}
}
return collisions;
}``````

ALL OF CHAPTER SIX CODE https://pastebin.com/CBA5nEgR

## Previous Chapter

5️⃣
Ch. 5 GameObject subclasses

## Next Chapter

7️⃣
Ch. 7 Main Functions

©2023 Code 4 Tomorrow 501(c)(3) Non-Profit (EIN: 92-0635065)