You are previewing Building HTML5 Games with ImpactJS.

Building HTML5 Games with ImpactJS

Cover of Building HTML5 Games with ImpactJS by Jesse Freeman Published by O'Reilly Media, Inc.
  1. Introducing HTML5 Game Development
  2. SPECIAL OFFER: Upgrade this ebook with O’Reilly
  3. A Note Regarding Supplemental Files
  4. Preface
    1. About This Book
    2. Who This Book Is For
    3. Who This Book Is Not For
    4. Conventions Used in This Book
    5. This Book’s Example Files
    6. Using Code Examples
    7. How To Use This Book
    8. Safari® Books Online
    9. How to Contact Us
    10. Acknowledgments
  5. 1. Introduction To Impact
    1. Why Use Impact?
    2. Setting Up a Local Environment
    3. Install WebStorm/PHPStorm
    4. Install Apache/PHP/MySQL
    5. Other Hosting Options
    6. Setting Up a New Impact Project
    7. Modules
    8. How Classes Work
    9. Core Classes
    10. How Inner Classes Work
    11. Level Editor
  6. 2. Working With Sprites
    1. Sprites and Sprite Sheets
    2. Scripting in Photoshop
    3. Working with Sprites in Photoshop
    4. Optimizing Sprites
  7. 3. Introduction To Game Design
    1. What is Game Design?
    2. Sample Game Design Document
      1. Gameplay
      2. Exploring a Map
      3. Combat
      4. Completing a Map
      5. Death
      6. Main Character
      7. Monsters
      8. Bosses
      9. Equipment
      10. Inventory
      11. Equipping Items
      12. Weapons and Armor
      13. Leveling Up
      14. Winning the Game
    3. Coming Up With Ideas
    4. Books to Read
  8. 4. Building A Game
    1. Creating Our First Level
    2. Saving/Loading Maps in Weltmeister
    3. CollisionMaps
    4. The Main Class
    5. Customizing the Main Class
    6. Key Binding
    7. Creating the Player Class
      1. Using Your Sprite Sheet
      2. Adding Simple Physics
      3. Defining Animation Sequences
    8. Creating a Monster Class
    9. Collision Detection
    10. type Property
    11. checkAgainst Property
    12. collides Property
    13. Health
    14. Weapons
    15. Firing the Weapon
    16. Add Multiple Weapons
    17. Killing Entities
    18. Respawning the Player
    19. Create Death Animations
    20. Adding Grenade Explosions
    21. Customizing the Camera
    22. Loading New Levels
  9. 5. Working With Text
    1. Creating Font Sprite Sheets
    2. Adding Text to Your Game
  10. 6. Working With Sound
    1. Adding Sounds
    2. Adding Music
    3. Mobile Browser Sound Compatibility Issues
  11. 7. Creating Game Screens and HUDs
    1. Extending Impact’s Game Class
    2. Creating a Start Screen
    3. Player Stats Screen
    4. Creating the Game Over Screen
    5. Adding In-Game HUD
    6. Game Rewards
    7. In-Game Analytics
  12. 8. Debugging Your Game
    1. Impact’s Debugger
    2. Publishing Your Game
    3. Baking Your Game
    4. Mobile Web Support
    5. Compiling for Native iOS
  13. 9. Wrapping Up
    1. References and Links
  14. About the Author
  15. SPECIAL OFFER: Upgrade this ebook with O’Reilly
O'Reilly logo

Create Death Animations

One of the easiest ways to show a death animation is to create a small particle explosion where the player is killed. Not only does this cut down on the amount of animations you have to create but you can also use the same technique to show damage taken by a projectile weapon. In order to do this, we will need to create two new entities, one for the explosion and the other for the actual particles. Let’s add the following inner class to our player.js module:

EntityDeathExplosion = ig.Entity.extend({
    lifetime: 1,
    callBack: null,
    particles: 25,
    init: function( x, y, settings ) {
          this.parent( x, y, settings );
          for(var i = 0; i < this.particles; i++)
               ig.game.spawnEntity(EntityDeathExplosionParticle, x, y, {colorOffset: settings.colorOffset ? settings.colorOffset : 0});
               this.idleTimer = new ig.Timer();
    },
    update: function() {
          if( this.idleTimer.delta() > this.lifetime ) {
               this.kill();
               if(this.callBack)
                     this.callBack();
               return;
          }
    }
});

This is a very simple class. It handles spawning particle entities, which we will create next, and also has a timer, which we use to call a callback() method that is supplied by the setting property. Pay special attention to this.idleTimer and the new ig.Timer(). We use these to keep track of how much time has elapsed since its instantiation, just like we did when we added invincibility to the player.

There is also something else going on here. You may have noticed that when we spawn our EntityDeathExplosionParticle, we are passing in a color offset value. If you take a look at the blood sprite, you will see that we have colored sprites for the player in red and for the zombie in green.

This sprite contains the player and zombie blood particles.

Figure 4-27. This sprite contains the player and zombie blood particles.

This is a neat trick and one that is used in a lot of sprite sheet-based games. Our blood particles are going to be 2×2 pixels in size. That means we have eight sprites for each color. When we set up our particle, we will apply the color offset to the graphic we display. So if the player is hit, we will add 0 to the offset, which will generate a random red color. For zombies we will add 1 to the offset, which will multiply by the base number of possible sprites and move the randomly selected sprite into the green zone. Let’s take a look at our particle class to see this in action. Create a new inner class with the following code:

EntityDeathExplosionParticle = ig.Entity.extend({
    size: {x: 2, y: 2},
    maxVel: {x: 160, y: 200},
    lifetime: 2,
    fadetime: 1,
    bounciness: 0,
    vel: {x: 100, y: 30},
    friction: {x:100, y: 0},
    collides: ig.Entity.COLLIDES.LITE,
    colorOffset: 0,
    totalColors: 7,
    animSheet: new ig.AnimationSheet( 'media/blood.png', 2, 2 ),
    init: function( x, y, settings ) {
        this.parent( x, y, settings );
        var frameID = Math.round(Math.random()*this.totalColors) + (this.colorOffset * (this.totalColors+1));
        this.addAnim( 'idle', 0.2, [frameID] );
        this.vel.x = (Math.random() * 2 - 1) * this.vel.x;
        this.vel.y = (Math.random() * 2 - 1) * this.vel.y;
        this.idleTimer = new ig.Timer();
    },
    update: function() {
        if( this.idleTimer.delta() > this.lifetime ) {
            this.kill();
            return;
        }
        this.currentAnim.alpha = this.idleTimer.delta().map(
            this.lifetime - this.fadetime, this.lifetime,
            1, 0
        );
        this.parent();
    }
});

As you can see, the particle has a few properties such as its maximum velocity, how long before it fades away, bounciness, and initial velocity. Most of this should look very familiar from what we did with our grenade class. As you can see in the init() method, we assign a random value to the particle’s vel.x and vel.y values, which sends each one off in different directions. Since this is blood and we don’t want it bouncing around like the grenade, the bounciness property is set to 0. We take advantage of this.currentAnim.alpha value, which assigns a new alpha value after each update, and eventually the particle disappears. Once it fades away, we call kill() to remove it from the display.

Now that we have our particle emitter and our particle, we can extend the player’s kill() method to spawn our EntityDeathExplosion where the player was killed and watch it spawn random particles as if the player exploded. Here is the modified EntityPlayer kill() method:

kill: function(){
    this.parent();
    var x = this.startPosition.x;
    var y = this.startPosition.y;
    ig.game.spawnEntity(EntityDeathExplosion, this.pos.x, this.pos.y, {callBack:function(){ig.game.spawnEntity( EntityPlayer, x, y)}} );
}

Since we are passing a function into the settings object, we will need to re-scope the start position of the player. If you refresh your browser and run the player into the monster, you will now see him explode into tiny pieces that bounce and fade away.

The player now explodes into pieces.

Figure 4-28. The player now explodes into pieces.

As I mentioned before, this is also a great effect for us to show when an entity has been hit. Let’s override the zombie.js receiveDamage() method with the following:

receiveDamage: function(value){
    this.parent(value);
    if(this.health > 0)
          ig.game.spawnEntity(EntityDeathExplosion, this.pos.x, this.pos.y, {particles: 2, colorOffset: 1});
},

We can actually use the same death explosion class in our zombie entity, even though it is an inner class of player. This is a neat little hack thanks to the fact that JS’s scope is global and, when any entity gets defined in Impact, it is available throughout the game engine. So, in the EntityZombie class, we simply spawn a new death explosion just like we did in the player class, but pass in a smaller number of particles to be emitted. We also pass in the colorOffset so that we can display green blood instead of red. Now when a bullet hits the zombie, little particles will shoot off of it. Also, don’t forget to use the same death animation technique we used on the player by overriding the zombie.js kill() method with the following:

kill: function(){
    this.parent();
    ig.game.spawnEntity(EntityDeathExplosion, this.pos.x, this.pos.y, {colorOffset: 1});
}

And there you go; you have just created a nice-looking dynamic death animation for your player and monster. We can also apply the same technique to our grenades and make their explosions more visually appealing, so let’s take a look.

The best content for your career. Discover unlimited learning on demand for around $1/day.