Making a Game with JavaScript
Tags: flatiron, javascript, rails, gamedev
Published: 2020-05-05 19:31:19

---
title: Making a Game with JavaScript
published: true
description: Making a Game with JavaScript
tags: flatiron, javascript, rails, gamedev
series: Invasion
---

(Note: I'm moving my posts from my time at Flatiron School from my Github to this platform. This blog entry was first posted on March 18, 2020)

For my JavaScript/Rails Single Page Application (SPA) project I made a game called *Invasion!*, about my dog dreaming of battling squirrels in space. The game was made with JavaScript, HTML, and CSS and a backend Rails API to store and fetch player’s names and scores.

For the most part I utilized object orientated design. All of the game objects and sprites (images) are broken into classes. For example, the player, enemies, and bullets are all objects that inherit from `GameObject`. Each `GameObject` has `update()` and `draw()`  methods. Anything pertaining to displaying sprites or text goes in `draw`, and anything that manipulates these things goes into `update`.

Example of game objects inheriting from a GameObject class:

```js
class GameObject {
	static all = [];
	constructor() {
		GameObject.all.push(this);
	}
	
	update() {
		this.checkForCollision();
	}
	
	draw(ctx) {
		const { sourceX, sourceY, sourceWidth, sourceHeight, x, y, width, height, image } = this.spriteObj;
    	ctx.drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, x, y, width, height);
	}
	
	// other methods to check for and handle 
	// collisions, out of bounds, etc ...
}
```

```js
class Player extends GameObject {
	constructor() {
		super();
		// other properties initialized here
	}
	
	update() {
		super.update();
		
		if (this.collided) {
			ExplosionObject.createExplosion(this);
		}
		
		this.move();
		
		// etc...
	}
	
	// no need for a draw method since nothing changes from 
	// the GameObject class
}
```



Upon initialization, each `GameObject` is stored in a static variable array called `all`. This way I was able to handle looping through updates and draws for every existing object at once.

```js
class Game {
	// constructor, other methods, etc...
	
	update() {
		// spawn enemies...
		
		GameObject.all.forEach(obj => obj.update());
		
		if (this.player.isHit) this.gameOver();
	}
	
	 draw() {
    	this.ctx.clearRect(0, 0, GAME_WIDTH, GAME_HEIGHT);

	    if (this.mode === "play") {
      	GameObject.all.forEach(obj => obj.draw(this.ctx));
    	}
  	}
}
```


Sprites were separated into their own classes, depending on whether they were animated or not. My regular sprite class, `SpriteObject` consisted simply of a constructor that took in the source location on the spritesheet and size for the sprite, the (x,y) location and sizes I wanted, and created a `new Image()`. The `AnimatedSpriteObject`, which inherits from `SpriteObject`, is a lot more complicated. Aside from the properties already mentioned, I needed to know how many rows, columns, and frames an animation had. 

A sprite object does not inherit from `GameObject` because the thing the sprite is an image/animation of does. For example, if an enemy squirrel ship appears on screen, a `new enemy()` is created (which inherits from `GameObject`. When it is created a `new SpriteObject()` is created for the enemy and stored as `this.spriteObj` on the enemy instance.

```js
class Enemy extends GameObject {
  constructor(spawnX, speed = 1) {
    super();
    this.spriteObj = new SpriteObject(Enemy.initObj(spawnX));
    this.speed = speed;
  }
}

 static initObj(spawnX) {
    return {
      sourceX: 0,
      sourceY: 176,
      sourceWidth: 218,
      sourceHeight: 169,
      x: spawnX,
      y: -170,
      width: 218 / 2,
      height: 169 / 2
    }
  }
```

Oh, I should mention that I used `requestAnimationFrame` to handle the game looping. `requestAnimationFrame` updates the browser roughly 60 times a second. It works similarly to `setInterval` but performs better for game purposes.

In order to animate, I had to create a delay value and keep track of how many 'ticks' went by. Each 'tick' is a frame per second (fps). If I didn't use a delay then the images would pretty much loop at rapid speed and you would never accurately see the animation. I set my delay to 3; this way it would only update to the next image every 3fps. Then I reset the tickCount to 0 to start over for the next frame.

Animating the sprites turned out to be the most challenging part of this whole project. I spent a lot of time googling and watching YouTube videos before I could get it working properly. If you're interested in knowing more about game development using JavaScript I found this channel to be pretty helpful: [PothOnProgramming](https://www.youtube.com/playlist?list=PLcN6MkgfgN4B8N1Oyo74SQVDO_dsMKALV).

If you'd like to check out *Invasion!* you can do so here: [github](https://github.com/robotspacefish/invasion)