Chapter 1. Introduction To Impact

Impact is a JavaScript game framework created by Dominic Szablewski. Impact takes advantage of the modern browser’s Canvas element in order to create high-performance 2D games on the Web and even mobile. One of the biggest advantages of using Impact is that it is easy to pick up, comes with very good code examples, has an active community, and has a very robust level editor called Weltmeister. The only barrier of entry is the licensing fee for the software, since it is not open source. After purchasing a license, you do get the full source code, the Weltmeister level editor, and free current major version updates (1.x). While there are other open source and free JavaScript game frameworks out there, Impact has an extra level of polish I haven’t seen with anything else so far.

Why Use Impact?

Perhaps one of the most appealing factors of buying Impact is the inclusion of a sample Objective-C project that allows you to compile your Web game into a native iOS app. This enables your game to take advantage of OpenGL for graphics and OpenAL for sound instead of the Canvas and Audio elements in the mobile Safari browser. This solution gives your game almost native-like performance on iOS, and it can be packaged up and sold in the Apple Store just like a native app.

Here are some links to help you learn more about Impact and examples of it in action:

Tools you will need:

PHP

For saving levels created with Weltmeister.

Apache

For locally hosting and testing your game.

IDEs

Impact has no IDE dependencies; you can create your games with any simple text editor. I prefer to use WebStorm or PHPStorm since these IDEs, which are made by JetBrains, offer code hinting, project management, refactoring, and debugging.

Browsers

Impact works very well on WebKit browsers, especially Chrome, but any modern browser with support for Canvas and the Audio tag should also work.

Setting Up a Local Environment

Before getting started, we are going to have to set up a simple Web development environment in order to take full advantage of Impact and its level editor. Plus, by setting up a local development environment, we can simulate what it will be like to host the game in a production environment. Let’s take a look at configuring Apache, the IDE, and Impact itself.

Install WebStorm/PHPStorm

While you can use any basic text editor, I prefer to use an IDE that offers a more robust set of features such as code hinting, refactoring, project management, version control integration, and a debugger. JetBrains has two IDEs that both handle JavaScript/HTML5 development. If you only plan on doing JavaScript development, I would suggest using WebStorm. If you need to do HTML5 and PHP development (which comes in handy since Impact’s level editor uses PHP) you should look at PHPStorm.

Installing these applications is straightforward. Here are URLs for each IDE:

Each IDE has a 30-day trial and after the trial costs $99 for a license. There are a lot of resources out there on how to use each IDE, so I am not going to cover it here.

Install Apache/PHP/MySQL

There are many guides for installing Apache and PHP on your operating system of choice. Here are some simple one-click solutions to help get you up and running as quickly as possible:

Mac

For Mac, you should use an all-in-one solution such as MAMP. This is a free one-click solution for getting Apache, PHP, and MySQL set up on your Mac. Likewise, you can also use the built-in version of PHP that comes with OS X, but you will need to do some manual configuration of Apache to get it working. Simply do a search for “Enabling PHP in Mac OS X” in order to find instructions.

PC

Just like on Mac, there are some excellent one-click solutions for setting up Apache, PHP, and MySQL. I have used XAMP in the past, and have had excellent success with it.

Other Hosting Options

If you prefer not to work on a LAMP (Linux, Apache, MySQL, PHP) stack you can check out the following projects that allow you to run Impact on different hosting environments:

Node.js

Conner Petzold made a Node.js module that allows Impact to run on a Node HTTP server. His Node-Impact module is on GitHub.

.NET

You can run Impact on IIS and .NET thanks to Mike Hamilton’s ImpactJS-IIS-.NET-API project.

Ruby

Chris Darroch put together a Sinatra backend for Impact. Just remove the .php extensions for the API calls in your lib/weltmeister/config.js and fire up impact.rb.

Python

Joe Esposito has a GitHub project that implements a backend server in Python for Impact to let you develop multiple games at once.

Setting Up a New Impact Project

Impact is a self-contained project. Each game you create will require you to copy the default Impact project folder (which you get once you buy a license) into a new location on your server and start from scratch. Impact is set up so you can easily do all your work from your local host.

To get started, copy the Impact project into your local host. You should see the following files (Figure 1-1).

Impact project files.
Figure 1-1. Impact project files.

As you can see, I have renamed my impact folder residentraver, which is the name of the game we are going to create in this book. Here is a quick breakdown of everything in the folder:

index.html

This is the main .html file that runs your game.

lib

This is the core code for Impact and where you will store your own game-specific JS files. This also contains the source code for Weltmeister.

media

This is the assets directory, and where all game art and sound files will go.

tools

This directory contains .php scripts to minify your game’s JS files and make it harder for people to have access to the game’s source code. This is part of the license and is important so you don’t accidentally distribute the source code.

weltmeister.html

This is the level editor’s .html file.

You should now have everything you need to run your first game. If you open your browser and navigate to http://localhost/residentraver[1] you should see the following page (Figure 1-2).

This is what you will see when you run an Impact game for the first time.
Figure 1-2. This is what you will see when you run an Impact game for the first time.

Before moving on, I just wanted to take a quick moment to look at the index.html file and how it is set up. Open it up in your editor and you should see the following HTML code:

1    <!DOCTYPE html>
2    <html>
3    <head>
4        <title>Impact Game</title>
5        <style type="text/css">
6            html,body {
7                background-color: #000;
8                color: #fff;
9                font-family: helvetica, arial, sans-serif;
10                margin: 0;
11                padding: 0;
12                font-size: 12pt;
13            }
1415            #canvas {
16                position: absolute;
17                left: 0;
18                right: 0;
19                top: 0;
20                bottom: 0;
21                margin: auto;
22                border: 1px solid #555;
23            }
24        </style>
25
26        <script type="text/javascript" src="lib/impact/impact.js"></script>
27        <script type="text/javascript" src="lib/game/main.js"></script>
28    </head>
29    <body>
30        <canvas id="canvas"></canvas>
31    </body>
32    </html>

Outside of the style tag, you may notice there isn’t a lot of code actually embedded in the page. We have two script tags that load in the impact.js framework and our main.js JavaScript file. Finally the only tag in body is the Canvas element.

Note

The Canvas element is part of the HTML5 spec and is what actually allows Impact to run in the browsers. Think of the canvas as an image that we can draw bitmap data into. Impact takes care of all the underlying code we would have had to write in order to display game graphics to the screen. You can learn more about how the Canvas tag works at the whatwg.org Canvas page. It’s also important to note that the Canvas element only works in modern browsers such as Chrome 13+, Safari 3.2+, Firefox 6+ and IE 9+. For a full list of browsers that support the Canvas element, go to http://caniuse.com/#search=canvas.

You can also add your own HTML code around the Canvas element and design this page to look like any other HTML file. Just keep in mind that we use the canvas id in our game in order to tell impact where to render our game’s graphics to, so don’t change it unless you update your game’s initialization logic.

Now we are ready to learn more about the Impact framework.

Modules

Impact’s source code is organized into modules. Since JavaScript itself does not have an include() function that can load other JavaScript source files into an object, Impact has its own system. A module typically looks like this:

1    ig.module(
2        'game.my-file'
3    )
4    .requires(
5        'impact.game',
6        'impact.image',
7        'game.other-file'
8    )
9    .defines(function(){
10        // code for this module
11    });

The first block defines the module name 'game.my-file', which directly corresponds to the file name. Modules and their dependencies typically reside in the lib/ folder of your Impact project directory, and subdirectories are included in a path to these files using object-model dot syntax. Therefore, the my-file.js file sits in the lib/game/my-file.js.

The second block defines any additional files that will be loaded at runtime. Since JavaScript itself does not have an established way to load other JavaScript source files into an object, Impact has its own system. The modules listed in the .requires() method will be loaded from the lib/impact/game.js, lib/impact/image.js, and lib/game/other-file.js project directory, respectively. These required files will be loaded before the module’s body and before the last block of the above module example is executed.

The last step the module takes is to execute the function passed to the .defines() method. This linear process allows you to control when code is loaded and run. It’s important to follow Impact’s file naming and location structure since it will try to automatically load these resources for you during the pre-load phase. Next, we’ll talk a little more about classes in Impact and how they work.

How Classes Work

In JavaScript, there is no real notion of a traditional class structure like you have in other OOP languages. In JavaScript, everything is an Object. While this allows JavaScript to be incredibly flexible, it also makes it difficult to structure your code in a reusable way. To solve this issue, Impact has a pseudo-class object, which is the basis of every class we will create in our game.

Note

Impact’s class object is based on John Resig’s simple JavaScript inheritance code (http://ejohn.org/blog/simple-javascript-inheritance), but it is extended with deep copying of properties and static instantiation.

Here is an example of how we can create a new person class by building off of Impact’s core Class object:

1    // Create a new class "Person"
2    var Person = ig.Class.extend({
3        name: '',
4        init: function( name ) {
5            this.name = name;
6        }
7    });
8
9    // Instantiate an object of the first class
10    var e = new Person('John Doe');
11    e.name; // => John Doe

You may have noticed that we actually extend the functionality of the ig.Class object via the .extend() method.

Note

In traditionally class based languages, the extends keyword allows us to copy over the existing functionality of another class. This is what will allow us to infuse additional functionality into all of our game classes without having to actually duplicate code all over the place.

In addition to extending off of ig.Class, you can actually extend off of any custom class you create. Again, in order to extend another class you simply use the .extend() functionality. Here we are going to extend off of our person class to create a new zombie class:

1    // Create another class by extending the "Person" class
2    var Zombie = Person.extend({
3        init: function( name ) {
4            this.parent( 'Zombie: ' + name );
5        }
6    });
7
8    // Instantiate an object of the second class
9    var p = new Zombie('John Doe');
10    p.name; // => Zombie: John Doe

All classes that are created with .extend() will also have an .extend() method that can be used for further subclassing. When working inside of extended classes, you can use .this and .parent for scope. You will see later on how splitting up core logic into individual classes will help expostulate functionality and make our game code easier to maintain while we develop it.

Core Classes

Impact is made up of several core classes that revolve around the game framework and all the necessary systems such as rendering, maps, sounds, and more. All the classes are in the ig namespace, which is set up by the core class. Here is a list of the main classes used in Impact along with a short description of what they do:

ig Core

The ig object provides the module definition and loading capabilities as well as some utility functions.

Animation

An ig.Animation object takes care of animating an entity or BackgroundMap tiles. Frames from an AnimationSheet—an image with all animation frames—are drawn as specified by the animation’s frameTime and sequence.

AnimationSheet

ig.AnimationSheet is a thin wrapper around an ig.Image object. It specifies the width and height properties for each animation frame in the sheet. It is used by the ig.Animation class.

BackgroundMap

An ig.BackgroundMap draws tiles from a Tileset, as indicated by its 2D data array.

CollisionMap

An ig.Collision takes a 2D TileMap and allows tracing against it for collisions.

Entity

Interactive objects in the game world are typically subclassed from this base entity class. It provides animation, drawing, and basic physics. Subclassing your entities from ig.Entity ensures that it can be added to the game world, react to the CollisionMap along with other entities, and be added to a level within Weltmeister.

Font

An ig.Font object loads a specially formatted font image and allows you to draw text with it.

Game

ig.Game is the main hub for your game. It hosts all currently active entities, BackgroundMaps, and a CollisionMap. You can subclass your own game class from ig.Game.

Image

ig.Image is a wrapper around image resources (.png, .gif, .jpeg). It takes care of loading and scaling the source image. You can draw the whole image by calling .draw() or just one tile of it by calling .drawTile().

Input

ig.Input handles all keyboard and mouse input.

Loader

ig.Loader is the default pre-loader for all images and sounds that the game needs. By default, it displays a white progress bar on a black background.

Map

ig.Map is the base class for ig.BackgroundMap and ig.CollisionMap. It only provides basic access to the tiles in the map data.

Music

ig.Music offers the ability to play a list of background music in order or randomly.

Sound

An instance of ig.Sound represents a sound file to be used as background music or game sound.

SoundManager

The SoundManager takes care of loading sounds and providing them for ig.Music and ig.Sound instances. An instance of the SoundManager is automatically created at ig.soundManager by the ig.main() function.

System

ig.System takes care of starting and stopping the run loop and calls the .run() method on the current game object. It also does the housekeeping for ig.Input and provides some utility methods.

Timer

The ig.Timer has two distinct modes of operation. You can either get the difference by calling .delta() between the current time and the timer’s target time (as set by the constructor or .set()) or just get the current tick—the time since the last call to .tick().

You can learn more about each of these classes and their methods on Impact’s website under the documentation section at http://impactjs.com/documentation.

How Inner Classes Work

In traditional class-based languages, you usually have the option to put a class inside of another class’s package structure. These are called inner classes. Impact has its own version of this, which allows us to add more than one class to a single module file.

Creating an inner class is similar to making a normal class, with the exception that you will be adding it to the end of the main class’s module. These inner classes also support inheritance as well. Here is a quick example of two classes in the same module:

1    ig.module(
2        game.entities.myclass'
3    )
4    .requires(
5        'impact.entity'
6    )
7    .defines(function(){
8        EntityMyClass = ig.Entity.extend({
9            //Properties and methods go here
10        });
11
12        EntityMyInnerClass = ig.Entity.extend({
13            //Properties and methods go here
14        });
15    });

This technique is incredibly helpful when it comes to keeping your code organized, as you will see later in the book.

Level Editor

One of the best features of Impact is its level editor called Weltmeister. It is located in the libs/weltmeister folder inside the Impact project. We will go through using this editor in the next chapter, but I wanted to take some time to highlight its features and how to use it.

You can pull up the level editor anytime by navigating to the root of your project’s domain and loading the weltmeister.html file. You will be presented with this screen:

This is the screen you will see after loading Weltmeister for the first time. Select a layer to see the grid numbers.
Figure 1-3. This is the screen you will see after loading Weltmeister for the first time. Select a layer to see the grid numbers.

When you load the editor for the first time, you are presented with an empty untitled.js map file. Along the top are your main controls such as Save, Save As, New, and Load. Reload Images allows you to make visual tweaks to your map without having to do a hard refresh. Finally, on the far right, you will see a large arrow that shows/hides the layers, and below that are your map’s layers. By default, there is an entities layer, which is where your player, monster, and other in-game elements will go. You can add new layers at any time by pressing the plus sign on the right of the Layers label.

Note

Layers simply allow you to draw level tiles onto the stage just as you would use a stamp tool in a painting program. If your game’s level is incredibly detailed, you may want to break out parts of the level’s tiles into a background, middle ground, and foreground layers as well as creating other layers for collision detection and additional details. Anything that moves in the game will go into the entities layer.

Before we can start making levels for our game, we need to create some graphics. Let’s take a look at the asset pipeline, and more importantly, how to create graphics for Impact projects.



[1] Based on how Apache is set up on your computer, you may have a different URL for your localhost. If you are using MAMP, it may be http://localhost:8888, or with XAMP it is http://localhost. Refer to your Apache documentation for the correct URL.

Get Building HTML5 Games with ImpactJS now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.