 ## ElasticCollision

Wikipedia: “An elastic collision is a collision in which the total kinetic energy of the colliding bodies after collision is equal to their total kinetic energy before collision.”

In this case ball collision by manipulating DOM elements with CSS animations. This is a basic game mechanic used in many games like Snooker or Hunderds.

Although this tutorial is written in javascript, you should be able to use the same techniques and concepts in almost any development environment. Based on a flash tutorial Managing ball vs ball collision with Flash by Emanuele Feronato.

In the first function we call, we add the balls to the scene. Just creating some DIV elements, give them some properties and push them to an array to access them later on. We also start the render if the last element is added. To keep the DIV elements in style we set some CSS properties like “border-radius”.

```var ballsArray =[];
var maxBalls = 5;

function initBalls()
{
for (var i=0;i<maxBalls;i++)
{
var ball = document.createElement("div");
ball.className ="ball";

//RANDOM START POSITION ON THE SCREEN
ball.left =Math.round(Math.random()*window.innerWidth-30);
ball.top = Math.round(Math.random()*390);
ball.collision = 0;
ball.mass = 1;

//RANDOM START SPEED
ball.xspeed = Math.round(Math.random()*8-4);
ball.yspeed = Math.round(Math.random()*8-4);

document.getElementById('wrapper').appendChild(ball);

ballsArray.push(ball);

if(ballsArray.length == maxBalls){tick();}
}
}```

## move the balls

In this function we loop trough the Array which stores the balls an animate them by changing some CSS properties. First we check if any ball reaches the end of the screen. If so we inverse speed for the x and y direction. Next we get the speed value for the actual ball and apply it to the current position. This function is called in the render tick so it is executed on every frame.

```function moveBall()
{
//for each ball in the array
for (var i=0;i<maxBalls;i++)
{
//Check for a collision with boundaries
if (ballsArray[i].left<0) {ballsArray[i].left = 0;ballsArray[i].xspeed *= -1;}		// BOUNDRIES Left
if (ballsArray[i].left>window.innerWidth-30) {ballsArray[i].left = window.innerWidth-30;ballsArray[i].xspeed *= -1;}	// BOUNDRIES Right
if (ballsArray[i].top<0) {ballsArray[i].top = 0;ballsArray[i].yspeed *= -1;}		// BOUNDRIES Top
if (ballsArray[i].top>window.innerHeight-30) {ballsArray[i].top = innerHeight-30;ballsArray[i].yspeed *= -1;}	// BOUNDRIES Bottom

//GET THE NEW POSITION
ballsArray[i].left += ballsArray[i].xspeed;
ballsArray[i].top += ballsArray[i].yspeed;

//APPLY THE NEW POSITION
//ballsArray[i].style.WebkitTransform = "translate("+ballsArray[i].left+"px,"+ballsArray[i].top+"px)";//2D Transform
ballsArray[i].style.WebkitTransform = "translate3D("+ballsArray[i].left+"px,"+ballsArray[i].top+"px,0px)";//3D Transform fo better Performance?? -> "testing"
ballsArray[i].style.MozTransform = "translate3D("+ballsArray[i].left+"px,"+ballsArray[i].top+"px,0px)";
}
//ball.style.WebkitTransform = "translate("+ball.dx+"px,"+ball.dy+"px)";
}```

## ball collision

There is a whole lot of math in this function. It gets called every time two balls collide together, ball and ball2. If you want to understand how this works, you could read these articles “The Physics of an Elastic Collision”  also “real-world-physics-problems“.

```function manage_bounce(ball, ball2) {
dx = ball.left-ball2.left;
dy = ball.top-ball2.top;
collisionision_angle = Math.atan2(dy, dx);
magnitude_1 = Math.sqrt(ball.xspeed*ball.xspeed+ball.yspeed*ball.yspeed);
magnitude_2 = Math.sqrt(ball2.xspeed*ball2.xspeed+ball2.yspeed*ball2.yspeed);
direction_1 = Math.atan2(ball.yspeed, ball.xspeed);
direction_2 = Math.atan2(ball2.yspeed, ball2.xspeed);
new_xspeed_1 = magnitude_1*Math.cos(direction_1-collisionision_angle);
new_yspeed_1 = magnitude_1*Math.sin(direction_1-collisionision_angle);
new_xspeed_2 = magnitude_2*Math.cos(direction_2-collisionision_angle);
new_yspeed_2 = magnitude_2*Math.sin(direction_2-collisionision_angle);
final_xspeed_1 = ((ball.mass-ball2.mass)*new_xspeed_1+(ball2.mass+ball2.mass)*new_xspeed_2)/(ball.mass+ball2.mass);
final_xspeed_2 = ((ball.mass+ball.mass)*new_xspeed_1+(ball2.mass-ball.mass)*new_xspeed_2)/(ball.mass+ball2.mass);
final_yspeed_1 = new_yspeed_1;
final_yspeed_2 = new_yspeed_2;
ball.xspeed = Math.cos(collisionision_angle)*final_xspeed_1+Math.cos(collisionision_angle+Math.PI/2)*final_yspeed_1;
ball.yspeed = Math.sin(collisionision_angle)*final_xspeed_1+Math.sin(collisionision_angle+Math.PI/2)*final_yspeed_1;
ball2.xspeed = Math.cos(collisionision_angle)*final_xspeed_2+Math.cos(collisionision_angle+Math.PI/2)*final_yspeed_2;
ball2.yspeed = Math.sin(collisionision_angle)*final_xspeed_2+Math.sin(collisionision_angle+Math.PI/2)*final_yspeed_2;
}```

## render tick

This function is called every frame to animate all the Objects on the screen. The function check first if the distance between any balls is greater than the diameter. If not it collides, calls the ball collision function and passes the two colliding balls over. We also call the moveBall & tick function to keep the animation running.

```function tick()
{

for (x=0; x<=maxBalls; x++)
{
for (y=x+1; y<maxBalls; y++)
{
distance_x = Math.abs(ballsArray[x].left-ballsArray[y].left);
distance_y = Math.abs(ballsArray[x].top-ballsArray[y].top);
distance = Math.sqrt(distance_x*distance_x+distance_y*distance_y);

if (distance<=31 && (ballsArray[x].collision == 0 || ballsArray[y].collision == 0))
{
ballsArray[x].collision = 1;
ballsArray[y].collision = 1;
manage_bounce(ballsArray[x], ballsArray[y]);
}
else if (distance>31)
{
ballsArray[x].collision = 0;
ballsArray[y].collision = 0;
}

//window.console.log(distance)
}
}

moveBall();

requestAnimFrame( tick );//RUN THE NEXT TICK
}```

## conclusion

If your game mechanic bases on elastic collision this is a great way of doing it. Full control over the code, light weight, fast and simple.

Posted in gameDev | Tagged #### inkfood

We are experts in creating games and assets of high quality. We create games, websites , mobile apps, tools and any kind of digital entertainment. We also blog occasionally about game development.