Loading New Levels

It looks like we are ready to load our next level. Loading levels in Impact is incredibly easy; we actually did it as one of the first steps in setting up this game. In this section, I will talk about building something we call a trigger, which is an invisible area of the map that executes an activity when the player enters it. In this case, we will be building a level exit.

Let’s start by creating a new entity file called levelexit.js and add the following code to it:

12    ig.module(
13        'game.entities.levelexit'
14    )
15    .requires(
16        'impact.entity'
17    )
18    .defines(function(){
19        EntityLevelexit = ig.Entity.extend({
21        });
22    });

Since our exit doesn’t have any graphics, we still need something to display in Weltmeister. Let’s add the following properties to our class:

_wmDrawBox: true,
_wmBoxColor: 'rgba(0, 0, 255, 0.7)',
size: {x: 8, y: 8},

These two properties with the _wm prefix tell Weltmeister how to render the object in the edit view, even though it doesn’t have an actual graphic in the game. So, Weltmeister will draw an 8×8 pixel blue box.

Now, we need a way to store the name of the next level we should load when the player collides with the level exit entity. Add the following property, which will be automatically set during our entity’s construction by the settings parameter we will pass in from the level data:

level: null,

Next, we just need to add some collision code. Let’s have our level exit check against any TYPE.A entities by adding the following property to the top of your class:

checkAgainst: ig.Entity.TYPE.A,

Now, we will override update() and remove its call to this.parent() so we are not spending render cycles trying to draw an entity with no graphics. This is a great technique for any kind of triggers you may build for your map that aren’t required to be updated visually on every frame:

update: function(){},

Finally, we will also override the check() method to handle the collision:

check: function( other ) {
    if(other instanceof EntityPlayer){
          if( this.level ) {
               var levelName = this.level.replace(/^(Level)?(\w)(\w*)/, function( m, l, a, b ) {
               return a.toUpperCase() + b;
               ig.game.loadLevelDeferred( ig.global['Level'+levelName] );

As you can see, we simply test that the instance of other (which is passed into the method during a collision) is an instance of the player’s class. This helps avoid any other entity of TYPE.A you may have accidentally triggered in the level exit.

The last part of the code simply does a regex cleanup of the exit’s level property to make sure it is capitalized correctly before calling ig.game.loadLevelDeferred(). This method is very important. You may remember that in our main class, it simply called loadLevel(). Well, loadLevelDeferred() waits until the main game’s update loop is completed before loading the level. This will help avoid any sudden redraw errors that may happen when trying to exit in the middle of the render loop.

Once we have our new EntityLevelexit, we can open up Weltmeister and create a small exit to place our entity in.

Now we can see where we placed the level exit in the editor.

Figure 4-33. Now we can see where we placed the level exit in the editor.

When you add the level exit, you will need to tell it what level to load. Click on it and go to the layer area just under where it says Entity Settings. You should see all the properties of your entity instance. For the Key, put level and in Value, put dorm2.

Setting up a level property on the LevelExit entity.

Figure 4-34. Setting up a level property on the LevelExit entity.

It is very important that you hit Enter/Return after adding a value to an entity’s Key, or it will not be saved. You will know it has been saved when you see the new Key/Value listed under the entity’s name and its x,y values, which are set up by default. You can modify any Key by clicking on it.

Modifying entity properties in the level editor.

Figure 4-35. Modifying entity properties in the level editor.

Now that our entity is configured, we need to create a new level. Name your level dorm2 and design it as shown in Figure 4-36.

The second level of our game.

Figure 4-36. The second level of our game.

As you build out your new level you may notice that the player graphic is missing in the editor. This happens because now our player is set to invincible when he is created, so he is invisible. If this is an issue, you can add the following two properties to your player.js class:

_wmDrawBox: true,
_wmBoxColor: 'rgba(255, 0, 0, 0.7)',

This will render out a red box for the player when in the editor, just like we did with our level edit.

We use a red box to display the invisible player in the level editor.

Figure 4-37. We use a red box to display the invisible player in the level editor.

The last thing you need to do is add the level and the level exit to the main.js requires block:


Once you have done this, refresh your game and you should be able to exit the level and go into the second level.

You may notice that the transition is a little jarring. There are a few things you can do to make sure that doesn’t happen, such as matching the level exit and spawn points up, or building a quick transition before exiting the level. Usually, games have an end-of-level summary screen that gets displayed, so that when the next level loads up the player doesn’t notice the transition as much. We’ll talk more about this later in the book.

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.