HTML Canvas Games from Scratch #4
Tags: html, javascript, gamedev, physics
Published: 2020-04-22 18:53:02

<img src="https://lh3.googleusercontent.com/proxy/Prm6w3fSFSM_wWl33aS8OY68mLee9Eto-DBG3_EJjWEEmIcUKQZV8j7TgHGLKzAhX9K8GN8l5vHbRrHyJR_fb2TL2XWG1DWZ53a_-77WZrZZ3ulF4ZhGHn4VOz-CO49f" width="700px">
Hello devs!:video_game:
Let us continue with the game:space_invader:
Now we need to implement these functionalities to complete the game: 
- Collide bullets with aliens
- Healthbar for the player
- Respawning of aliens
- Background
- Score calculation and game over

Let's do it! :rocket:

## Phase 4

So we will begin with the code we left last time.
If you don't already have it, you can **download it** from : **[HERE](https://github.com/jrathod9/Making-of-Space-X-/tree/master/Phase%203/Final)**
So we will follow the order of functionalities given above.

### Bullet alien collision:boom:: 
So the alien should die if the bullet touches the alien's body. To do this we will implement a **distance()** function which will take the coordinates of the alien and the bullet in consideration and check if any collisions occur. We will be iterating through the array **Aliens** and the array **Bullets** to check for each pair of {alien , bullet} to check for a collision. Let's code!

```js
//Checking for bullet kill
		for(i=0;i<Bullets.length;i++)
		{
			for(j=0;j<maxAliens;j++)
			{
				if(Math.abs(Bullets[i].x - Aliens[j].x) <= 18 && Bullets[i].y <= Aliens[j].y && Bullets[i].y>=Aliens[j].y-20 && (player.y - Aliens[j].y) >= 38 )
				{
					kills++;
					Bullets[i].y = -10;
					var addAlien = new alien(Math.random()*(window.innerWidth-100)+60, Math.random()*(window.innerHeight/2-300),Math.floor(Math.random()*2));
					Aliens[j] = addAlien;				
				}
			}
		}
``` 
Now let us analyse this code.

We are traversing through both the arrays and checking for **4 conditions** : 
- Absolute distance between bullet and alien in x axis is less than or equal to 18 (as the aliens are almost 36px in width).
- The y coordinate of the bullet is less than the y coordinate of the alien.
- The y coordinate of the bullet is greater than ( alien.y - 20 ).(as the aliens are almost 40px in height)
- The y coordinate of the space shuttle (center) is at least 38px below the aliens center.(this ensures that the alien and space shuttle are not )

If these conditions are satisfied, we :
- Update number of kills (variable **kills++**)
- Send the bullet out of the screen (**y = -10**)
- Add a new alien in place of the dead alien.

Source Code : **[Code Link](https://github.com/jrathod9/Making-of-Space-X-/tree/master/Phase%204/BulletCollisions)**
Location in repository : **\Phase 4\BulletCollisions**
>Try and run this code yourself to see the output.

### Healthbar:heart::

For this we define a new variable called **healthBarHeight**.
So out health bar height will depend on the **health** variable, which is initially valued 90. As the aliens *touch the shuttle*, or the aliens *pass beyond the screen *, the shuttle's health is reduced.
Turning it into code :     

```js
//Drawing the health bar
c.beginPath();
if(health == 90){
	c.fillStyle = "green";
	healthbarHeight = 90*6;
}
else if(health == 60){
	c.fillStyle = "orange";
	healthbarHeight = 60*6;
}	
else if(health == 30){
	c.fillStyle = "red";
	healthbarHeight = 30*6;
}
else{
	healthbarHeight = 0;
}
c.fillRect(20, 20, 20 , healthbarHeight );
c.closePath();
c.fill();
```
>Note : All this is written inside the **draw()** function.

Well we also need to handle the cases where the player loses health. Write this inside the draw() function : 
```js
for( j=0 ; j<Aliens.length ; j++)
{
	if(Math.abs(Aliens[j].y - testShuttle.y) <= 60 && Math.abs(Aliens[j].x - testShuttle.x)<=18 ||  Aliens[j].y >= window.innerHeight -30){	
		health-=30;
		var addAlien = new alien(Math.random()*(window.innerWidth-100)+60, Math.random()*(window.innerHeight/2-300),Math.floor(Math.random()*2));
		Aliens[j] = addAlien;
	}
}
```
Try to check what conditions are handled.
>Note : As soon as any of the conditions are satisfied, we have also killed the alien. Try removing the last 2 lines inside the if statement and then run the code and see the outcome.

The healthbar would looks something like this : 
<center><img src = "https://github.com/jrathod9/Making-of-Space-X-/blob/master/Phase%204/Health/Healthbar.png?raw=true" width="700px"></center> 

Source Code : **[Code Link](https://github.com/jrathod9/Making-of-Space-X-/tree/master/Phase%204/Health)**
Location in repository : **\Phase 4\Health**
>Note : We still need to add the "Game Over" condition. We will do that at the end.

Before moving forward, let us code to increase the difficulty with score.
I.e. as kills increase, so will the speed of the aliens and the number of aliens:
```js
var level = 0; 		//Declare this at the top

//Increase difficulty with kills 
//Add this inside "Checking for bullet kill" after Aliens[j] = addAlien;
if(kills % 10 == 0){
	alienSpeed += 0.1;
}		
if(kills % 20 == 0){
	level++;			
	var levelupAlien = new alien(Math.random()*(window.innerWidth-100)+60, Math.random()*(window.innerHeight/2-300),Math.floor(Math.random()*2));
	Aliens.push(levelupAlien);
	maxAliens++;		
}
```
At every **15 kills** we **add a new alien**, and at every **10 kills** we **increase the speed**. 
Source Code : **[Code Link](https://github.com/jrathod9/Making-of-Space-X-/tree/master/Phase%204/LevelUp)**
Location in repository : **\Phase 4\LevelUp**

### Background:eight_pointed_black_star::

The game is set in outer space, so whats missing?
Right! Stars✨!
Lets code this separately first: 
```js
var maxStars = 150;		//Stars on the screen
var starSpeed = 5;			

//Star object
var star = function(x,y ,rad){
	this.x = x;
	this.y = y;
	this.rad = rad;
}

Stars = new Array();	//Array of stars
 
 //Filling the array 
for(a = 0; a<maxStars ; a++){
	var temp = new star(Math.random()*(window.innerWidth-20), Math.random()*(window.innerHeight-20),Math.random()*3 );
	Stars.push(temp);
}
```
Now we will be drawing these stars, but every time a star leaves the screen we will place it back on the top. Hence it will be like a single screen just repeating itself. 
This is how most of the infinite runner games like temple run and subway surfers take up just a few MB of space. 
So here goes the draw function :
```js
function draw(){	
	//Clear window
	c.clearRect(0,0,window.innerWidth, window.innerHeight);
	//Draw stars
	for(j = 0;j<maxStars ; j++){
		c.beginPath();
		c.fillStyle = 'rgba(255,255,255,0.7)';
		c.arc(Stars[j].x,Stars[j].y,Stars[j].rad , 0 , Math.PI * 2 , false);
		Stars[j].y += starSpeed;
		//This part send the star back to the top
		if(Stars[j].y >= window.innerHeight-20){
			Stars[j].y = 0;
		}
		
		c.closePath();
		c.fill();
	}
	requestAnimationFrame(draw);
}
draw();
```
Result:
<center><img src="https://github.com/jrathod9/Making-of-Space-X-/blob/master/Phase%204/Background/background.gif?raw=true" width="700px"></center>

Source Code : **[Code Link](https://github.com/jrathod9/Making-of-Space-X-/tree/master/Phase%204/Background)**
Location in repository : **\Phase 4\Background**

Now we need to add this to the game . The background will be drawn regardless of what's going on in the game so let us straightaway merge the code in the game code, resulting in :

<center><img src="https://github.com/jrathod9/Making-of-Space-X-/blob/master/Phase%204/BackgroundMerged/GameWithBackground.gif?raw=true" width="700"></center>

Source Code : **[Code Link](https://github.com/jrathod9/Making-of-Space-X-/tree/master/Phase%204/BackgroundMerged)**
Location in repository : **\Phase 4\BackgroundMerged**

Its time to wrap it up by calculating the *score* and handling the *game over* condition. 

### Game 0ver:crossed_flags::
To calculate the score there may be different ways. It totally depends on you how do you want to calculate the score.
I personally feel it is best to check the *Accuracy* and *Level Reached*:
```js
var alive = 1;			//1 alive 0 dead
..
..
function draw(){
	//Enter code to draw Stars
	..
	..
	if(alive)
	{
		//Rest of the game
		..
		..	
		//Check if alien touches shuttle or crosses screen to reduce health
		..	
		..
		if(health == 0)		//Check if health is 0
			alive = 0;
		..
		..
	}
	else
	{	
		//Score screen
		c.beginPath();
		c.fillStyle = 'rgba(255,255,255,0.5)';
		c.font = "30px Calibri";
		c.fillText("GAME OVER!" , (window.innerWidth-20)/2 - 55 , (window.innerHeight-20)/2 - 30);
		c.fillText("Kills : " + kills , (window.innerWidth-20)/2 - 15 , (window.innerHeight-20)/2 );
		c.fillText("Accuracy : " + (kills*100/totalBullets).toFixed(2), (window.innerWidth-20)/2 - 55 , (window.innerHeight-20)/2 + 30);
	}
	requestAnimationFrame();
}
draw();
..
..
``` 
This is how the *game over* screen will look:
 
 <center><img src="https://github.com/jrathod9/Making-of-Space-X-/blob/master/Phase%204/Final/GameOver.png?raw=true" width="700px"></center>

<u>So we are now ready with the final game:</u>
Source Code : **[FINAL GAME](https://github.com/jrathod9/Making-of-Space-X-/tree/master/Phase%204/Final)** 
Location in repository : **\Phase 4\Final**

I've added a flickering effect to the alien as it looks cool. ;)
Enjoy playing and share it with your friends too! You can now experiment with the code to add your own effects, functionalities, audio, video and much more.

[Play This Game](https://jrathod9.github.io/Making-of-Space-X-/)
[Play Another Version](https://jrathod9.github.io/Space-X/)  

Well this is the end of the series. Hope you try and create more such games and visuals on canvas.

If you liked canvas check [THIS](https://github.com/jrathod9/Canvas-Collection) out!
Do leave suggestion/comments if any.
Cheers!:candy: 
<hr>

*Written by* : **Jay Rathod**:computer:
*Links* : [Portfolio](https://jrathod9.github.io/) | [Github](https://github.com/jrathod9) | [Codepen](https://codepen.io/jrathod9) | [Linkedin](https://www.linkedin.com/in/jrathod9/) | [Instagram](https://www.instagram.com/they_say_j/)