Complete Guide to Building Games in the Browser
Tags: javascript, gamedev, tutorial, programming
Published: 2021-12-09 03:47:51

Back in the early days when I first started out in web development, I eventually stumbled across __HTML Canvas__, and I was immediately _hooked_. This discovery would prompt me to create many projects, from things like art programs to photo applications, and eventually even _games_.

Often I've been revisiting HTML Canvas, and combining it with some of my newer skills like Node.js. Using the two, I've been able to create full blown online games, and honestly have impressed myself with how much I've improved since I first came across the technology, becoming a kind of "canvas connoisseur" if I do say so myself! 😌

I thought it was about time I shared some of the knowledge I've gained over the years, and figured this was a good way to do it. So, today Im going to share with you my process and methods for __creating games from scratch using HTML Canvas__, showing you everything you need to know to get started building and designing your own!

Since this post will be a little lengthy, heres an overview of all of the topics I'll be covering:

1. [What is HTML Canvas?](#chapter-1)
 * [Getting Started](#chapter-11)
 * [Drawing Graphics](#chapter-12)
2. [Sizing the Game Area](#chapter-2)
 * [Applying a Static Fit](#chapter-21)
 * [Applying a Theator Fit](#chapter-22)
 * [Applying a Fullscreen Fit](#chapter-23)
3. [Creating a Rendering Pipeline](#chapter-3)
4. [Building Sprites](#chapter-4)
 * [Background Sprites](#chapter-41)
 * [Object Sprites](#chapter-42)
 * [Character Sprites](#chapter-43)
5. [Movement and Controls](#chapter-5)
 * [Implementing Joysticks](#chapter-51)
 * [Joystick Movement](#chapter-52)
 * [Keyboard Controls](#chapter-53)
 * [Character Rotation](#chapter-54)
 * [Static vs Dynamic Movement](#chapter-55)
6. [Collision Detection](#chapter-6)
 * [Squares and Rectangles](#chapter-61)
 * [Circles](#chapter-62)
7. [Events](#chapter-7)
8. [Putting it All Together](#chapter-8)


Just as a heads up, Im going to assume you have somewhat strong knowledge of Javascript and the DOM as I go through this guide, so I wont be explaining any syntax or basic concepts, only concepts related to HTML Canvas. Throughout this post I'll be explaining the key concepts used in my personal process, and then lastly in the final chapter I'll show a simple game I've created to showcase those concepts. But with that out of the way, lets get into it! 😎


## What is HTML Canvas? <a name="chapter-1"></a>

The HTML `<canvas>` element, or __Canvas API__ as it's also called, is a special HTML Element used for creating graphics, similar to its counterpart __SVG__ which is also used for creating graphics on the web. Unlike SVG however, HTML Canvas is built for _speed_ and the rendering of graphics programmatically on the fly.

The API consists of the `<canvas>` element, which is used as a container for our graphics, and contains a whole plethora of properties and methods used for drawing things like shapes, images, text, 3d models and more onto it, as well as applying transformation on said elements.

Because its so simple, fast and versatile its applied in a wide range of web applications like games (2D and 3D), video chat, animations, art programs and everything in between. But before we start applying it for _our_ game, let's get into how it works.

### Getting Started <a name="chapter-11"></a>

To get started with HTML Canvas, we'll need to first add it into our HTML. The `<canvas>` element has no children, but text can be added between its tags to serve as the text to be shown to a user in the case that their browser dosen't support Canvas.
```html
<canvas>Sorry, your browser dosen't support HTML Canvas!</canvas>
```
By default, the dimensions of the `<canvas>` element are __300x150__(px), but it can be resized in CSS. Note that this may alter the aspect ratio of the canvas's content, and it may be stretched as a result of resizing, but I'll get more into that later.

To breifly give you an introduction to the use of HTML Canvas (before we jump into the good stuff), I'll quickly go over each of the most important methods and properties you need to know to get started. Before we can render anything however, we first need to get a reference to the canvas's __context__ using the `canvasElement.getContext()` method.
```javascript
// get a reference to our canvas's context
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d"); 
```
The `canvasElement.getContext()` method takes 2 parameters. One is the __context type__, and another is the __context attributes__, however context attributes are irrelevant in our case, and can be ommited. The main two values for the context type are `"2d"` and `"webgl"`.

Passing it a `"2d"` context specifies that we want a 2D rendering context, and `canvasElement.getContext()` will return a `CanvasRenderingContext2D` object, containing properties and methods for rendering 2D graphics onto our canvas. Passing `"webgl"`, will return a `WebGLRenderingContext` object, which contains properties and methods for rendering 3D graphics.

[WebGL](https://webglfundamentals.org/) as you may have heard of before, is a Javascript API for rendering 3D graphics, and is a very popular choice for creating 3D games on the web. The API however is very complex, which is why people usually opt to use libraries like [Three.js](https://threejsfundamentals.org/threejs/lessons/threejs-fundamentals.html) to interact with it. 

In this guide, we'll be using a 2D rendering context which is much simpler, but if you're interested in either Three.js or WebGL, you can check out some of the resources linked at the end of this article.

Anyway, let's take a look at some properties and rendering methods..👇

### Drawing Graphics <a name="chapter-12"></a>

Quickly, lets go over the main rendering methods and properties we'll be using to create our game. If any of these properties or methods dont seem clear, they'll become clearer as we apply them later in this article:

* `beginPath()`: Starts a new "path", which means ties with previous renderings are cut. The path is all of the drawing commands that have been called up untill the current point. If you were to stroke a rectangle using `rect()` and `stroke()`, and then fill a rectangle using `rect()` and `fill()`, the stroked rectangle would get filled as well because both rectangles are part of the same path. Thus when `fill()` is called both rectangles are filled. This method prevents this from ocurring by starting a new path. Later you'll see this in action. 

* `stroke()`: Used to stroke (or line) the current path. Lines and shapes wont be stroked by default, so this should always be called explicitly.

* `fill()`: Used to fill the current path. Lines and shapes wont be filled by default, so this should be always called explicitly.

* `moveTo(x,y)`: Moves the pen (the current coordinates from which to start drawing from) to `x` and `y` coordinates.

* `lineTo(x,y)`: Draws a line form the current pen coordinates to `x`and `y` coordinates. Line wont show unless `stroke()` is used after.

* `rect(x,y,width,height)`: Draws a rectangle whose top left corner is located at `x` and `y`, and whose dimensions are `width` and `height`. Wont show unless `stroke()` or `fill()` are explicitly called after.

* `strokeRect(x,y,width,height)`: Same as `rect()` but strokes (lines) the rectangle in the same function call (no need to call `stroke()` afterwards).

* `fillRect(x,y,width,height)`: Same as `strokeRect()`, but fills the rectangle in the same function call instead of stroking it.

* `clearRect(x,y,width,height)`: Same as `fillRect()`, but fill clear out (erase) the area of space specified. This is often used to clear the canvas for the next frame, as you'll see later.

* `drawImage(image,x,y,width,height)`: Renders a given image (`image`) onto the canvas located at x and y width the given `width` and `height`. Usually an `HTMLImageElement` created through the `Image()` constructor is used as the `image` value.

* `fillText(text,x,y)`: Creates text specified by `text` and `x` and `y`. Settings such as font and text alignment can be set using additional properties, which i wont go over here.

* `arc(x,y,radius,startAngle,endAngle,direction)`: Draws an arc centered at `x` and `y` coordinates, which has a radius of `radius`, starts at the angle `startAngle` and ends at the angle `endAngle` (both given in radians).__To create a circle, set `startAngle` to 0 and `endAngle` to `2*Math.PI`__. `direction` specifies weather the arc is drawn counter clockwise, the default being clockwise.

* `strokeStyle`: This property sets the color which will be used in strokes (lines). Can be any valid CSS color value. The new stroke color will be applied to everything drawn after its been set.

* `fillStyle`: Sets the fill color. The new fill color will be applied to everything drawn after its been set.

* `globalAlpha`: Sets the opacity. The new opacity will be applied to everything drawn after its been set.

These are the principle methods and properties that we'll be using to render our game onto the canvas, and draw each element from backgrounds, to characters and even on-screen controls for mobile users.

To keep this section as short as possible, i've only gone over the essencials. But, theres a _ton_ of additional useful properties and methods you can use to acheive all kinds of stuff (some of which we will see later on). You can explore them [here](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D) if you're interested. 

Don't worry about it if it's hard to visualize any of these, as you'll see them in action further along. Any tips or other relevant information will be explained as this guide progresses. But now that we understand _what_ we're using to create our game and a little about how to use it, let's look at the first step in implementing it.

## Sizing the Game Area <a name="chapter-2"></a>
   
The first step we need to take before drawing any game elements onto our canvas is to determine what kind of sizing we'll use, and how we want the game area to behave on different screen sizes. Before I show the methods I have for doing so, it's important we go over the `width` and `height` attributes of the canvas.

As before mentioned, the default dimensions of the canvas are __300x150__, but this also serves as the default dimensions of the canvas's _content_. Using the `width` and `height` attributes we can change these inner content dimensions, and control how many units the canvas uses for rendering on it's `x` and `y` axis. Below is a further example and explination of how this works:

{% codepen https://codepen.io/ZippCodder/pen/RwZJQLB %}

The canvas dimensions and it's content dimensions can also be set in one go, using it's `width` and `height` attributes in HTML: 

```html
<!-- canvas itself and its content is 300x250 -->
<canvas width="300" height="250">Sorry, your browser dosen't support HTML Canvas!</canvas>
```

What option you choose for sizing will determine how or weather or not you'll use these two attributes. But now that this concept is understood, let me show you what I think are the three best and most common methods for sizing your game. 

### Applying a Static Fit <a name="chapter-21"></a>

A __"Static Fit"__ (for the lack of a better term) is when you apply permanent default dimensions to your canvas, and then simply position it somewhere on your webpage. Generally, this is used for larger screens and desktops where you want other content to be visible without maximizing the game area, or you want to maintain the aspect ratio of the game area and dont care about maximizing it.

For some games, aspect ratio is important because if it's altered, the content of the game could squish or stretch. A good example of a static fit is the online game [Tank Trouble](https://tanktrouble.com/) (one i used to play quite a bit 😊). You can see they've simply positioned their game area onto the page, maintain it's aspect ratio, and keep it minimized as to keep the rest of the webpage content visible.

When applying this type of fit, you'll want to set the default __content dimensions__ of the canvas __once__ and never change them. They should have the same aspect ratio as the __physical canvas dimensions__ in CSS, and whenever you want to scale the canvas, always keep it's aspect ratio and inner dimensions the same.

### Applying a Theator Fit <a name="chapter-22"></a>

The __"theator fit"__ or __"theator mode"__ method, is one of the most common ways used to maximize the size of content which must maintain its aspect ratio. This is when you stretch the height of the content to the full height of the device, and keep the width proporcionate, optionally filling in any gaps with black (or vice-versa, based on the client device dimenisons).

This method is usually applied when the game area has to maintain a certain aspect ratio and you want to maximize it as much as possible without cutting off any of the canvas. I could'nt find a good example in a game, but the Youtube video player serves as a good example. As seen when you try to fullscreen the video, black bars may cover the top or bottom of the video player in order to cover gaps not filled my the video itself.

Below, I show an example and full explination on how you can apply this:

{% codepen https://codepen.io/ZippCodder/pen/ZEJMxyB %}

Notice how the canvas adapts to the viewport changing, that way our game content wont end up stretching or being altered if a user resizes, and always provides the most optimum presentation possible. Similar to a static fit, you should set the content dimensions once and never change them, only changing the canvas's CSS dimensions to scale it, and maintain aspect ratio. It would also be smart to encourage your users to flip their device (if possible) to get as close to the aspect ratio of the game area as possible.

### Applying a Fullscreen Fit <a name="chapter-23"></a>

A __fullscreen__ fit can be simple, or a tad more complicated. It's when you stretch the canvas dimension's (__and it's content dimensions__) to the exact dimensions of the user's device, as to leave no gaps. __When using a fullscreen and theator fit, I would recommend fullscreening the canvas on touchscreen devices via the `HTMLElement.requestFullscreen()` method to lock it in place, because the browser may scroll and move as the player interacts with the screen to play the game__.

 A fullscreen fit should usually only be applied when the dimensions of your game area dont matter, and or the full game area within the canvas dosen't have to be visible. A good example of this is the online game [Narwhale.io](http://narwhale.io/), where the character is centered and the map moves into view naturally.

A small pitfall if this is that the sizing of your game may vary slightly in terms of how much of the map certain clients will see. If your game is drawn on a phone with smaller dimensions than a tablet, the content is drawn using the same amount of units for each rendering (meaning a 2x2 square on the phone is also 2x2 on the tablet), except the tablet uses more units since the canvas's content dimensions will adapt to its larger screen size. __This means that users on larger screens will end up seeing significantly more of the map than users with smaller screens__.

Depending on your game, this may not matter to you, but if it's somthing you care about, I have a solution. I found to get around this was not to use pixels (the default units) as units when sizing renderings, but instead inventing my own _"viewport unit"_ based on the dimensions of the device. __Think of it as using "%" units instead of "px" units in CSS__.
   
When applying this in an online game I had started a while back which used a _fullscreen fit_, it proved very effective at maintaining consistent proporcionality between devices. Below, you can see two screenshots I took, comparing the the size of the game area relative to the screen of my phone, and my tablet.

#### Phone game area (720x1520):
![phone game area](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fsyt7omtfkiidma9owsv.jpg)

#### Tablet game area (1920x1200):
![tablet game area](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j5oewfys49cqwvq6qada.png)

Notice how the elements of the game dont seem smaller on the tablet screen, and the distance between the benches from the edge of the screen is almost the same. Of course, some devices will inevadablely see slightly more or less of the map than others, because of slight differences in aspect ratio, but it's nothing to worry about.

In short, if you use pixel units (the default units) with a fullscreen fit you'll probably see large changes in the sizing of the map between devices (which isn't a problem, if you dont care), but if you use "viewport" units, the sizing of your game will stay consistent. [Here](https://codepen.io/ZippCodder/pen/yLoRGab) I show an example and explination of how to apply these percentage units if you're interested.

On another note, if you're on a touch screen device and you're interested in checking out the unfinished multiplayer game where I took the screenshots from, you can check that out [here](https://zippcodder.github.io/runners/pages/index.html). You can also dig through the [code](https://github.com/ZippCodder/runners/blob/master/src/index.ts) if you'd like to see how I apply some of the techniques I talk about here.

But with all that out of the way, lets finally start building our game, shall we? 👇

## Creating a Rendering Pipeline <a name="chapter-3"></a>

Before creating any characters, objects or backgrounds, we first need to define an order and structure through which each of these entities will be rendered and managed. Since we're building our game from scratch and HTML Canvas provides no kind of framework, we'll have to define ourselves a structure. I call this my __rendering pipeline__.

Generally it'll look like this:

```javascript
// get canvas 2D context object
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

// object for storing globally accessable states
const GLOBALS = {}


// Array where all props will be stored
const PROPS = [];

// Array where all characters will be stored
const CHARS = [];

// function for applying any initial settings
function init() {

}

// function for rendering background elements
function renderBackground() {
 
}

// function for rendering prop objects in PROPS
function renderProps() {

}

// function for rendering character objects in CHARS
function renderCharacters() {

}

// function for rendering onscreen controls 
function renderControls() {

}

// main function to be run for rendering frames
function startFrames() {
// erase entire canvas
ctx.clearRect(0,0,canvas.width,canvas.height);

// render each type of entity in order, relative to layers
renderBackground();
renderProps();
renderCharacters();
renderControls();

// rerun function (call next frame)
window.requestAnimationFrame(startFrames);
}

init(); // initialize game settings
startFrames(); // start running frames
```

This provides us with an orderly process we can use to draw all of the elements of our game. The process goes as follows:

1. We create a container for any states that we want to be accessable globally. For example, if we wanted to create a "pet" that follows our character around, we could store the character's coordinates in our global container, for the pet object to access and use as a relative point to follow.

2. Two arrays are defined, one which will store all objects for props (objects that move or can be interacted with by the user), and another that will store all objects for characters (objects controlled by the user). Objects for props and characters will be created using classes, as we'll see later.

3. An initialization function is defined, which will set any initial states, like setting the canvas's dimensions, colors, fonts, etc. This is typically where you'd put the logic for your initial canvas sizing, like discussed in the previous section, or perhaps register an event listener for adjusting the game area on resize (depending on your prefered sizing method).

4. A function for rendering the backdrop is defined. Here we can either render an image, or separate background elements (more on that later).

5. We create a function which will render each prop in the `PROPS` array.

6. We create a function which will render each character in the `CHARS` array.

7. We create a function which will render onscreen controls (for mobile devices) line buttons and joysticks, as well as any other displays like showing the number of lives.

8. The main function is created. This function when called will begin running frames. It starts by erasing the canvas using `clearRect()`, then calls the render function for each type of entity. If somthing is drawn onto the canvas, and then we draw somthing directly ontop of it, the first rendering will be covered, meaning we'll have to think in layers. Thus, the render function for each type of entity is called in a logical order (background-> objects-> characters-> controls), with the background being on the bottom layer, and the onscreen controls being on the top. The last thing this function dose is run a special method `requestAnimationFrame`. This method takes in a function, which it will run as soon as the browser is ready to render new content, so we pass it `startFrames`. We call it in a loop, so that our frames run indefinitly (note that `requestAnimationFrame` isn't blocking, like if you were to run a `for` loop indefinitely, making the page unresponsive).

9. We call `init` and `startFrames`, to initialize our game, and begin running frames.

Of course, you can personalize this process however you please if you're actively following along, as this is just my personal process and none of this is set in stone (though I'd recommed still using `requestAnimationFrame`). 

The purpose of this section was to explain that you should have some kind of structure for rendering your game, and managing states, animations and user interactions. This is the most important part, as it'll prevent our game from becoming a confusing, clunky mess in the long run.

Hopefully by now the fundamentals have more or less stuck, but now that the scafolding for our game is all set up, we can finally start filling our rendering pipeline with actual backgrounds, objects and characters (etc) to render!

## Building Sprites <a name="chapter-4"></a>

A __"sprite"__ refers to any rendered object or character that can be moved around, interected with, or hold some type of state or animation. Some can be represented as objects, and others with functions, both of which should typically be stored in a separate file, to keep the file where your rendering pipeline lives clean. Usually I split these into three categories:

* Background Sprites
* Object Sprites
* Character Sprites

As implied, they function as a tangible rendered elements of the game, each of which serves a different purpose. Below, I explain exactly the application of these, and how to create each of them.

### Background Sprites <a name="chapter-41"></a>

When creating a background for your game (as we'll dive deeper into later) there are generally two options. The background can be rendered as a single pre-created image, or, it can be rendered as a collection of __"background sprites"__. This can be multiple renderings, or a collection of multiple images. 

Because background elements cant be interected with and hold no state, usually these are created as functions which do nothing but render the sprite, rather than objects with render methods and properties as used in character and object sprites (more on that later). These functions will take in an `x` and `y` coordinate as parameters (optionally any other parameters regarding display as well), and will simply be called inside the `renderBackground()` function of our rendering pipeline.

Heres an example of a simple flower pot sprite ive created:

  {% codepen https://codepen.io/ZippCodder/pen/bGryQeE %}

Here I draw each flower from scratch using rendering methods. If you do this its important that you draw each peice of the sprite relative to the `x` and `y` parameters that are passed into the function. I wouldn't recommend doing this however, as its tedious and using a prepared image generally will look alot better. I'm just using rendering methods to examplify their use.

Again, you can just as easily skip all of the building of the flower yourself, and simply use the `drawImage(x,y)` method to draw a pre-build image or PNG (one that hopefully looks better than my flowers) onto the canvas for a single background sprite, or even skip everything all together and render a single image for the entire background in the `renderBackground()` function.
 

### Object Sprites <a name="chapter-42"></a>

Object sprites are like background sprites, except they usually hold some kind of state (for user interactions), movement or have an animation, and may have access to certain global states in `GLOBALS`, like a ceiling fan, or a door that opens and closes when the user touches it. Usually these are made with classes and objects, which are stored in the `PROPS` array, which is later iterated through to render each object in it, inside the `renderProps()` function.

Classes for object sprites will always carry a `render()` method containing the commands to render the sprite, which will be accessed and called in `renderProps`. Of course you dont have to call it that, but you should have some kind of standard method for rendering each prop. Inside the `render()` method, state can be used to influence how the sprite is displayed. Similar to background sprites, these can also accept an `x` and `y` parameter, and any other additional parameters regarding interaction or display. Below I create animated spikes as an example of a simple object sprite:

{% codepen https://codepen.io/ZippCodder/pen/eYEabvX %}

The movement works because we're constantly changing the coordinates (our state) where the rendering is drawn, and because frames are running indefinitely, any changes we apply to the rendering will be immediately reflected since the sprite is being redrawn with new state repeatedly, which means it's up to us to control timing in animations. Again, my spikes are fairly ugly, and I'm just using render methods to demonstrate their use and prove the concept. You can make your sprites as pretty as you'd like.

This is a good example of the types of elements you should render as object sprites, such as obstacles or things a character can interact with or be affected by. As shown, typically you should make these as a class in which you'll specify its default functionality and give it a `render` method, then simply envoke it whenever you need to place a new object sprite of the same type, keeping our code nice and DRY.

### Character Sprites <a name="chapter-43"></a>

Character sprites function essencially the same as object sprites, accept they usually have state thats controlled by outside factors like keyboard controls or a joystick, and are rendered on a higher layer than objects. Character sprites are created as objects from a standard class which have state and a `render` method, and are added to the `CHARS` array which will be iterated through in `renderCharacters()` to call the render method of each existing character. This can include the player's character as well as other players, like in an online game. 

Though they're similar, it's best to keep them separated, because usually you'll want your characters to be rendered on a higher layer than the objects and background.

In the next section I'll show how you can implement controls with a character sprite, and explain how to create different types of movements in your game like having the character look towards the mouse, making joysticks and using keyboard controls.

## Movement and Controls <a name="chapter-5"></a>

In this section I'll explain and demonstrate how to implement common controls and character movements that you'll typically apply in a 2D game, many of the methods I use to implement which can be used to create other types of controls and movements. Below I explain each one by one, and provide code and an example.

### Implementing Joysticks <a name="chapter-51"></a>

Joysticks are a common type of control used for mobile games and typically have two applications in regards to character actions: 1) __Controlling a character's angle__ 2) __Controlling a character's movement direction__. Apart from display, a joystick's primary purpose is to keep track of each of these, so that we can apply them to whatever entity(s) it's controling. Typically it'll keep it's angle and `x` and `y` direction in `GLOBALS` so that they're accessible to every sprite that needs it.

These properties will allow us to specify certain directions in which sprites will travel on the game area, and the angle at which they're facing. Usually these are applied as character controls, and _dual-joysticks_ are used, __one for the character's angle and one for the character's direction__.

Below I show an example and full explination on how to create a joystick. I've made this example so that you can interact using a mouse or a touchscreen device. Try not to resize to much, as it could break the example:

{% codepen https://codepen.io/ZippCodder/pen/NWvQMmy %}

As you can see iv'e created a class for creating joysticks just like I would've made an object sprite, then __instanciate and render it inside `renderControls()`__. They technically aren't sprites however, because the joystick isn't an element of the game itself. I've rendered it simply as two circles, one serving as the __thumbstick__ and one as the __base__ (again, you can make these peices look however you want).

 Within it's `render` method I added logic to draw the thumbstick towards the user's finger, while keeping it inside of the base (the `distance()` helper function, which measures the distance between two points, aids in this). Using one of the helper functions I've added to `GLOBALS` (`angle()`), the center coordinates of the base and the center coordinates of the thumbstick, Im also able to determine the angle between the two coordinates, and the `x` and `y` offset the thumbstick is from the base (the formula for which will be covered later), which is the information shown above the joystick. __The formula used by `angle()` and `distance()` can be found commented in the above pen.__

> __Note:__ The formula I've used to calculate the angle will output radians, because that's the unit used by the `rotate()` method of the canvas's context. This will be used later to rotate our character.

This information can be kept in `GLOBALS` to later be accessed by our main character sprite, to control it's movements. Another important note to mention is how im giving the joystick class access to the mouse actions through `GLOBALS`, and then implementing it's logic within it's own class instead of inside the event listeners for mouse/touch events. This keeps things much more orderly, rather than cramming the logic of each sprite who needs mouse events inside the same event listeners. This is why inside `init()` I've registered mouse/touch event listeners which when fired just add that information to `GLOBALS` to be globally accessible.

### Joystick Movement <a name="chapter-52"></a>

Below is an example of integrating a joystick with a character sprite to allow movement. Our character sprite is the red circle in the top left corner. Simply use the joystick to move it across the screen with your finger or mouse. Again, try not to resize the window:

{% codepen https://codepen.io/ZippCodder/pen/ExwYpVg %}

Here our character sprite is accessing the `charX` and `charY` properties on `GLOBALS`, which are being continuously updated by and based on our joystick's state. Again, this is better than directly updating our character sprite's coordinates inside of the joystick's class, because if we we're to add more sprites for the joystick to control, we would have to cram a ton of code inside it. Instead, any sprite can simply access the information via `GLOBALS` and keep its implementation within it's own class.

The way this movement works is a bit different than implementing keyboard controls, because our character sprite is moving in very smooth angles rather than simply _up_ or _left_. __Here's how it works__: First we declare `charX` and `charY` onto `GLOBALS`, which serve as the _horizontal_ and _vertical_ amount of units a character will move over time. 

> __Note:__ The way the joystick determines both of these values is by mesuring the `x` and `y` offset of the thumbstick of the joystick from the center of it's base. These are determined by subtracting the base's `x` coordinate from the thumbstick's `x` coordinate to get `charX`, and then subtracting the base's `y` coordinate from the thumbstick's `y` coordinate to get `charY`. You might want to only use a fraction of the result of both of these calculations, like a __10%__, because if the result of calculating `charX` for exmaple is -56.09, your character will be moving alot of units to the left very quickly. You can fraction each of these however (as long as you fraction both the same). It's all about the ratio between the amount of units our character sprite is moving in one direction vs the other overtime, to apply movement at dynamic angles.  

If a user had the joystick positioned at the bottom right (as far as it could go in each direction), this would mean our character would move diagonally downwards to the right. Why? Because since `charX` and `charY` are the same value (__because the width and height of the joystick are equal and thus if the thumbstick is at the bottom right it has equal `x` and `y` offset__) `charX` and `charY` would be set the same, and the character would move _down_ and _right_ at the same rate, causing our character to move __diagonally downwards towards the right__. Hopefully that made sense, but lucky for you implementing keyboard controls is 10x simpler.

### Keyboard Controls <a name="chapter-53"></a>

Unlike joystick controls keyboard movements are much simpler to implement. It's as simple as registering a `keydown` and `keyup` event inside `init()`, and then keeping track of weather or not the __keycodes__ you're listening for are pressed down or released. That information is kept inside `GLOBALS`, where our character sprite has easy access, and depending on weather a key is currently being pressed, the `x` and `y` coordinates of the character sprite will be incremented or decremented by a certain amount (the character sprite's `speed` property).

Below is an example of a character sprite (the red circle) which you can control using the arrow keys:

{% codepen https://codepen.io/ZippCodder/pen/VwMwvjM %}

Simple right? As it's name implies, the `speed` property of the character sprite controls how many units our character will move when it dose, allowing us to control how much ground it covers in each movement. The same can be done with joystick controls by either multiplying `charX` and `charY` to go faster, or dividing them to go slower (__as long as they're multiplied or divided by the same factor__).

### Character Rotation <a name="chapter-54"></a>

In the below example I've made a small rocketship character sprite using the `drawImage()` method. Not only dose it _move_ in the direction of the joystick, but also mimics the _angle_ of the joystick. The joystick's angle is kept in `GLOBALS.roation`, which our character sprite has easy access to for it to rotate that amount.

Below is an example and explination of how to apply rotation to a character sprite:

{% codepen https://codepen.io/ZippCodder/pen/jOGOBxB %}

The key part here is the `angle()` method on `GLOBALS`, which takes in two sets of coordinates and returns the angle between them (in __radians__). __The formula for which is `atan2(y2 - y1, x2 - x1)`__. We use `angle()` to measure the angle between the center of the joystick's thumbstick, and the center of the joystick's base, and then put the result into `GLOBALS.rotation`. This formula (and every other I cover in this post) has a ton of applications when building a game, and you can use it to control rotation with the mouse as well, by mesuring the angle between the mouse coordinates and the center of the screen.

The second primary part which allows this to work is the `rotate()` method of the canvas's context, which is what's used to apply the rotation to the character sprite. __The way this method works is by rotating the canvas from its top left corner by the specified amount of radians__. The rotation only applies to everything drawn __after__ the method is called. Of course this works alot differently than you would expect, but we can normalize it by doing the following:

> We want to rotate the canvas by the center of the thing we want to rotate (our character sprite) rather then the top left corner. The way to do this is by using the `translate(x,y)` method to move the canvas's top left corner to the center coordinates of the thing we want to rotate, rotate our desired amount using `rotate(radians)`, undo the translation (`translate(-x,-y)`), redraw our sprite with the applied canvas rotation, and then call the `resetTransform()` method to __reset the canvas transformations we just did, so that everything drawn after the thing we wanted to rotate dosen't become part of the rotation or translation__. This process can be seen in the render method of our character sprite.
 
You can read more on the `rotate()` and `translate()` methods [here](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/rotate).

### Static vs Dynamic Movement <a name="chapter-55"></a>

In 2D games typically there exists two major types of character movement:

* __Static Movement__: This is when the map is fixed on the game area, and the character moves relative to the map. Like in [Tank Trouble](https://tanktrouble.com/).

* __Dynamic Movement__: This is when the character is fixed to the center of the screen, and the _map_ moves relative to the _character_. Like in [Narwhale.io](http://narwhale.io/).

So far the type of movement I've examplified has all been __static movement__, but in this section I'll give an example and explination on how to apply __dynamic movement__:

{% codepen https://codepen.io/ZippCodder/pen/oNGXZMy %}

See how the "camera" follows our character as the map moves relative to it. The way we do this is by applying the joystick's `x` and `y` offset to coordinates which will serve as a __map anchor__, which our background sprites will be drawn relative to (and of course remove the `charX` and `charY` implementation from our main character sprite).

First what I do is store the joystick's `x` and `y` offset in `GLOBALS.anchorX`and `GLOBALS.anchorY`, and then declare `GLOBALS.mapAnchor` to store the "map anchor" coordinates. Inside `renderBackground()` before rendering each sprite, I update `GLOBALS.mapAnchor.x` and `GLOBALS.mapAnchor.y` by _subtracting_ `GLOBALS.anchorX` from `GLOBALS.mapAnchor.x`, and _subtracting_ `GLOBALS.anchorY` from `GLOBALS.mapAnchor.y`. 

__Here we subtract instead of add like we did in static movement, because the map has to flow the opposite direction from where the character is moving towards.__ Then finally, inside our `Pot()` sprite, I add `GLOBALS.mapAnchor.x` and `GLOBALS.mapAnchor.y` to it's `x` and `y` coordinate, to draw the sprite relative to the current map anchor coordinates.

## Collision Detection <a name="chapter-6"></a>

Collision detection is typically an essencial when it comes to games, weather it's stopping a character from walking through a wall, or killing a character when a bullet hits them.

In this section I'll touch base on basic collision detection, and explain how to detect collision between __squares__, __circles__ and __rectangles__ as well as give examples.

### Squares and Rectangles <a name="chapter-61"></a>

Collision detection is all about __using the dimensions and coordinates of two shapes, to mathematically determine weather or not both are in contact__. Depending on the shapes themselves (square, circle, etc.), the way you'll determine this will vary.

Below I give an example and explination on how to apply collision detection with squares (same exact method can be used with rectangles of any size). Simply drag the pink square into the blue square, and the blue square will turn red when the pink square comes into contact in the following example:

{% codepen https://codepen.io/ZippCodder/pen/poWJprJ %} 

The first thing I did was implement some logic for dragging the pink square. That isn't as relevant but if your interested in how I implemented it just take a look at the code. Next, onto the base class for our squares (which is the one the _blue_ square instanciates) I attach an object inside the constructor called `collisions`. On this object, we'll keep a sub object for every sprite we want to detect collision for, thus, I add `pinkSquare`.

On `pinksquare` (and every other collision object in `collisions`) there exists a `conditions` property which holds __the boolean for mathematically determining contact with the pink square__ (which we're about to dig into), and then an `inContact` property which specifies weather not the sprite is in contact, though here we aren't using this property. This is a good standard to use when implementing collision detection, since its simple and keeps things orderly. 

>__Note:__ `collisions.pinkSquare.conditions` is a _string_ rather than a boolean, so that we can revaluate it constantly with `eval()`, and we dont have to hard code it into `if` statements.

Here is the pseudo-code for determining collision between two rectangles/squares, exactly the same structures as the boolean in `collisions.pinkSquare.conditions`:
```
A = {x: ... y: ..., width: ..., height: ...}
B = {x: ..., y: ..., width: ..., height: ...}

if (A.x + A.width) > B.x 
 and A.x < (B.x + B.width)
 and (A.y + A.height) > B.y
 and A.y < (B.y + B.height) 
...
```
Try visualizing this boolean in action as you read through it, and eventually you'll get the gist.

### Circles <a name="chapter-62"></a>

Determining contact between two circles (_not_ ovals, we'll get to that) is very straight forward and simple to understand. Because Im lazy, just imagine the shapes in the above example I showed are now two circles. The pseudo code for `collisions.pinkCircle.conditions` would be the following, to determine weather the two circles are in contact:
```
A = {x: ..., y: ..., radius: ...}
B = {x: ..., y: ..., radius: ...}

if
 distance between A and B < (A.radius + B.radius) 

...
```

Here, "distance between A and B" refers to the distance between the two points where each circle is centered. If you remember, you determine this with the handy-dandy formula: `√(x2 − x1)^2 + (y2 − y1)^2`. Simple right? 

These two examples are pretty simple, but collision detection with more complex and irregular shapes can require much more advanced methods of determining collisions. Of course here I've only gone over the basics, but if you do plan on implementing collision detection for complex shapes, I highly recommend you check out these resources: 

* [https://www.gamedeveloper.com/programming/advanced-collision-detection-techniques](https://www.gamedeveloper.com/programming/advanced-collision-detection-techniques)
* [https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects](https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects)

## Events <a name="chapter-7"></a>

Keeping track of certain events, such as when a door is opened or when the character is hit in a game is important. This allows us to globally listen for (and trigger) when certain things happen our game no matter what sprite we're in.

Below I've edited the previous example to use events to run two `alert()`s every time the squares are in contact:

{% codepen https://codepen.io/ZippCodder/pen/mdBVLqp %}

Basically the way I've implemented events is exactly how DOM events are implemented, by adding an `addEventListener()` and `dispatchEvent()` method to `GLOBALS`. That way both methods are globally accessible.

`GLOBALS` also includes an `events` property, and each of its sub properties are the name of an existing event which points to an array where callbacks for that event will be stored. I simply call `GLOBALS.addEventListener(name,callback)` to add a callback to the array for the specified event, and then call `dispatchEvent(name)` to call each callback inside the array of the specified event name. And of course we can all new events by adding a new property to `GLOBALS.events`. Easy-peasy! 🍋

Despite how simple it is, I just wanted to clarify that its important that you implement some kind of event system within your game, otherwise you'll be hardcoding alot of stuff, which isn't good practice.

## Putting it All Together <a name="chapter-8"></a>

Finally let me go down the list of each integral concept that makes this process possible. If any of what I explained previously seemed unclear, I recommend you try to examine where and how each concept is implemented within the code to gain a better understanding of how this all functions. Let us first again go down the list of each of the steps of the process:

1. Choose a sizing for the game area (apply it in `init()`)
2. Create your rendering pipeline
3. Fill your rendering pipeline with sprites (in their respective locations depending on the sprite)
4. Apply movement and controls
5. Apply collision detection
6. Integrate events

Each of these concepts can be seen applied in this simple game I've created, named "Drift". The objective is to last as long as possible without being hit by a barrier or leaving the map, steering a car by tapping the left or right half of the game area or using arrow keys. I found it about as frustrating as playing Flappy Bird, my highest score being 33. 

{% codepen https://codepen.io/ZippCodder/pen/PoJNzQz %}

This game greatly examlifies the process and methods I've explained throughout, and hopefully with this guide and example to throw it all together, you'll be equiped with the knowledge to build your own games using HTML Canvas, and the techniques I've gone over in this post. 

I hope you've managed to gain somthing from this article, and if you're still thirsty for more related to game development, definitely checkout the resources below.

Thanks for reading, and happy coding! 👍

* HTML Canvas API - [https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)
* Advanced Collision Detection - [https://www.gamedeveloper.com/programming/advanced-collision-detection-techniques](https://www.gamedeveloper.com/programming/advanced-collision-detection-techniques)
* [https://docs.microsoft.com/en-us/archive/msdn-magazine/2015/march/game-development-a-web-game-in-an-hour](https://docs.microsoft.com/en-us/archive/msdn-magazine/2015/march/game-development-a-web-game-in-an-hour)