Game distribution - Game development

Game distribution
=================

You've followed a tutorial or two and created an HTML game — that's great! This article covers all you need to know about the ways in which you can distribute your newly created game into the wild. This includes hosting it yourself online, submitting it to open marketplaces, and submitting it to closed ones like Google Play or the iOS App Store.

Benefits of HTML over native
----------------------------

Building games with HTML gives you extra advantages, such as:

### Multiplatform bliss

The technology itself is multiplatform, so you can write the code once and target multiple devices. This can range from low-end smartphones or tablets, through laptops and desktop computers, to smart TVs, watches or even a fridge if it can handle a modern enough browser.

You don't need to have separate teams to work on the same title targeting different platforms with only one code base to worry about. You can spend more time and money on Promotion and Monetization.

### Instant updates

You don't have to wait several days to have your game's code updated. If your user finds a bug, you can quickly fix it, update the system and refresh the game on your server to provide players with the updated code almost instantly.

### Direct link distribution and instant play

You don't have to tell people to search for your game in an app store with HTML games. You can just send them a direct URL to access the game, which they can then click to play the game right away without the need to use third party plugins or download and install a large package. Bear in mind that downloading the game might still take a bit of time depending on the size of the game and your network speed. In any case, it's a lot easier to promote the game if you can drive traffic directly where you want it and don't have to jump through lots of hoops to play.

Desktop vs. mobile
------------------

The vast majority of the traffic we are interested in — people playing HTML games — comes from mobile devices so that's something you will have to focus on if you truly want to succeed. Mobile devices are where HTML technology can truly shine and show its advantages. There's no Flash, and HTML is fully multiplatform.

Trying to compete with desktop games directly is very difficult. You can put your HTML games into the same arena (see Native desktop, later on) and you should because it's good to diversify the platforms you support, but you have to remember that developers creating desktop games have years of experience, great tools and stable distribution channels. Many HTML games will target different market segments than native desktop games, e.g. simple time killer games to be played while on the move rather than huge immersive experiences. Such games are often designed to be played with two, or even one finger, so you can hold the device, play the game and be able to use the second hand for whatever you currently need.

Saying this, desktop platforms can be used for distribution quite easily with the availability of wrappers that can help you prepare native builds of your game see Packaging games. It's also nice to provide desktop controls for your games even if you're mostly targeting mobile. Players are enjoying your games on any platform available, and desktop is one of them. Plus, it is usually easier to build and test the game first on desktop, and then move on to debugging mobile.

Publishing the game
-------------------

There are three main options when it comes to publishing a game:

* Self-hosting
* Publishers
* Stores

Remember that the name of your game should be unique enough to be quickly promoted later on, but also catchy enough, so people don't forget it.

### Self-hosting

If you are a front-end developer, you may already know what to do. An HTML game is just another website. You can upload it to a remote server, grab a catchy domain name, and host it yourself.

If you want to make money out of game dev, you should secure your source code one way or another against people who could easily take it and sell it as their own. You can concatenate and minify the code to make it smaller and uglify it so it's a lot harder to reverse engineer your game. Another good measure to take is to provide an online demo if you're planning on packaging it and selling it in a closed store like iTunes or Steam.

If you're working on a side project just for fun, then leaving the source open will benefit those who would like to learn from what you've created. You don't even have to worry about looking for a hosting provider as it's possible to host games on GitHub Pages. You'll get free hosting, version control and possible contributors if your project is interesting enough.

### Publishers and portals

As the name may suggest, publishers can handle the publishing of your game for you. Whether you should go that way or not depends on what your plan is for having your game distributed: Do you want to send it wherever possible, or do you want to restrict its presence to those who've bought an exclusive license? It's up to you. Consider various options, experiment and conclude. Publishers will be explained in more detail in the monetization article.

There are also independent portals collecting interesting games like HTML5Games.com, GameArter.com, MarketJS.com, GameFlare, GameDistribution.com, Poki, or CrazyGames where you can send your game in and it will get some natural promotion because of the big traffic those sites attract. Some of these take your files and host them on their server, whereas others only link to your website or embed your game on their site. Such exposure may just provide promotion for your game, or if you have adverts shown beside your game (or other money making options) it may also provide monetization.

### Web and native stores

You can also upload and publish your game directly to different types of stores, or marketplaces. To do that you'll have to prepare and package it to a build format specific for every app ecosystem you want to target it at. See Marketplaces — distribution platforms for more details of what marketplace types are available.

Marketplaces — Distribution platforms
-------------------------------------

Let's see what the available options are regarding the marketplaces/stores available for different platforms and operating systems.

**Note:** These are the most popular distribution platforms, but this is not to say these are the only options. Instead of trying to add your game to the thousands of others in the iOS store say, you can also try to find a niche and promote directly to the audience who would be interested in your games. Your creativity is critical here.

### Web stores

The best platforms for HTML games are Web-based stores. You can prepare games for web stores by adding a manifest file and other data, such as resources, in a zipped package. Not many modifications of the game itself are required.

* The Chrome Web Store is also an attractive option — again, having a manifest file ready, zipping your game and filling in the online submission form is about all that's required.
### Native mobile stores

When it comes to the mobile market, there's the Apple App Store for iOS, Google Play for Android and all the rest of the competition. Native stores are already filled with established devs selling great games, so you have to be talented and lucky to get noticed.

* The iOS App Store is quite hard to get into as there are strict requirements games have to meet, and you'll have to wait a week or two to get accepted. Plus, it's the most prominent mobile store, with hundreds of thousands of apps, so it's extremely hard to stand out from the crowd.
* Google Play's requirements are less strict, so the store is polluted with low quality games. It's still quite hard to be noticed there as the number of apps submitted daily is huge. It's harder to earn money here too — most of the paid games from iOS are published as free games on Android, with monetization coming from in-app purchases (IAPs) or ads.
* Other stores for native mobile platforms like Windows Phone or Blackberry are working hard to get a piece of the cake, and are way behind the competition. It can be good to submit your game there as it will be a lot easier to be noticed.

If you're looking for more information about the different types of app stores you can check the List of mobile software distribution platforms article on Wikipedia.

### Native desktop

To broaden your audience you can hit the desktop ecosystem with your HTML games too — just remember all the popular AAA games that take most of the market share, and think carefully about whether this suits your strategy. To do the desktop thing properly you should support all three operating systems: Windows, macOS and Linux. The biggest desktop store for games is definitely Steam — indie developers can get on Steam via the Steam Direct program. Remember that you have to deal with the cross-platform issues yourself by uploading separate versions for different platforms.

After you've covered Steam, there's plenty of buzz around initiatives like Humble Bundle where the most popular indie games get presented to a broader audience. It's more like an excellent promotional opportunity than a way to earn a lot of money, however, as the prices paid for the games in a bundle are usually quite low.

Packaging games
---------------

The web is the first and the best choice for HTML games, but if you want to reach a broader audience and distribute your game in a closed ecosystem, you still can do that by packaging it. The good thing is that you don't need a few separate teams working on the same game for different platforms — you can build it once and use tools like Phonegap or CocoonIO to package the game for native stores. The resulting packages are usually pretty reliable, but you should still test them and be on the lookout for small issues or bugs to fix.

### Available tools

There are various tools to choose from depending on your skills, preferred frameworks or target platforms. It's all about picking the best tool for your particular task.

* Ejecta — a tool specifically for packaging games created with the ImpactJS framework for iOS, built by the ImpactJS author. It provides seamless integration with ImpactJS, but it supports only one framework and app store.
* NW.js — formerly known as Node-Webkit, this is the first choice when it comes to building a desktop game that works on Windows, Mac and Linux. The distributions are packaged with the WebKit engine to provide rendering on any platform.

Other alternative tools are:

* Intel XDK — an exciting alternative, similar to CocoonIO.
* Electron — known as Atom Shell — is an open-sourced and cross-platform tool from GitHub.
* Manifold.js — this tool from the Microsoft team can create native distributions of HTML games from iOS, Android, and Windows.
Summary
-------

Distribution is the way to give the world access to your game. There are many options available and there's no single good answer as to which is the best. When you've published the game it's time to focus on promotion — letting people know your game exists. Without promotion, they wouldn't even be able to learn about it and play it.


3D games on the Web - Game development

3D games on the Web
===================

For rich gaming experiences on the web, the weapon of choice is WebGL, which is rendered on HTML `<canvas>`. WebGL is basically an OpenGL ES 2.0 for the Web — it's a JavaScript API providing tools to build rich interactive animations and of course, also games. You can generate and render dynamic 3D graphics with JavaScript that is hardware accelerated.

Documentation and browser support
---------------------------------

The WebGL project documentation and specification is maintained by the Khronos Group, not the W3C as with most of the web APIs. Support on modern browsers is very good, even on mobile, so you don't have to worry about that too much. The main browsers are all supporting WebGL and all you need to focus on is optimizing the performance on the devices you use.

There's an ongoing effort on releasing WebGL 2.0 (based on OpenGL ES 3.0) in the near future, which will bring many improvements and will help developers build games for the modern web using current, powerful hardware.

Explaining the basic 3D theory
------------------------------

The basics of 3D theory centers around shapes represented in a 3D space, with a coordinate system being used to calculate their positions. See our Explaining basic 3D theory article for all the information you need.

Advanced concepts
-----------------

You can do a lot more with WebGL. There are some advanced concepts which you should dive into and learn more about — like shaders, collision detection, or the latest hot topic: virtual reality on the web.

### Shaders

It's worth mentioning shaders, which are a separate story on their own. Shaders use GLSL, a special OpenGL shading language, with syntax similar to C, that is executed directly by the graphics pipeline. They can be split into vertex shaders and fragment shaders (or pixel shaders) — the former transforms shape positions to real 3D drawing coordinates, while the latter computes rendering colors and other attributes. You should definitely check out GLSL Shaders article to learn more about them.

### Collision detection

It's hard to imagine a game without collision detection — we always need to work out when something is hitting something else. We have information available for you to learn from:

* 2D collision detection
* 3D collision detection
### WebXR

The concept of virtual reality is not new, but it's storming onto the web thanks to hardware advancements such as the Meta Quest, and the (currently experimental) WebXR API for capturing information from XR hardware and making it available for use in JavaScript applications. For more, read WebXR — Virtual and Augmented Reality for the Web.

There's also the Building up a basic demo with A-Frame article showing you how easy it is to build 3D environments for virtual reality using the A-Frame framework.

The rise of libraries and frameworks
------------------------------------

Coding raw WebGL is fairly complex, but you'll want to get to grips with it in the long run, as your projects get more advanced (see our WebGL documentation to get started.) For real-world projects you'll probably also make use of a framework to speed up development and help you manage the project you're working on. Using a framework for 3D games also helps optimize the performance as a lot is taken care of by the tools you use, so you can focus on building the game itself.

The most popular JavaScript 3D library is Three.js, a multipurpose tool that makes common 3D techniques simpler to implement. There are other popular game development libraries and frameworks worth checking too; A-Frame, PlayCanvas and Babylon.js are among the most recognizable ones with rich documentation, online editors and active communities.

### Building up a basic demo with A-Frame

A-Frame is a web framework for building 3D and VR experiences. Under the hood, it is a Three.js framework with a declarative entity-component pattern, meaning we can build scenes with just HTML. See the Building up a basic demo with A-Frame subpage for the step-by-step process of creating the demo.

### Building up a basic demo with Babylon.js

Babylon.js is one of the most popular 3D game engines used by developers. As with any other 3D library, it provides built-in functions to help you implement common 3D functionality more quickly. See the Building up a basic demo with Babylon.js subpage for the basics of using Babylon.js, including setting up a development environment, structuring the necessary HTML, and writing the JavaScript code.

### Building up a basic demo with PlayCanvas

PlayCanvas is a popular 3D WebGL game engine open-sourced on GitHub, with an editor available online and good documentation. See the Building up a basic demo with PlayCanvas subpage for higher-level details, and further articles showing how to create demos using the PlayCanvas library, and the online editor.

### Building up a basic demo with Three.js

Three.js, like any other library, gives you a huge advantage: instead of writing hundreds of lines of WebGL code to build anything interesting you can use built-in helper functions to do it a lot easier and faster. See the Building up a basic demo with Three.js subpage for the step-by-step process of creating the demo.

### Other tools

Both Unity and Unreal can export your game to WebGL with asm.js, so you're free to use their tools and techniques to build games that will be exported to the web.

![Illustration of three 3D geometry shapes: a grey torus, a blue cube, and a yellow cylinder.](/en-US/docs/Games/Techniques/3D_on_the_web/shapes.png)

Where to go next
----------------

With this article we just scratched the surface of what's possible with currently available technologies. You can build immersive, beautiful and fast 3D games on the Web using WebGL, and the libraries and frameworks build on top of it.

### Source code

You can find all the source code for this series demos on GitHub.

### APIs

* Canvas API
* WebGL API
* WebVR API
### Frameworks

* Three.js
* PlayCanvas
* Babylon.js
* A-Frame
### Tutorials

* Building up a basic demo with Three.js
* Building up a basic demo with PlayCanvas
* Building up a basic demo with Babylon.js
* Building up a basic demo with A-Frame


Crisp pixel art look with image-rendering - Game development

Crisp pixel art look with image-rendering
=========================================

This article discusses a useful technique for giving your canvas/WebGL games a crisp pixel art look, even on high definition monitors.

The concept
-----------

Retro pixel art aesthetics are getting popular, especially in indie games or game jam entries. But since today's screens render content at high resolutions, there is a problem with making sure the pixel art does not look blurry. Developers have been manually scaling up graphics so they are shown with blocks that represent pixels. Two downsides to this method are larger file sizes and compression artifacts.

|  |  |  |
| --- | --- | --- |
| small pixelated man | small pixelated man | larger pixelated man |
| original size | 4x size | 4x size (scaled with an image editor) |
| none | vendor's algorithm | nearest-neighbor algorithm |

A CSS-based solution
--------------------

The good news is that you can use CSS to automatically do the up-scaling, which not only solves the blur problem, but also allows you to use the images in their original, smaller size, thus saving download time. Also, some game techniques require algorithms that analyze images, which also benefit from working with smaller images.

The CSS property to achieve this scaling is `image-rendering`. The steps to achieve this effect are:

* Create a `<canvas>` element and set its `width` and `height` attributes to the original, smaller resolution.
* Set its CSS `width` and `height` properties to be 2x or 4x the value of the HTML `width` and `height`. If the canvas was created with a 128 pixel width, for example, we would set the CSS `width` to `512px` if we wanted a 4x scale.
* Set the `<canvas>` element's `image-rendering` CSS property to `pixelated`, which does not make the image blurry. There are also the `crisp-edges` and `-webkit-optimize-contrast` values that work on some browsers. Check out the `image-rendering` article for more information on the differences between these values, and which values to use depending on the browser.
An example
----------

Let's have a look at an example. The original image we want to upscale looks like this:

![Pixelated night scenery of a cat on the edge off a cliff with little hearts above his head, behind him a big full moon. With a black background, white text is displayed at the bottom of the image saying: in love with the moon.](/en-US/docs/Games/Techniques/Crisp_pixel_art_look/cat.png)

Here's some HTML to create a simple canvas:

```html
<canvas id="game" width="128" height="128">A cat</canvas>
```

CSS to size the canvas and render a crisp image:

```css
canvas {
  width: 512px;
  height: 512px;
  image-rendering: pixelated;
}
```

And some JavaScript to set up the canvas and load the image:

```js
// Get canvas context
const ctx = document.getElementById("game").getContext("2d");

// Load image
const image = new Image();
image.onload = () => {
  // Draw the image into the canvas
  ctx.drawImage(image, 0, 0);
};
image.src = "cat.png";
```

This code used together produces the following result:

**Note:** Canvas content is not accessible to screen readers. Include descriptive text as the value of the `aria-label` attribute directly on the canvas element itself or include fallback content placed within the opening and closing canvas tag. Canvas content is not part of the DOM, but nested fallback content is.


Tiles and tilemaps overview - Game development

Tiles and tilemaps overview
===========================

Tilemaps are a very popular technique in 2D game development, consisting of building the game world or level map out of small, regular-shaped images called **tiles**. This results in performance and memory usage gains — big image files containing entire level maps are not needed, as they are constructed by small images or image fragments multiple times. This set of articles covers the basics of creating tile maps using JavaScript and Canvas (although the same high level techniques could be used in any programming language.)

Besides the performance gains, tilemaps can also be mapped to a logical grid, which can be used in other ways inside the game logic (for example creating a path-finding graph, or handling collisions) or to create a level editor.

Some popular games that use this technique are *Super Mario Bros*, *Pacman*, *Zelda: Link's Awakening*, *Starcraft*, and *Sim City 2000*. Think about any game that uses regularly repeating squares of background, and you'll probably find it uses tilemaps.

The tile atlas
--------------

The most efficient way to store the tile images is in an atlas or spritesheet. This is all of the required tiles grouped together in a single image file. When it's time to draw a tile, only a small section of this bigger image is rendered on the game canvas. The below images shows a tile atlas of 8 x 4 tiles:

![Tile atlas image](/en-US/docs/Games/Techniques/Tilemaps/tile_atlas.png)

Using an atlas also has the advantage of naturally assigning every tile an **index**. This index is perfect to use as the tile identifier when creating the tilemap object.

The tilemap data structure
--------------------------

It is common to group all the information needed to handle tilemaps into the same data structure or object. These data objects (map object example) should include:

* **Tile size**: The size of each tile in pixels across / pixels down.
* **Image atlas**: The Image atlas that will be used (one or many.)
* **Map dimensions**: The dimensions of the map, either in tiles across / tiles down, or pixels across / pixels down.
* **Visual grid**: Includes indices showing what type of tile should be placed on each position in the grid.
* **Logic grid**: This can be a collision grid, a path-finding grid, etc., depending on the type of game.

**Note:** For the visual grid, a special value (usually a negative number, `0` or `null`) is needed to represent empty tiles.

Square tiles
------------

Square-based tilemaps are the most simple implementation. A more generic case would be rectangular-based tilemaps — instead of square — but they are far less common. Square tiles allow for two **perspectives**:

* Top-down (like many RPG's or strategy games like *Warcraft 2* or *Final Fantasy*'s world view.)
* Side-view (like platformers such as *Super Mario Bros*.)
### Static tilemaps

A tilemap can either fit into the visible screen area screen or be larger. In the first case, the tilemap is **static** — it doesn't need to be scrolled to be fully shown. This case is very common in arcade games like *Pacman*, *Arkanoid*, or *Sokoban*.

Rendering static tilemaps is easy, and can be done with a nested loop iterating over columns and rows. A high-level algorithm could be:

```js
for (let column = 0; column < map.columns; column++) {
  for (let row = 0; row < map.rows; row++) {
    const tile = map.getTile(column, row);
    const x = column \* map.tileSize;
    const y = row \* map.tileSize;
    drawTile(tile, x, y);
  }
}
```

You can read more about this and see an example implementation in Square tilemaps implementation: Static maps.

### Scrolling tilemaps

**Scrolling** tilemaps only show a small portion of the world at a time. They can follow a character — like in platformers or RPGs — or allow the player to control the camera — like in strategy or simulation games.

#### Positioning and camera

In all scrolling games, we need a translation between **world coordinates** (the position where sprites or other elements are located in the level or game world) and **screen coordinates** (the actual position where those elements are rendered on the screen). The world coordinates can be expressed in terms of tile position (row and column of the map) or in pixels across the map, depending on the game. To be able to transform world coordinates into screen coordinates, we need the coordinates of the camera, since they determine which section of the world is being displayed.

Here are examples showing how to translate from world coordinates to screen coordinates and back again:

```js
// these functions assume that the camera points to the top left corner

function worldToScreen(x, y) {
  return { x: x - camera.x, y: y - camera.y };
}

function screenToWorld(x, y) {
  return { x: x + camera.x, y: y + camera.y };
}
```

#### Rendering

A trivial method for rendering would just be to iterate over all the tiles (like in static tilemaps) and draw them, subtracting the camera coordinates (like in the `worldToScreen()` example shown above) and letting the parts that fall outside the view window sit there, hidden. Drawing all the tiles that can not be seen is wasteful, however, and can take a toll on performance. **Only tiles that are at visible should be rendered** ideally — see the Performance section for more ideas on improving rendering performance.

You can read more about implementing scrolling tilemaps and see some example implementations in Square tilemaps implementation: Scrolling maps.

### Layers

The visual grid is often made up of several layers. This allows us to have a richer game world with fewer tiles, since the same image can be used with different backgrounds. For instance, a rock that could appear on top of several terrain types (like grass, sand or brick) could be included on its own separate tile which is then rendered on a new layer, instead of several rock tiles, each with a different background terrain.

If characters or other game sprites are drawn in the middle of the layer stack, this allows for interesting effects such as having characters walking behind trees or buildings.

The following screenshot shows an example of both points: a character appearing *behind* a tile (the knight appearing behind the top of a tree) and a tile (the bush) being rendered over different terrain types.

![A grid of layered background terrains. A bush tile is rendered at the top, over a large grass terrain, and again over a layered rectangular terrain with brown sand at the bottom. A tree tile is rendered over the grass terrain at the bottom left and again at the bottom right. A knight tile appears behind the tree tile that is rendered at the bottom left.](/en-US/docs/Games/Techniques/Tilemaps/screen_shot_2015-10-06_at_15.56.05.png)

### The logic grid

Since tilemaps are an actual grid of visual tiles, it is common to create a mapping between this visual grid and a logic grid. The most common case is to use this logic grid to handle collisions, but other uses are possible as well: character spawning points, detecting whether some elements are placed together in the right way to trigger a certain action (like in *Tetris* or *Bejeweled*), path-finding algorithms, etc.

**Note:** You can take a look at our demo that shows how to use a logic grid to handle collisions.

Isometric tilemaps
------------------

Isometric tilemaps create the illusion of a 3D environment, and are extremely popular in 2D simulation, strategy, or RPG games. Some of these games include *SimCity 2000*, *Pharaoh*, or *Final Fantasy Tactics*. The below image shows an example of an atlas for an isometric tileset.

![A 3x4 map of variously colored tiles in isometric projection](/en-US/docs/Games/Techniques/Tilemaps/iso_tiles.png)

Performance
-----------

Drawing scrolling tile maps can take a toll on performance. Usually, some techniques need to be implemented so scrolling can be smooth. The first approach, as discussed above, is to **only draw tiles that will be visible**. But sometimes, this is not enough.

One simple technique consists of pre-rendering the map in a canvas on its own (when using the Canvas API) or on a texture (when using WebGL), so tiles don't need to be re-drawn every frame and rendering can be done in just one blitting operation. Of course, if the map is large this doesn't really solve the problem — and some systems don't have a very generous limit on how big a texture can be.

One way consists of drawing the section that will be visible off-canvas (instead of the entire map.) That means that as long as there is no scrolling, the map doesn't need to be rendered.

A caveat of that approach is that when there *is* a scrolling, that technique is not very efficient. A better way would be to create a canvas that is 2x2 tiles bigger than the visible area, so there is one tile of "bleeding" around the edges. That means that the map only needs to be redrawn on the canvas when the scrolling has advanced one full tile — instead of every frame — while scrolling.

In fast games that might still not be enough. An alternative method would be to split the tilemap into big sections (like a full map split into 10 x 10 chunks of tiles), pre-render each one off-canvas and then treat each rendered section as a "big tile" in combination with one of the algorithms discussed above.

See also
--------

* Related articles on the MDN:
    + Static square tile maps implementation with Canvas API
    + Scrolling square tile maps implementation with Canvas API
* External resources:
    + Demos and source code
    + Amit's thoughts on grids
    + Isometric graphics in videogames (Wikipedia)


Implementing controls using the Gamepad API - Game development

Implementing controls using the Gamepad API
===========================================

This article looks at implementing an effective, cross-browser control system for web games using the Gamepad API, allowing you to control your web games using console game controllers. It features a case study game — Hungry Fridge, created by Enclave Games.

Controls for web games
----------------------

Historically playing games on a console connected to your TV was always a totally different experience to gaming on the PC, mostly because of the unique controls. Eventually, extra drivers and plugins allowed us to use console gamepads with desktop games — either native games or those running in the browser. Now we have the Gamepad API, which gives us the ability to play browser-based games using gamepad controllers without any plugins. The Gamepad API achieves this by providing an interface exposing button presses and axis changes that can be used inside JavaScript code to handle the input. These are good times for browser gaming.

API status and browser support
------------------------------

The Gamepad API is still at the Working Draft stage in the W3C process, which means its implementation might still change, but saying that the browser support is already quite good. Firefox 29+ and Chrome 35+ support it out of the box. Opera supports the API in version 22+ (not surprising given that they now use Chrome's Blink engine.) And Microsoft implemented support for the API in Edge recently, which means four main browsers now supporting the Gamepad API.

Which gamepads are best?
------------------------

The most popular gamepads right now are those from the Xbox 360, Xbox One, PS3 and PS4 — they have been heavily tested and work well with the Gamepad API implementation in browsers across Windows and macOS.

There's also a number of other devices with various different button layouts that more or less work across browser implementations. The code discussed in this article was tested with a few gamepads, but the author's favorite configuration is a wireless Xbox 360 controller and the Firefox browser on macOS.

Case Study: Hungry Fridge
-------------------------

The GitHub Game Off II competition ran in November 2013 and Enclave Games decided to take part in it. The theme for the competition was "change", so they submitted a game where you have to feed the Hungry Fridge by tapping the healthy food (apples, carrots, lettuces) and avoid the "bad" food (beer, burgers, pizza.) A countdown changes the type of food the Fridge wants to eat every few seconds, so you have to be careful and act quickly.

The second, hidden "change" implementation is the ability to transform the static Fridge into a full-blown moving, shooting and eating machine. When you connect the controller, the game significantly changes (Hungry Fridge turns into the Super Turbo Hungry Fridge) and you're able to control the armored fridge using the Gamepad API. You have to shoot down the food, but once again you also have to find the type of food the Fridge wants to eat at each point, or else you'll lose energy.

The game encapsulates two totally different types of "change" — good food vs. bad food, and mobile vs. desktop.

Demo
----

The full version of the Hungry Fridge game was built first, and then to showcase the Gamepad API in action and show the JavaScript source code, a simple demo was created. It's part of the Gamepad API Content Kit available on GitHub where you can dive deep into the code and study exactly how it works.

The code explained below is from the full version of the Hungry Fridge game, but it's almost identical to the one from the demo — the only difference is that the full version uses the `turbo` variable to decide whether the game will be launched using Super Turbo mode. It works independently, so it could be turned on even if the gamepad is not connected.

**Note:** Easter Egg time: There's a hidden option to launch Super Turbo Hungry Fridge on the desktop without having a gamepad connected — click the gamepad icon in the top right corner of the screen. It will launch the game in the Super Turbo mode and you'll be able to control the Fridge with the keyboard: A and D for turning the turret left and right, W for shooting and arrow keys for movement.

Implementation
--------------

There are two important events to use along with the Gamepad API — `gamepadconnected` and `gamepaddisconnected`. The first one is fired when the browser detects the connection of a new gamepad while the second one is fired when a gamepad is disconnected (either physically by the user or due to inactivity.) In the demo, the `gamepadAPI` object is used to store everything related to the API:

```js
const gamepadAPI = {
  controller: {},
  turbo: false,
  connect() {},
  disconnect() {},
  update() {},
  buttonPressed() {},
  buttons: [],
  buttonsCache: [],
  buttonsStatus: [],
  axesStatus: [],
};
```

The `buttons` array contains the Xbox 360 button layout:

```js
buttons: [
  'DPad-Up','DPad-Down','DPad-Left','DPad-Right',
  'Start','Back','Axis-Left','Axis-Right',
  'LB','RB','Power','A','B','X','Y',
],
```

This can be different for other types of gamepads like the PS3 controller (or a no-name, generic one), so you have to be careful and not just assume the button you're expecting will be the same button you'll actually get. Next, we set up two event listeners to get the data:

```js
window.addEventListener("gamepadconnected", gamepadAPI.connect);
window.addEventListener("gamepaddisconnected", gamepadAPI.disconnect);
```

Due to security policy, you have to interact with the controller first while the page is visible for the event to fire. If the API worked without any interaction from the user it could be used to fingerprint them without their knowledge.

Both functions are fairly simple:

```js
connect(evt) {
  gamepadAPI.controller = evt.gamepad;
  gamepadAPI.turbo = true;
  console.log('Gamepad connected.');
},
```

The `connect()` function takes the event as a parameter and assigns the `gamepad` object to the `gamepadAPI.controller` variable. We are using only one gamepad for this game, so it's a single object instead of an array of gamepads. We then set the `turbo` property to `true`. (We could use the `gamepad.connected` boolean for this purpose, but we wanted to have a separate variable for turning on Turbo mode without needing to have a gamepad connected, for reasons explained above.)

```js
disconnect(evt) {
  gamepadAPI.turbo = false;
  delete gamepadAPI.controller;
  console.log('Gamepad disconnected.');
},
```

The `disconnect` function sets the `gamepad.turbo property` to `false` and removes the variable containing the gamepad object.

### Gamepad object

There's lots of useful information contained in the `gamepad` object, with the states of buttons and axes being the most important:

* `id`: A string containing information about the controller.
* `index`: A unique identifier for the connected device.
* `connected`: A boolean variable, `true` if the device is connected.
* `mapping`: The layout type of the buttons; `standard` is the only available option for now.
* `axes`: The state of each axis, represented by an array of floating-point values.
* `buttons` : The state of each button, represented by an array of `GamepadButton` objects containing `pressed` and `value` properties.

The `index` variable is useful if we're connecting more than one controller and want to identify them to act accordingly — for example when we have a two-player game requiring two devices to be connected.

### Querying the gamepad object

Beside `connect()` and `disconnect()`, there are two more methods in the `gamepadAPI` object: `update()` and `buttonPressed()`. `update()` is executed on every frame inside the game loop, to update the actual status of the gamepad object regularly:

```js
update() {
  // Clear the buttons cache
  gamepadAPI.buttonsCache = [];

  // Move the buttons status from the previous frame to the cache
  for (let k = 0; k < gamepadAPI.buttonsStatus.length; k++) {
    gamepadAPI.buttonsCache[k] = gamepadAPI.buttonsStatus[k];
  }

  // Clear the buttons status
  gamepadAPI.buttonsStatus = [];

  // Get the gamepad object
  const c = gamepadAPI.controller || {};

  // Loop through buttons and push the pressed ones to the array
  const pressed = [];
  if (c.buttons) {
    for (let b = 0; b < c.buttons.length; b++) {
      if (c.buttons[b].pressed) {
        pressed.push(gamepadAPI.buttons[b]);
      }
    }
  }

  // Loop through axes and push their values to the array
  const axes = [];
  if (c.axes) {
    for (let a = 0; a < c.axes.length; a++) {
      axes.push(c.axes[a].toFixed(2));
    }
  }

  // Assign received values
  gamepadAPI.axesStatus = axes;
  gamepadAPI.buttonsStatus = pressed;

  // Return buttons for debugging purposes
  return pressed;
},
```

On every frame, `update()` saves buttons pressed during the previous frame to the `buttonsCache` array and takes fresh ones from the `gamepadAPI.controller` object. Then it loops through buttons and axes to get their actual states and values.

### Detecting button presses

The `buttonPressed()` method is also placed in the main game loop to listen for button presses. It takes two parameters — the button we want to listen to and the (optional) way to tell the game that holding the button is accepted. Without it you'd have to release the button and press it again to have the desired effect.

```js
buttonPressed(button, hold) {
  let newPress = false;

  // Loop through pressed buttons
  for (let i = 0; i < gamepadAPI.buttonsStatus.length; i++) {
    // If we found the button we're looking for
    if (gamepadAPI.buttonsStatus[i] === button) {
      // Set the boolean variable to true
      newPress = true;

      // If we want to check the single press
      if (!hold) {
        // Loop through the cached states from the previous frame
        for (let j = 0; j < gamepadAPI.buttonsCache.length; j++) {
          // If the button was already pressed, ignore new press
          newPress = (gamepadAPI.buttonsCache[j] !== button);
        }
      }
    }
  }
  return newPress;
},
```

There are two types of action to consider for a button: a single press and a hold. The `newPress` boolean variable will indicate whether there's a new press of a button or not. Next, we loop through the array of pressed buttons — if the given button is the same as the one we're looking for, the `newPress` variable is set to `true`. To check if the press is a new one, so the player is not holding the key, we loop through the cached states of the buttons from the previous frame of the game loop. If we find it there it means that the button is being held, so there's no new press. In the end the `newPress` variable is returned. The `buttonPressed` function is used in the update loop of the game like this:

```js
if (gamepadAPI.turbo) {
  if (gamepadAPI.buttonPressed("A", "hold")) {
    this.turbo\_fire();
  }
  if (gamepadAPI.buttonPressed("B")) {
    this.managePause();
  }
}
```

If `gamepadAPI.turbo` is `true` and the given buttons are pressed (or held), we execute the proper functions assigned to them. In this case, pressing or holding `A` will fire the bullet and pressing `B` will pause the game.

### Axis threshold

The buttons have only two states: `0` or `1`, but the analog sticks can have many values — they have a float range between `-1` and `1` along both the `X` and `Y` axes.

Gamepads can get dusty from lying around inactive, meaning that checking for exact -1 or 1 values can be a problem. For this reason, it can be good to set a threshold for the value of the axis to take effect. For example, the Fridge tank will turn right only when the `X` value is bigger than `0.5`:

```js
if (gamepadAPI.axesStatus[0].x > 0.5) {
  this.player.angle += 3;
  this.turret.angle += 3;
}
```

Even if we move it a little by mistake or the stick doesn't make it back to its original position, the tank won't turn unexpectedly.

Specification update
--------------------

After more than a year of stability, in April 2015 the W3C Gamepad API spec was updated (see the latest.) It hasn't changed much, but it's good to know what is going on — the updates are as follows.

### Getting the gamepads

The `Navigator.getGamepads()` method has been updated with a longer explanation and an example piece of code. Now the length of the array of gamepads has to be `n+1` where `n` is the number of connected devices — when there's one device connected and it has the index of 1, the array's length is 2 and it will look like this: `[null, [object Gamepad]]`. If the device is disconnected or unavailable, the value for it is set to `null`.

### Mapping standard

The mapping type is now an enumerable object instead of a string:

```ts
enum GamepadMappingType {
  "",
  "standard",
}
```

This enum defines the set of known mappings for a Gamepad. For now, there's only the `standard` layout available, but new ones may appear in the future. If the layout is unknown, it is set to an empty string.

### Events

There were more events available in the spec than just `gamepadconnected` and `gamepaddisconnected` available, but they were removed from the specification as they were thought to not be very useful. The discussion is still ongoing whether they should be put back, and in what form.

Summary
-------

The Gamepad API is very easy to develop with. Now it's easier than ever to deliver a console-like experience to the browser without the need for any plugins. You can play the full version of the Hungry Fridge game directly in your browser. Check the other resources on the Gamepad API Content Kit.


2D collision detection - Game development

2D collision detection
======================

Algorithms to detect collision in 2D games depend on the type of shapes that can collide (e.g. Rectangle to Rectangle, Rectangle to Circle, Circle to Circle). Generally you will have a simple generic shape that covers the entity known as a "hitbox" so even though collision may not be pixel perfect, it will look good enough and be performant across multiple entities. This article provides a review of the most common techniques used to provide collision detection in 2D games.

Axis-Aligned Bounding Box
-------------------------

One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.
```

<div id="cr-stage"></div>
<p>
  Move the rectangle with arrow keys. Green means collision, blue means no
  collision.
</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.5.4/crafty-min.js"></script>
```

```js
Crafty.init(200, 200);

const dim1 = { x: 5, y: 5, w: 50, h: 50 };
const dim2 = { x: 20, y: 10, w: 60, h: 40 };

const rect1 = Crafty.e("2D, Canvas, Color").attr(dim1).color("red");

const rect2 = Crafty.e("2D, Canvas, Color, Keyboard, Fourway")
  .fourway(2)
  .attr(dim2)
  .color("blue");

rect2.bind("EnterFrame", function () {
  if (
    rect1.x < rect2.x + rect2.w &&
    rect1.x + rect1.w > rect2.x &&
    rect1.y < rect2.y + rect2.h &&
    rect1.y + rect1.h > rect2.y
  ) {
    // Collision detected!
    this.color("green");
  } else {
    // No collision
    this.color("blue");
  }
});
```

**Note:** Another example without Canvas or external libraries.

Circle Collision
----------------

Another simple shape for collision detection is between two circles. This algorithm works by taking the center points of the two circles and ensuring the distance between the center points are less than the two radii added together.
```

<div id="cr-stage"></div>
<p>
  Move the circle with arrow keys. Green means collision, blue means no
  collision.
</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.5.4/crafty-min.js"></script>
```

```
#cr-stage {
  position: static !important;
  height: 200px !important;
}
```

```js
Crafty.init(200, 200);

const dim1 = { x: 5, y: 5 };
const dim2 = { x: 20, y: 20 };

Crafty.c("Circle", {
  circle(radius, color) {
    this.radius = radius;
    this.w = this.h = radius \* 2;
    this.color = color || "#000000";

    this.bind("Move", Crafty.DrawManager.drawAll);
    return this;
  },

  draw() {
    const ctx = Crafty.canvas.context;
    ctx.save();
    ctx.fillStyle = this.color;
    ctx.beginPath();
    ctx.arc(
      this.x + this.radius,
      this.y + this.radius,
      this.radius,
      0,
      Math.PI \* 2,
    );
    ctx.closePath();
    ctx.fill();
    ctx.restore();
  },
});

const circle1 = Crafty.e("2D, Canvas, Circle").attr(dim1).circle(15, "red");

const circle2 = Crafty.e("2D, Canvas, Circle, Fourway")
  .fourway(2)
  .attr(dim2)
  .circle(20, "blue");

circle2.bind("EnterFrame", function () {
  const dx = circle1.x - circle2.x;
  const dy = circle1.y - circle2.y;
  const distance = Math.sqrt(dx \* dx + dy \* dy);

  const colliding = distance < circle1.radius + circle2.radius;
  this.color = colliding ? "green" : "blue";
});
```

**Note:** Here is another example without Canvas or external libraries.

Separating Axis Theorem
-----------------------

This is a collision algorithm that can detect a collision between any two *convex* polygons. It's more complicated to implement than the above methods but is more powerful. The complexity of an algorithm like this means we will need to consider performance optimization, covered in the next section.

Implementing SAT is out of scope for this page so see the recommended tutorials below:

1. Separating Axis Theorem (SAT) explanation
2. Collision detection and response
3. Collision detection Using the Separating Axis Theorem
4. SAT (Separating Axis Theorem)
5. Separating Axis Theorem
Collision Performance
---------------------

While some of these algorithms for collision detection are simple enough to calculate, it can be a waste of cycles to test *every* entity with every other entity. Usually games will split collision into two phases, broad and narrow.

### Broad Phase

Broad phase should give you a list of entities that *could* be colliding. This can be implemented with a spacial data structure that will give you a rough idea of where the entity exists and what exist around it. Some examples of spacial data structures are Quad Trees, R-Trees or a Spacial Hashmap.

### Narrow Phase

When you have a small list of entities to check you will want to use a narrow phase algorithm (like the ones listed above) to provide a certain answer as to whether there is a collision or not.


Async scripts for asm.js - Game development

Async scripts for asm.js
========================

Every medium or large game should compile asm.js code as part of an async script to give the browser the maximum flexibility to optimize the compilation process. In Gecko, async compilation allows the JavaScript engine to compile the asm.js off the main thread when the game is loading and cache the generated machine code so that the game doesn't need to be compiled on subsequent loads (starting in Firefox 28). To see the difference, toggle `javascript.options.parallel_parsing` in `about:config`.

Putting async into action
-------------------------

Getting async compilation is easy: when writing your JavaScript, just use the `async` attribute like so:

```html
<script async src="file.js"></script>
```

or, to do the same thing via script:

```js
const script = document.createElement("script");
script.src = "file.js";
document.body.appendChild(script);
```

(Scripts created from script default to `async`.) The default HTML shell Emscripten generates produces the latter.

When is async not async?
------------------------

Two common situations in which a script is \*not\* async (as defined by the HTML spec) are:

```html
<script async>
 code();
</script>
```

and

```js
const script = document.createElement("script");
script.textContent = "code()";
document.body.appendChild(script);
```

Both are counted as 'inline' scripts and get compiled and then run immediately.

What if your code is in a JS string? Instead of using `eval` or `innerHTML`, both of which trigger synchronous compilation, you should use a Blob with an object URL:

```js
const blob = new Blob([codeString]);
const script = document.createElement("script");
const url = URL.createObjectURL(blob);
script.onload = script.onerror = () => URL.revokeObjectURL(url);
script.src = url;
document.body.appendChild(script);
```

The setting of `src` rather than `innerHTML` is what makes this script async.


Audio for Web games - Game development

Audio for Web games
===================

Audio is an important part of any game; it adds feedback and atmosphere. Web-based audio is maturing fast, but there are still many browser differences to navigate. We often need to decide which audio parts are essential to our games' experience and which are nice to have but not essential, and devise a strategy accordingly. This article provides a detailed guide to implementing audio for web games, looking at what works currently across as wide a range of platforms as possible.

Mobile audio caveats
--------------------

By far the most difficult platforms to provide web audio support for are mobile platforms. Unfortunately these are also the platforms that people often use to play games. There are a couple of differences between desktop and mobile browsers that may have caused browser vendors to make choices that can make web audio difficult for game developers to work with. Let's look at these now.

### Autoplay

Browser autoplay policy now affects desktop *and* mobile browsers. There is further information about it here from the Google Developers site.

It is worth noting that autoplay with sound is allowed if:

* the User has interacted with the domain.
* on mobile the user has made the application installable.

Many browsers will ignore any requests made by your game to automatically play audio; instead playback for audio needs to be started by a user-initiated event, such as a click or tap. This means you will have to structure your audio playback to take account of that. This is usually mitigated against by loading the audio in advance and priming it on a user-initiated event.

For more passive audio autoplay, for example background music that starts as soon as a game loads, one trick is to detect *any* user initiated event and start playback then. For other more active sounds that are to be used during the game we could consider priming them as soon as something like a *Start* button is pressed.

To prime audio like this we want to play a part of it; for this reason it is useful to include a moment of silence at the end of your audio sample. Jumping to, playing, and then pausing that silence will mean we can now use JavaScript to play that file at arbitrary points. You can find out more about best practices with the autoplay policy here.

**Note:** Playing part of your file at zero volume could also work if the browser allows you to change volume (see below). Also note that playing and immediately pausing your audio does not guarantee that a small piece of audio won't be played.

**Note:** Adding a web app to your mobile's homescreen may change its capabilities. In the case of autoplay on iOS, this appears to be the case currently. If possible, you should try your code on several devices and platforms to see how it works.

### Volume

Programmatic volume control may be disabled in mobile browsers. The reason often given is that the user should be in control of the volume at the OS level and this shouldn't be overridden.

### Buffering and preloading

Likely as an attempt to mitigate runaway mobile network data use, we also often find that buffering is disabled before playback has been initiated. Buffering is the process of the browser downloading the media in advance, which we often need to do to ensure smooth playback.

The `HTMLMediaElement` interface comes with lots of properties to help determine whether a track is in a state to be playable.

**Note:** In many ways the concept of buffering is an outdated one. As long as byte-range requests are accepted (which is the default behavior), we should be able to jump to a specific point in the audio without having to download the preceding content. However, preloading is still useful — without it, there would always need to be some client-server communication required before playing can commence.

### Concurrent audio playback

A requirement of many games is the need to play more than one piece of audio at the same time; for example, there might be background music playing along with sound effects for various things happening in the game. Although the situation is soon going to get better with the adoption of the Web Audio API, the current most widely-supported method — using the vanilla `<audio>` element — leads to patchy results on mobile devices.

### Testing and support

Here's a table that shows what mobile platforms support the features talked about above.

Mobile support for web audio features| Mobile browser | Version | Concurrent play | Autoplay | Volume adjusting | Preload |
| --- | --- | --- | --- | --- | --- |
| Chrome (Android) | 69+ | Y | Y | Y | Y |
| Firefox (Android) | 62+ | Y | Y | Y | Y |
| Edge Mobile |  | Y | Y | Y | Y |
| Opera Mobile | 46+ | Y | Y | Y | Y |
| Safari (iOS) | 7+ | Y/N\* | N | N | Y |
| Android Browser | 67+ | Y | Y | Y | Y |

There's a full compatibility chart for mobile and desktop HTMLMediaElement support here.

**Note:** Concurrent audio playback is tested using our concurrent audio test example, where we attempt to play three pieces of audio at the same time using the standard audio API.

**Note:** Simple autoplay functionality is tested with our autoplay test example.

**Note:** Volume changeability is tested with our volume test example.

Mobile workarounds
------------------

Although mobile browsers can present problems, there are ways to work around the issues detailed above.

### Audio sprites

Audio sprites borrow their name from CSS sprites, which is a visual technique for using CSS with a single graphic resource to break it into a series of sprites. We can apply the same principle to audio so that rather than having a bunch of small audio files that take time to load and play, we have one larger audio file containing all the smaller audio snippets we need. To play a specific sound from the file, we just use the known start and stop times for each audio sprite.

The advantage is that we can prime one piece of audio and have our sprites ready to go. To do this we can just play and instantly pause the larger piece of audio. You'll also reduce the number of server requests and save bandwidth.

```js
const myAudio = document.createElement("audio");
myAudio.src = "mysprite.mp3";
myAudio.play();
myAudio.pause();
```

You'll need to sample the current time to know when to stop. If you space your individual sounds by at least 500ms then using the `timeUpdate` event (which fires every 250ms) should be sufficient. Your files may be slightly longer than they strictly need to be, but silence compresses well.

Here's an example of an audio sprite player — first let's set up the user interface in HTML:

```html
<audio id="myAudio" src="http://jPlayer.org/tmp/countdown.mp3"></audio>
<button data-start="18" data-stop="19">0</button>
<button data-start="16" data-stop="17">1</button>
<button data-start="14" data-stop="15">2</button>
<button data-start="12" data-stop="13">3</button>
<button data-start="10" data-stop="11">4</button>
<button data-start="8" data-stop="9">5</button>
<button data-start="6" data-stop="7">6</button>
<button data-start="4" data-stop="5">7</button>
<button data-start="2" data-stop="3">8</button>
<button data-start="0" data-stop="1">9</button>
```

Now we have buttons with start and stop times in seconds. The "countdown.mp3" MP3 file consists of a number being spoken every 2 seconds, the idea being that we play back that number when the corresponding button is pressed.

Let's add some JavaScript to make this work:

```js
const myAudio = document.getElementById("myAudio");
const buttons = document.getElementsByTagName("button");
let stopTime = 0;

for (const button of buttons) {
  button.addEventListener(
    "click",
    () => {
      myAudio.currentTime = button.getAttribute("data-start");
      stopTime = button.getAttribute("data-stop");
      myAudio.play();
    },
    false,
  );
}

myAudio.addEventListener(
  "timeupdate",
  () => {
    if (myAudio.currentTime > stopTime) {
      myAudio.pause();
    }
  },
  false,
);
```

**Note:** You can try out our audio sprite player live on JSFiddle.

**Note:** On mobile we may need to trigger this code from a user-initiated event such as a start button being pressed, as described above.

**Note:** Watch out for bit rates. Encoding your audio at lower bit rates means smaller file sizes but lower seeking accuracy.

### Background music

Music in games can have a powerful emotional effect. You can mix and match various music samples and assuming you can control the volume of your audio element you could cross-fade different musical pieces. Using the `playbackRate()` method you can even adjust the speed of your music without affecting the pitch, to sync it up better with the action.

All this is possible using the standard `<audio>` element and associated `HTMLMediaElement`, but it becomes much easier and more flexible with the more advanced Web Audio API. Let's look at this next.

### Web Audio API for games

The Web Audio API is supported across all modern desktop and mobile browsers, except for Opera Mini. With that in mind, it's an acceptable approach for many situations to use the Web Audio API (see the Can I use Web Audio API page for more on browser compatibility). The Web Audio API is an advanced audio JavaScript API that is ideal for game audio. Developers can generate audio and manipulate audio samples as well as positioning sound in 3D game space.

A feasible cross-browser strategy would be to provide basic audio using the standard `<audio>` element and, where supported, enhance the experience using the Web Audio API.

**Note:** Significantly, iOS Safari now supports the Web Audio API, which means it's now possible to write web-based games with native-quality audio for iOS.

As the Web Audio API allows precise timing and control of audio playback, we can use it to play samples at specific moments, which is a crucial immersive aspect of gaming. You want those explosions to be accompanied by a thundering boom, not followed by one, after all.

### Background music with the Web Audio API

Although we can use the `<audio>` element to deliver linear background music that doesn't change in reaction to the game environment, the Web Audio API is ideal for implementing a more dynamic musical experience. You may want music to change depending on whether you are trying to build suspense or encourage the player in some way. Music is an important part of the gaming experience and depending on the type of game you are making you may wish to invest significant effort into getting it right.

One way you can make your music soundtrack more dynamic is by splitting it up into component loops or tracks. This is often the way that musicians compose music anyway, and the Web Audio API is extremely good at keeping these parts in sync. Once you have the various tracks that make up your piece you can bring tracks in and out as appropriate.

You can also apply filters or effects to music. Is your character in a cave? Increase the echo. Maybe you have underwater scenes, during which you could apply a filter that muffles the sound.

Let's look at some Web Audio API techniques for dynamically adjusting music from its base tracks.

### Loading your tracks

With the Web Audio API you can load separate tracks and loops individually using the Fetch API or `XMLHttpRequest`, which means you can load them synchronously or in parallel. Loading synchronously might mean parts of your music are ready earlier and you can start playing them while others load.

Either way you may want to synchronize tracks or loops. The Web Audio API contains the notion of an internal clock that starts ticking the moment you create an audio context. You'll need to take account of the time between creating an audio context and when the first audio track starts playing. Recording this offset and querying the playing track's current time gives you enough information to synchronize separate pieces of audio.

To see this in action, let's lay out some separate tracks:

```html
<section id="tracks">
  <ul>
    <li data-loading="true">
      <a href="leadguitar.mp3" class="track">Lead Guitar</a>
      <p class="loading-text">Loading…</p>
      <button data-playing="false" aria-describedby="guitar-play-label">
        <span id="guitar-play-label">Play</span>
      </button>
    </li>
    <li data-loading="true">
      <a href="bassguitar.mp3" class="track">Bass Guitar</a>
      <p class="loading-text">Loading…</p>
      <button data-playing="false" aria-describedby="bass-play-label">
        <span id="bass-play-label">Play</span>
      </button>
    </li>
    <li data-loading="true">
      <a href="drums.mp3" class="track">Drums</a>
      <p class="loading-text">Loading…</p>
      <button data-playing="false" aria-describedby="drums-play-label">
        <span id="drums-play-label">Play</span>
      </button>
    </li>
    <li data-loading="true">
      <a href="horns.mp3" class="track">Horns</a>
      <p class="loading-text">Loading…</p>
      <button data-playing="false" aria-describedby="horns-play-label">
        <span id="horns-play-label">Play</span>
      </button>
    </li>
    <li data-loading="true">
      <a href="clav.mp3" class="track">Clavi</a>
      <p class="loading-text">Loading…</p>
      <button data-playing="false" aria-describedby="clavi-play-label">
        <span id="clavi-play-label">Play</span>
      </button>
    </li>
  </ul>
  <p class="sourced">
    All tracks sourced from <a href="https://jplayer.org/">jplayer.org</a>
  </p>
</section>
```

All of these tracks are the same tempo and are designed to be synchronized with each other, so we need to make sure they are loaded and available to the API *before* we are able to play them. We can do this with JavaScript's `async`/`await` functionality.

Once they are available to play, we need to make sure they start at the correct point that other tracks might be playing at, so they sync up.

Let's create our audio context:

```js
const audioCtx = new AudioContext();
```

Now let's select all the `<li>` elements; later we can harness these elements to give us access to the track file path and each individual play button.

```js
const trackEls = document.querySelectorAll("li");
```

We want to make sure each file has loaded and been decoded into a buffer before we use it, so let's create an `async` function to allow us to do this:

```js
async function getFile(filepath) {
  const response = await fetch(filepath);
  const arrayBuffer = await response.arrayBuffer();
  const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);
  return audioBuffer;
}
```

We can then use the `await` operator when calling this function, which ensures that we can run subsequent code when it has finished executing.

Let's create another `async` function to set up the sample — we can combine the two async functions in a nice promise pattern to perform further actions when each file is loaded and buffered:

```js
async function loadFile(filePath) {
  const track = await getFile(filePath);
  return track;
}
```

Let's also create a `playTrack()` function, which we can call once a file has been fetched. We need an offset here, so if we have started one file playing, we have a record of how far through to start another file.

`start()` takes two optional parameters. The first is when to commence playback and the second is where, which is our offset.

```js
let offset = 0;

function playTrack(audioBuffer) {
  const trackSource = audioCtx.createBufferSource();
  trackSource.buffer = audioBuffer;
  trackSource.connect(audioCtx.destination);

  if (offset === 0) {
    trackSource.start();
    offset = audioCtx.currentTime;
  } else {
    trackSource.start(0, audioCtx.currentTime - offset);
  }

  return trackSource;
}
```

Finally, let's loop over our `<li>` elements, grab the correct file for each one and then allow playback by hiding the "loading" text and displaying the play button:

```js
trackEls.forEach((el, i) => {
  // Get children
  const anchor = el.querySelector("a");
  const loadText = el.querySelector("p");
  const playButton = el.querySelector("button");

  // Load file
  loadFile(anchor.href).then((track) => {
    // Set loading to false
    el.dataset.loading = "false";

    // Hide loading text
    loadText.style.display = "none";

    // Show button
    playButton.style.display = "inline-block";

    // Allow play on click
    playButton.addEventListener("click", () => {
      // Check if context is in suspended state (autoplay policy)
      if (audioCtx.state === "suspended") {
        audioCtx.resume();
      }

      playTrack(track);
      playButton.dataset.playing = true;
    });
  });
});
```

**Note:** You can see this demo in action here and view the source code here.

In the context of your game world you may have loops and samples that are played in different circumstances, and it can be useful to be able to synchronize with other tracks for a more seamless experience.

**Note:** This example does not wait for the beat to end before introducing the next piece; we could do this if we knew the BPM (Beats Per Minute) of the tracks.

You may find that the introduction of a new track sounds more natural if it comes in on the beat/bar/phrase or whatever units you want to chunk your background music into.

To do this before playing the track you want to sync, you should calculate how long it is until the start of the next beat/bar etc.

Here's a bit of code that given a tempo (the time in seconds of your beat/bar) will calculate how long to wait until you play the next part — you feed the resulting value to the `start()` function with the first parameter, which takes the absolute time of when that playback should commence. Note the second parameter (where to start playing from in the new track) is relative:

```js
if (offset === 0) {
  source.start();
  offset = context.currentTime;
} else {
  const relativeTime = context.currentTime - offset;
  const beats = relativeTime / tempo;
  const remainder = beats - Math.floor(beats);
  const delay = tempo - remainder \* tempo;
  source.start(context.currentTime + delay, relativeTime + delay);
}
```

**Note:** You can try our wait calculator code here, on JSFiddle (I've synched to the bar in this case).

**Note:** If the first parameter is 0 or less than the context `currentTime`, playback will commence immediately.

### Positional audio

Positional audio can be an important technique in making audio a key part of an immersive gaming experience. The Web Audio API not only enables us to position a number of audio sources in three-dimensional space but it can also allow us to apply filters that make that audio appear more realistic.

The `pannerNode` harnesses the positional capabilities of the Web Audio API so we can relate further information about the game world to the player. There's a tutorial here to help understand the `pannerNode` in better detail.

We can relate:

* The position of objects
* The direction and movement of objects
* The environment (cavernous, underwater, etc.)

This is especially useful in a three-dimensional environment rendered using WebGL, where the Web Audio API makes it possible to tie audio to the objects and viewpoints.

See also
--------

* Web Audio API on MDN
* `<audio>` on MDN
* Songs of Diridum: Pushing the Web Audio API to Its Limits
* Making HTML5 Audio Actually Work on Mobile
* Audio Sprites (and fixes for iOS)


WebRTC data channels - Game development

WebRTC data channels
====================

The WebRTC (Web Real-Time Communications) API is primarily known for its support for audio and video communications; however, it also offers peer-to-peer data channels. This article explains more about this, and shows you how to use libraries to implement data channels in your game.

What is a data channel?
-----------------------

A WebRTC data channel lets you send text or binary data over an active connection to a peer. In the context of a game, this lets players send data to each other, whether text chat or game status information. Data channels come in two flavors.

**Reliable channels** guarantee that messages you send arrive at the other peer and in the same order in which they're sent. This is analogous to a TCP socket.

**Unreliable channels** make no such guarantees; messages aren't guaranteed to arrive in any particular order and, in fact, aren't guaranteed to arrive at all. This is analogous to a UDP socket.

We have documentation for using WebRTC. This article, however, will take advantage of some libraries that can help trivialize the work, and will demonstrate ways to use abstraction to work around implementation differences between browsers. Hopefully, of course, those differences will fade away in time.

Using the p2p library
---------------------

One library you can use is the p2p library. This library provides a simple API for creating peer connections and setting up streams and data channels. There's also a broker server component and a hosted broker you can use instead of having to set one up for yourself.

**Note:** We will continue to add content here soon; there are some organizational issues to sort out.

Original Document Information
-----------------------------

* Author(s): Alan Kligman
* Source Article: WebRTC Data Channels for Great Multiplayer
* Other Contributors: Robert Nyman
* Copyright Information: Alan Kligman, 2013


3D collision detection - Game development

3D collision detection
======================

This article provides an introduction to the different bounding volume techniques used to implement collision detection in 3D environments. Followup articles will cover implementations in specific 3D libraries.

Axis-aligned bounding boxes
---------------------------

As with 2D collision detection, **axis-aligned bounding boxes** (AABB) are the quickest algorithm to determine whether the two game entities are overlapping or not. This consists of wrapping game entities in a non-rotated (thus axis-aligned) box and checking the positions of these boxes in the 3D coordinate space to see if they are overlapping.

![Two 3-D non-square objects floating in space encompassed by virtual rectangular boxes.](/en-US/docs/Games/Techniques/3D_collision_detection/screen_shot_2015-10-16_at_15.11.21.png)

The **axis-aligned constraint** is there because of performance reasons. The overlapping area between two non-rotated boxes can be checked with logical comparisons alone, whereas rotated boxes require additional trigonometric operations, which are slower to calculate. If you have entities that will be rotating, you can either modify the dimensions of the bounding box so it still wraps the object, or opt to use another bounding geometry type, such as spheres (which are invariant to rotation.) The animated GIF below shows a graphic example of an AABB that adapts its size to fit the rotating entity. The box constantly changes dimensions to snugly fit the entity contained inside.

![Animated rotating knot showing the virtual rectangular box shrink and grow as the knots rotates within it. The box does not rotate.](/en-US/docs/Games/Techniques/3D_collision_detection/rotating_knot.gif)

**Note:** Check out the Bounding Volumes with Three.js article to see a practical implementation of this technique.

### Point vs. AABB

Checking if a point is inside an AABB is pretty simple — we just need to check whether the point's coordinates fall inside the AABB; considering each axis separately. If we assume that *Px*, *Py* and *Pz* are the point's coordinates, and *BminX*–*BmaxX*, *BminY*–*BmaxY*, and *BminZ*–*BmaxZ* are the ranges of each axis of the AABB, we can calculate whether a collision has occurred between the two using the following formula:

f
(
P
,
B
)
=
(

P
x

≥

B

m
i
n
X

∧

P
x

≤

B

m
a
x
X

)
∧
(

P
y

≥

B

m
i
n
Y

∧

P
y

≤

B

m
a
x
Y

)
∧
(

P
z

≥

B

m
i
n
Z

∧

P
z

≤

B

m
a
x
Z

)

f(P, B)= (P\_x \ge B\_{minX} \wedge P\_x \le B\_{maxX}) \wedge (P\_y \ge B\_{minY} \wedge P\_y \le B\_{maxY}) \wedge (P\_z \ge B\_{minZ} \wedge P\_z \le B\_{maxZ})

Or in JavaScript:

```js
function isPointInsideAABB(point, box) {
  return (
    point.x >= box.minX &&
    point.x <= box.maxX &&
    point.y >= box.minY &&
    point.y <= box.maxY &&
    point.z >= box.minZ &&
    point.z <= box.maxZ
  );
}
```

### AABB vs. AABB

Checking whether an AABB intersects another AABB is similar to the point test. We just need to do one test per axis, using the boxes' boundaries. The diagram below shows the test we'd perform over the X-axis — basically, do the ranges *AminX*–*AmaxX* and *BminX*–*BmaxX* overlap?

![Hand drawing of two rectangles showing the upper right corner of A overlapping the bottom left corner of B, as A's largest x coordinate is greater than B's smallest x coordinate.](/en-US/docs/Games/Techniques/3D_collision_detection/aabb_test.png)

Mathematically this would look like so:

f
(
A
,
B
)
=
(

A

m
i
n
X

≤

B

m
a
x
X

∧

A

m
a
x
X

≥

B

m
i
n
X

)
∧
(

A

m
i
n
Y

≤

B

m
a
x
Y

∧

A

m
a
x
Y

≥

B

m
i
n
Y

)
∧
(

A

m
i
n
Z

≤

B

m
a
x
Z

∧

A

m
a
x
Z

≥

B

m
i
n
Z

)

f(A, B) = (A\_{minX} \le B\_{maxX} \wedge A\_{maxX} \ge B\_{minX}) \wedge ( A\_{minY} \le B\_{maxY} \wedge A\_{maxY} \ge B\_{minY}) \wedge (A\_{minZ} \le B\_{maxZ} \wedge A\_{maxZ} \ge B\_{minZ})

And in JavaScript, we'd use this:

```js
function intersect(a, b) {
  return (
    a.minX <= b.maxX &&
    a.maxX >= b.minX &&
    a.minY <= b.maxY &&
    a.maxY >= b.minY &&
    a.minZ <= b.maxZ &&
    a.maxZ >= b.minZ
  );
}
```

Bounding spheres
----------------

Using bounding spheres to detect collisions is a bit more complex than AABB, but still fairly quick to test. The main advantage of spheres is that they are invariant to rotation, so if the wrapped entity rotates, the bounding sphere would still be the same. Their main disadvantage is that unless the entity they are wrapping is actually spherical, the wrapping is usually not a good fit (i.e. wrapping a person with a bounding sphere will cause a lot of false positives, whereas an AABB would be a better match).

### Point vs. sphere

To check whether a sphere contains a point we need to calculate the distance between the point and the sphere's center. If this distance is smaller than or equal to the radius of the sphere, the point is inside the sphere.

![Hand drawing of a 2D projection of a sphere and a point in a Cartesian coordinate system. The point is outside of the circle, to the lower right of it. The distance is denoted by a dashed line, labeled D, from the circle's center to the point. A lighter line shows the radius, labeled R, going from the center of the circle to the border of the circle.](/en-US/docs/Games/Techniques/3D_collision_detection/point_vs_sphere.png)

Taking into account that the Euclidean distance between two points *A* and *B* is

(

A
x

−

B
x

)
2

+
(

A
y

−

B
y

)
2

+
(

A
z

−

B
z

)
2

\sqrt{(A\_x - B\_x)^2 + (A\_y - B\_y)^2 + (A\_z - B\_z)^2}

, our formula for point vs. sphere collision detection would work out like so:

f
(
P
,
S
)
=

S

r
a
d
i
u
s

≥

(

P
x

−

S
x

)
2

+
(

P
y

−

S
y

)
2

+
(

P
z

−

S
z

)
2

f(P,S) = S\_{radius} \ge \sqrt{(P\_x - S\_x)^2 + (P\_y - S\_y)^2 + (P\_z - S\_z)^2}

Or in JavaScript:

```js
function isPointInsideSphere(point, sphere) {
  // we are using multiplications because is faster than calling Math.pow
  const distance = Math.sqrt(
    (point.x - sphere.x) \* (point.x - sphere.x) +
      (point.y - sphere.y) \* (point.y - sphere.y) +
      (point.z - sphere.z) \* (point.z - sphere.z),
  );
  return distance < sphere.radius;
}
```

**Note:** The code above features a square root, which can be expensive to calculate. An easy optimization to avoid it consists of comparing the squared distance with the squared radius, so the optimized equation would instead involve `distanceSqr < sphere.radius * sphere.radius`.

### Sphere vs. sphere

The sphere vs. sphere test is similar to the point vs. sphere test. What we need to test here is that the distance between the sphere's centers is less than or equal to the sum of their radii.

![Hand drawing of two partially overlapping circles. Each circle (of different sizes) has a light radius line going from its center to its border, labeled R. The distance is denoted by a dotted line, labeled D, connecting the center points of both circles.](/en-US/docs/Games/Techniques/3D_collision_detection/sphere_vs_sphere.png)

Mathematically, this looks like:

f
(
A
,
B
)
=

(

A
x

−

B
x

)
2

+
(

A
y

−

B
y

)
2

+
(

A
z

−

B
z

)
2

≤

A

r
a
d
i
u
s

+

B

r
a
d
i
u
s

f(A,B) = \sqrt{(A\_x - B\_x)^2 + (A\_y - B\_y)^2 + (A\_z - B\_z)^2} \le A\_{radius} + B\_{radius}

Or in JavaScript:

```js
function intersect(sphere, other) {
  // we are using multiplications because it's faster than calling Math.pow
  const distance = Math.sqrt(
    (sphere.x - other.x) \* (sphere.x - other.x) +
      (sphere.y - other.y) \* (sphere.y - other.y) +
      (sphere.z - other.z) \* (sphere.z - other.z),
  );
  return distance < sphere.radius + other.radius;
}
```

### Sphere vs. AABB

Testing whether a sphere and an AABB are colliding is slightly more complicated, but still simple and fast. A logical approach would be to check every vertex of the AABB, doing a point vs. sphere test for each one. This is overkill, however — testing all the vertices is unnecessary, as we can get away with just calculating the distance between the AABB's *closest point* (not necessarily a vertex) and the sphere's center, seeing if it is less than or equal to the sphere's radius. We can get this value by clamping the sphere's center to the AABB's limits.

![Hand drawing of a square partially overlapping the top of a circle. The radius is denoted by a light line labeled R. The distance line goes from the circle's center to the closest point of the square.](/en-US/docs/Games/Techniques/3D_collision_detection/sphere_vs_aabb.png)

In JavaScript, we'd do this test like so:

```js
function intersect(sphere, box) {
  // get box closest point to sphere center by clamping
  const x = Math.max(box.minX, Math.min(sphere.x, box.maxX));
  const y = Math.max(box.minY, Math.min(sphere.y, box.maxY));
  const z = Math.max(box.minZ, Math.min(sphere.z, box.maxZ));

  // this is the same as isPointInsideSphere
  const distance = Math.sqrt(
    (x - sphere.x) \* (x - sphere.x) +
      (y - sphere.y) \* (y - sphere.y) +
      (z - sphere.z) \* (z - sphere.z),
  );

  return distance < sphere.radius;
}
```

Using a physics engine
----------------------

**3D physics engines** provide collision detection algorithms, most of them based on bounding volumes as well. The way a physics engine works is by creating a **physical body**, usually attached to a visual representation of it. This body has properties such as velocity, position, rotation, torque, etc., and also a **physical shape**. This shape is the one that is considered in the collision detection calculations.

We have prepared a live collision detection demo (with source code) that you can take a look at to see such techniques in action — this uses the open-source 3D physics engine cannon.js.

See also
--------

Related articles on MDN:

* Bounding volumes collision detection with Three.js
* 2D collision detection

External resources:

* Simple intersection tests for games on Game Developer
* Bounding volume on Wikipedia


Implementing game control mechanisms - Game development

Implementing game control mechanisms
====================================

One of HTML5's main advantages as a game development platform is the ability to run on various platforms and devices. Streamlining cross device differences creates multiple challenges, not least when providing appropriate controls for different contexts. In this series of articles we will show you how you can approach building a game that can be played using touchscreen smartphones, mouse and keyboard, and also less common mechanisms such as gamepads.

Case study
----------

We'll be using the Captain Rogers: Battle at Andromeda demo as an example.

![Captain Rogers: Battle at Andromeda - cover of the game containing Enclave Games and Blackmoon Design logos, Roger's space ship and title of the game.](/en-US/docs/Games/Techniques/Control_mechanisms/captainrogers2-cover.png)

Captain Rogers was created using the Phaser framework, the most popular tool for simple 2D game development in JavaScript right now, but it should be fairly easy to reuse the knowledge contained within these articles when building games in pure JavaScript or any other framework. If you're looking for a good introduction to Phaser, then check the 2D breakout game using Phaser tutorial.

In the following articles we will show how to implement various different control mechanisms for Captain Rogers to support different platforms — from touch on mobile, through keyboard/mouse/gamepad on desktop, to more unconventional ones like TV remote, shouting to or waving your hand in front of the laptop, or squeezing bananas.

Setting up the environment
--------------------------

Let's start with a quick overview of the game's folder structure, JavaScript files and in-game states, so we know what's happening where. The game's folders look like this:

![Captain Rogers: Battle at Andromeda - folder structure of the games' project containing JavaScript sources, images and fonts.](/en-US/docs/Games/Techniques/Control_mechanisms/captainrogers2-folderstructure.png)

As you can see there are folders for images, JavaScript files, fonts and sound effects. The `src` folder contains the JavaScript files split as a separate states — `Boot.js`, `Preloader.js`, `MainMenu.js` and `Game.js` — these are loaded into the index file in this exact order. The first one initializes Phaser, the second preloads all the assets, the third one controls the main menu welcoming the player, and the fourth controls the actual gameplay.

Every state has its own default methods: `preload()`, `create()`, and `update()`. The first one is needed for preloading required assets, `create()` is executed once the state had started, and `update()` is executed on every frame.

For example, you can define a button in the `create()` function:

```js
create() {
  // …
  const buttonEnclave = this.add.button(10, 10, 'logo-enclave', this.clickEnclave, this);
  // …
}
```

It will be created once at the start of the game, and will execute `this.clickEnclave()` action assigned to it when clicked, but you can also use the mouse's pointer value in the `update()` function to make an action:

```js
update() {
  // …
  if (this.game.input.mousePointer.isDown) {
      // do something
  }
  // …
}
```

This will be executed whenever the mouse button is pressed, and it will be checked against the input's `isDown` boolean variable on every frame of the game.

That should give you some understanding of the project structure. We'll be playing mostly with the `MainMenu.js` and `Game.js` files, and we'll explain the code inside the `create()` and `update()` methods in much more detail in later articles.

Pure JavaScript demo
--------------------

There's also a small online demo with full source code available on GitHub where the basic support for the control mechanisms described in the articles is implemented in pure JavaScript. It will be explained in the given articles themselves below, but you can play with it already, and use the code however you want for learning purposes.

The articles
------------

JavaScript is the perfect choice for mobile gaming because of HTML being truly multiplatform; all of the following articles focus on the APIs provided for interfacing with different control mechanisms:

1. Mobile touch controls — The first article will kick off with touch, as the mobile first approach is very popular.
2. Desktop mouse and keyboard controls — When playing on a desktop/laptop computer, providing keyboard and mouse controls is essential to provide an acceptable level of accessibility for the game.
3. Desktop gamepad controls — The Gamepad API rather usefully allows gamepads to be used for controlling web apps on desktop/laptop, for that console feel.
4. Unconventional controls — The final article showcases some unconventional control mechanisms, from the experimental to the slightly crazy, which you might not believe could be used to play the game.


Square tilemaps implementation: Static maps - Game development

Square tilemaps implementation: Static maps
===========================================

This article covers how to implement static square tilemaps using the Canvas API.

**Note:** When writing this article, we assumed previous reader knowledge of canvas basics such as how get a 2D canvas context, load images, etc., which is all explained in the Canvas API tutorial, as well as the basic information included in our Tilemaps introduction article.

The tile atlas
--------------

A tilemap might use one or several atlases — or spritesheets — that contain all of the tile images. This is the atlas we will be using as an example, which features five different tiles:

![Tiles packaged in an atlas](/en-US/docs/Games/Techniques/Tilemaps/Square_tilemaps_implementation:_Static_maps/tiles.png)

To draw a tile from the atlas into the canvas we make use of the `drawImage()` method in a canvas 2D context. We need to supply the atlas image, the coordinates and dimensions of the tile inside the atlas, and the target coordinates and size (a different tile size in here would scale the tile.)

So, for instance, to draw the tree tile, which is the third in the atlas, at the screen coordinates `(128, 320)`, we would call `drawImage()` with these values:

```js
context.drawImage(atlasImage, 192, 0, 64, 64, 128, 320, 64, 64);
```

In order to support atlases with multiple rows and columns, you would need to know how many rows and columns there are to be able to compute the source `x` and `y`.

The tilemap data structure
--------------------------

To store that map data, we can use a plain object or a custom class. For the sake of simplicity, in the example code a plain object has been used. It contains the basic map properties:

* `cols`: The width of the map, in columns.
* `rows`: The height of the map, in rows.
* `tsize`: The tile size, in pixels.
* `tiles`: A 1-dimensional array containing the visual grid.
* `getTile()`: A helper method that gets the tile index in a certain position.

`tiles` contains the actual visual map data. We are representing the tiles with indices, assigned to the tiles dependent on their position in the atlas (e.g. `0` for the left-most tile.) However, we must account for **empty tiles**, since they are crucial for implementing layers — empty tiles are usually assigned a negative index value, `0`, or a null value. In these examples, empty tiles will be represented by index `0`, so we will shift the indices of the atlases by one (and thus the first tile of the atlas will be assigned index `1`, the second index `2`, etc.)

The `getTile()` helper method returns the tile contained at the specified column and row. If `tiles` were a 2D matrix, then the returned value would just be `tiles[column][row]`. However, it's usually more common to represent the grid with a 1-dimensional array. In this case, we need to map the column and row to an array index:

```js
const index = row \* map.cols + column;
```

Wrapping up, an example of a tilemap object could look like the following. This features an 8 x 8 map with tiles 64 x 64 pixels in size:

```js
const map = {
  cols: 8,
  rows: 8,
  tsize: 64,
  tiles: [
    1, 3, 3, 3, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1,
    1, 1, 2, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1,
  ],
  getTile(col, row) {
    return this.tiles[row \* map.cols + col];
  },
};
```

Rendering the map
-----------------

We can render the map by iterating over its columns and rows. This snippet assumes the following definitions:

* `context`: A 2D canvas context.
* `tileAtlas`: An image object containing the tile atlas.
* `map`: The tilemap object discussed above.

```js
for (let c = 0; c < map.cols; c++) {
  for (let r = 0; r < map.rows; r++) {
    const tile = map.getTile(c, r);
    if (tile !== 0) {
      // 0 => empty tile
      context.drawImage(
        tileAtlas, // image
        (tile - 1) \* map.tsize, // source x
        0, // source y
        map.tsize, // source width
        map.tsize, // source height
        c \* map.tsize, // target x
        r \* map.tsize, // target y
        map.tsize, // target width
        map.tsize, // target height
      );
    }
  }
}
```

Demo
----

Our static tilemap implementation demo pulls the above code together to show what an implementation of this map looks like. You can see a live demo and grab the full source code.

![Aerial view of a field with trees, grass, and ground made from repeated sections of the tilemap.](/en-US/docs/Games/Techniques/Tilemaps/Square_tilemaps_implementation:_Static_maps/no-scroll.png)


Square tilemaps implementation: Scrolling maps - Game development

Square tilemaps implementation: Scrolling maps
==============================================

This article covers how to implement scrolling square tilemaps using the Canvas API.

**Note:** When writing this article, we assumed previous reader knowledge of canvas basics such as how get a 2D canvas context, load images, etc., which is all explained in the Canvas API tutorial, as well as the basic information included in our Tilemaps introduction article. This article also builds upon implementing static square tilemaps — you should read that too if you've not done so already.

The camera
----------

The camera is an object that holds information about which section of the game world or level is currently being shown. Cameras can either be free-form, controlled by the player (such as in strategy games) or follow an object (such as the main character in platform games.)

Regardless of the type of camera, we would always need information regarding its current position, viewport size, etc. In the demo provided along with this article, these are the parameters the camera has:

* `x` and `y`: The current position of the camera. In this implementation, we are assuming that `(x,y)` points to the top left corner of visible portion of the map.
* `width` and `height`: The size of the camera's viewport.
* `maxX` and `maxY`: The limit for the camera's position — The lower limit will nearly always be (0,0), and in this case the upper limit is equal to the size of the world minus the size of the camera's viewport.
Rendering the map
-----------------

There are two main differences between rendering scrolling maps vs. static maps:

* **Partial tiles might be shown**. In static maps, usually the rendering starts in the top left corner of a tile situated in the top left corner of a viewport. While rendering scrolling tilemaps, the first tile will often be clipped.
* **Only a section of the map will be rendered**. If the map is bigger than the viewport, we can obviously only display a part of it at a time, whereas non-scrolling maps are usually rendered wholly.

To handle these issues, we need to slightly modify the rendering algorithm. Let's imagine that we have the camera pointing at `(5,10)`. That means that the first tile would be `0x0`. In the demo code, the starting point is stored at `startCol` and `startRow`. It's convenient to also pre-calculate the last tile to be rendered.

```js
const startCol = Math.floor(this.camera.x / map.tsize);
const endCol = startCol + this.camera.width / map.tsize;
const startRow = Math.floor(this.camera.y / map.tsize);
const endRow = startRow + this.camera.height / map.tsize;
```

Once we have the first tile, we need to calculate how much its rendering (and therefore the rendering of the other tiles) is offset by. Since the camera is pointing at `(5, 10)`, we know that the first tile should be shifted by `(-5,-10)` pixels. In our demo the shifting amount is stored in the `offsetX` and `offsetY` variables.

```js
const offsetX = -this.camera.x + startCol \* map.tsize;
const offsetY = -this.camera.y + startRow \* map.tsize;
```

With these values in place, the loop that renders the map is quite similar to the one used for rendering static tilemaps. The main difference is that we are adding the `offsetX` and `offsetY` values to the target `x` and `y` coordinates, and these values are rounded, to avoid artifacts that would result from the camera pointing at positions with floating point numbers.

```js
for (let c = startCol; c <= endCol; c++) {
  for (let r = startRow; r <= endRow; r++) {
    const tile = map.getTile(c, r);
    const x = (c - startCol) \* map.tsize + offsetX;
    const y = (r - startRow) \* map.tsize + offsetY;
    if (tile !== 0) {
      // 0 => empty tile
      this.ctx.drawImage(
        this.tileAtlas, // image
        (tile - 1) \* map.tsize, // source x
        0, // source y
        map.tsize, // source width
        map.tsize, // source height
        Math.round(x), // target x
        Math.round(y), // target y
        map.tsize, // target width
        map.tsize, // target height
      );
    }
  }
}
```

Demo
----

Our scrolling tilemap implementation demo pulls the above code together to show what an implementation of this map looks like. You can take a look at a live demo, and see its source code.

![Animated gif of a section grass, dirt areas, and trees made from repeated sections of a tilemap showing how you see different sections of the area when you scroll.](/en-US/docs/Games/Techniques/Tilemaps/Square_tilemaps_implementation:_Scrolling_maps/untitled.gif)

There's another demo available, that shows how to make the camera follow a character.