Creating the Player Class

The player will be the first entity we build for our game. Entities are anything that exist in the level that are not part of the map. Monsters, bullets, doors, triggers, etc., are all considered entities. Our player class will extend the core entity.js class so it can inherit some basic behavior to get us started. Let’s begin by creating a new player.js file in the lib/game/entities directory.

Our player class goes in the entities directory.

Figure 4-11. Our player class goes in the entities directory.

Now, add the following code to our file:

1    ig.module(
2        'game.entities.player'
3    )
4    .requires(
5        'impact.entity'
6    )
7    .defines(function(){
8        EntityPlayer = ig.Entity.extend({
10        });
11    });

This is the basic structure for creating entities in Impact. As discussed previously, we define the module name and reference any required classes, then define the class itself, extending ig.Entity. At this point, however, nothing will happen if you refresh your game. We still need to set up the player and add it to the level. To do that, let’s add some properties to this class.

Using Your Sprite Sheet

Start by setting up an animation sheet. Add the following to the EntityPlayer code block:

EntityPlayer = ig.Entity.extend({
    animSheet: new ig.AnimationSheet( 'media/player.png', 16, 16 ),

This tells our player that it will use player.png in the media folder and that its tiles are 16×16. We are also going to need to define some values for the size and offset of the player. We’ll add the following underneath where we set up our animation sheet:

size: {x: 8, y:14},
offset: {x: 4, y: 2},
flip: false,

The size property represents the actual size of the player. The offset property describes any change in the player size needed to make collisions more accurate. In this case, we’re offsetting the bounding box used for collisions by 4 pixels on the left and right, and 2 pixels on top and bottom. By making the collision area smaller than the sprite, we can better account for the transparent space around the graphic. Finally, we don’t flip the player, so it remains oriented in its original direction.

Adding Simple Physics

Next let’s set up some physics properties, such as velocity, friction, rate of acceleration in the ground and air, and jump strength.

maxVel: {x: 100, y: 150},
friction: {x: 600, y: 0},
accelGround: 400,
accelAir: 200,
jump: 200,

These properties define how our player can move in the environment. Impact handles all of the physics calculations for us. Once we get the player up and running, you should feel free to tweak these values to see how they affect your game.

Defining Animation Sequences

With the player’s core values out of the way, we can look into setting up animation sequences. Create an init() method underneath where we defined the properties in the player class and add the following code to it:

init: function( x, y, settings ) {
    this.parent( x, y, settings );
    this.addAnim( 'idle', 1, [0] );
    this.addAnim( 'run', 0.07, [0,1,2,3,4,5] );
    this.addAnim( 'jump', 1, [9] );
    this.addAnim( 'fall', 0.4, [6,7] );

This function passes the x,y and settings values up to the parent’s init() method. This is very important, since entities need to know their starting x,y positions and any settings assigned to them when being created in the level. You can also pass in additional values through the level editor, which get attached to the settings object during the construction of the entities.

As discussed earlier, it’s easy to set up animations. Use the entity class’s addAnim() method and pass it an ID (or name) for the animation, along with the duration and an array for the frames from the sprite sheet. Before we move on, let’s make sure your player class looks like this:

1    ig.module(
2        'game.entities.player'
3    )
4    .requires(
5        'impact.entity'
6    )
7    .defines(function(){
8        EntityPlayer = ig.Entity.extend({
9            animSheet: new ig.AnimationSheet( 'media/player.png', 16, 16 ),
10            size: {x: 8, y:14},
11            offset: {x: 4, y: 2},
12            flip: false,
13            maxVel: {x: 100, y: 150},
14            friction: {x: 600, y: 0},
15            accelGround: 400,
16            accelAir: 200,
17            jump: 200,
18            init: function( x, y, settings ) {
19                this.parent( x, y, settings );
20                // Add the animations
21                this.addAnim( 'idle', 1, [0] );
22                this.addAnim( 'run', 0.07, [0,1,2,3,4,5] );
23                this.addAnim( 'jump', 1, [9] );
24                this.addAnim( 'fall', 0.4, [6,7] );
25            }
26        });
27    });

At this point, we are ready to switch back over to Weltmeister and add our player. When you load the editor back up, you should see our dorm1.js level. If it’s not there, simply load it up manually. When you load the level, the entities layer should automatically be highlighted. This layer works just like the other layers we created, so move over to the Canvas area and press the space bar to see the list of entities you can add to the level. Right now, you should see the player from the drop-down menu.

Select the player from the pop-up entity menu.

Figure 4-12. Select the player from the pop-up entity menu.

Select the player and add him to the level. You can place him anywhere for now; I put mine on the far left of the level. Also, make sure you hit Save once you are happy with your player’s start position.

A preview of the player in the level editor.

Figure 4-13. A preview of the player in the level editor.

It’s also important to note that as of version 1.19 of Impact, you no longer need to add each entity to your game’s requires block; it is now automatically handled for you when the level is loaded. Now you are ready to test out your game. Go to your browser and hit refresh.

The player is now in our game’s level.

Figure 4-14. The player is now in our game’s level.

You should now see your player in the game, but you will not be able to move him. Let’s fix that. Go back into the player.js class and add the following update() function:

update: function() {
    // move left or right
    var accel = this.standing ? this.accelGround : this.accelAir;
    if( ig.input.state('left') ) {
          this.accel.x = -accel;
          this.flip = true;
    }else if( ig.input.state('right') ) {
          this.accel.x = accel;
          this.flip = false;
          this.accel.x = 0;
    // jump
    if( this.standing && ig.input.pressed('jump') ) {
          this.vel.y = -this.jump;
    // move!


As you continue adding code to your game, always make sure there is a comma to separate new functions, or you may get an error when you try to preview your code.

Now, you are ready to refresh the game and test out moving the player. As you can see, we can move our player, but he doesn’t animate or fall off ledges. We are going to need to set the gravity of the game. We can do this in main.js. Add the following property to that class:

MyGame = ig.Game.extend({
    gravity: 300,
    init: function() {

Now, if you go back to your game, you will be able to jump and fall off ledges. When you test it out, though, you will not have a clean-looking fall animation. Let’s add in some additional code to keep track of the player’s velocity in order to show the correct animation such as jump, fall, idle, and run. This should go below our jump code in the player.js class:

// set the current animation, based on the player's speed
if( this.vel.y < 0 ) {
    this.currentAnim = this.anims.jump;
}else if( this.vel.y > 0 ) {
    this.currentAnim = this.anims.fall;
}else if( this.vel.x != 0 ) {
    this.currentAnim =;
    this.currentAnim = this.anims.idle;

Now, we should be able to jump and run with corresponding animation, but there is one thing missing. We need a way to tell the player to flip his animation based on the direction he is running. We can do this by adding the following code just before the this.parent() call in the player.js update function:

this.currentAnim.flip.x = this.flip;

Now we have a fully functional player. Let’s give it one more test and make sure everything works. At this point, our level is kind of boring—so let’s add a few monsters to the game.

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

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.