HTML Canvas Games from Scratch #4
Hello devs!š®
Let us continue with the gameš¾
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! š
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
So we will follow the order of functionalities given above.
Bullet alien collisionš„:
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!
//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
Location in repository : \Phase 4\BulletCollisions
Try and run this code yourself to see the output.
Healthbarā¤ļø:
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 :
//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 :
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 :
Source Code : Code Link
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:
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
Location in repository : \Phase 4\LevelUp
Backgroundā“ļø:
The game is set in outer space, so whats missing?
Right! Stars!
Lets code this separately first:
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 :
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:
Source Code : Code Link
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 :
Source Code : Code Link
Location in repository : \Phase 4\BackgroundMerged
Its time to wrap it up by calculating the score and handling the game over condition.
Game 0verš:
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:
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:
So we are now ready with the final game:
Source Code : FINAL GAME
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
Play Another Version
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 out!
Do leave suggestion/comments if any.
Cheers!š¬
Written by : Jay Rathodš»
Links : Portfolio | Github | Codepen | Linkedin | Instagram