How To Build Asteroids With the Impact HTML5 Game Engine: Boundry Checks

By Rob Hawkes  |  eMail Email    Print Print  

Boundary checks

The problem at the moment is that the asteroids disappear off the edge of the screen and never come back again. This is a bad thing. Jump back into the asteroids.js entity file and adding the following code underneath this.parent in the update function:

  1. // Boundary checks

  2. if (this.pos.x > ig.system.width) {

  3. this.pos.x = -64;

  4. } else if(this.pos.x < -64) {

  5. this.pos.x = ig.system.width;

  6. };

  7. if (this.pos.y > ig.system.height) {

  8. this.pos.y = -64;

  9. } else if (this.pos.y < -64) {

  10. this.pos.y = ig.system.height;

  11. };

What this does is check the position of the asteroid at the end of each update and, if it's outside of the game area, moves the asteroid to the other side of the game. This gives the effect of an infinite world where entities cannot be lost off the edge.

Player entity

Now that the basic asteroid entity is created, it's time to set up the player entity. Fortunately, most of the core logic is the same.

Create a new file called player.js and place it within the lib/game/entities folder. Add the follow code:

  1. ig.module(

  2. "game.entities.player"

  3. ).requires(

  4. "impact.entity"

  5. ).defines(function() {

  6. // Subclassed from ig.Enitity

  7. EntityPlayer = ig.Entity.extend({

  8. // Set the dimensions and offset for collision

  9. size: {x: 28, y: 50},

  10. offset: {x: 18, y: 7},

  11. // Entity type

  12. type: ig.Entity.TYPE.A,

  13. // Load an animation sheet

  14. animSheet: new ig.AnimationSheet("media/player.png", 64, 64),

  15. init: function(x, y, settings) {

  16. // Call the parent constructor

  17. this.parent(x, y, settings);

  18. // Add animations for the animation sheet

  19. this.addAnim("idle", 0.05, [0]);

  20. this.addAnim("thrust", 0.05, [1,2]);

  21. },

  22. // This method is called for every frame on each entity.

  23. update: function() {

  24. // Call the parent update() method to move the entity according to its physics

  25. this.parent();

  26. // Boundary checks

  27. if (this.pos.x > ig.system.width) {

  28. this.pos.x = -64;

  29. } else if(this.pos.x < -64) {

  30. this.pos.x = ig.system.width;

  31. };

  32. if (this.pos.y > ig.system.height) {

  33. this.pos.y = -64;

  34. } else if (this.pos.y < -64) {

  35. this.pos.y = ig.system.height;

  36. };

  37. }

  38. });

  39. });

There's nothing crazy new here. One difference is that the entity has a different name in the ig.module section, and also in the defines section. Another is that the size property isn't 64x64 pixels anymore; it's now 28x50 pixels, and the animation sheet is looking for the player sprite (which you can find in the game assets with this tutorial. The smaller size property represents the size of the rocket within the player sprite image, which you can see in this image:

Figure 7

The blue area is the area defined by the size property, and it's position is defined by the offset property. This is important for making sure the right area of the sprite is used when calculating collisions.

Finally, there are two animations being set up this time; one for when the player is standing still (idle), and another for when the player is moving (thrust):

  1. this.addAnim("idle", 1, [0]);

  2. this.addAnim("thrust", 0.05, [1,2]);

There are two frames in the thrust animation, meaning that the sprite will cycle from frame 1, to 2, and then back to 1 again. Each frame will be displayed for 0.05 seconds. You'll see this in a moment, but the effect will basically be a flickering flame.

The last step is to add the player entity into the main game file, just like you did with the asteroids earlier. Open up main.js and add the following line to the requires section at the top (remember to add a comma after the previous file):

  1. "game.entities.player"

Then add the following code above the init function:

  1. player: null,

And add the following underneath where you add the asteroids in the init function:

  1. // Load player entitiy

  2. var playerSettings = {};

  3. this.player = this.spawnEntity(EntityPlayer, 150, 150, playerSettings);

Nothing will show up yet so, just like with the asteroids, you'll need to move the player.png file from the game assets provided with this tutorial into the media folder.

Refresh the browser and you should see a little rocket in the top left hand corner. Cool!

Figure 8

Game background

Although this isn't a true entity, it's something we still need to set up. While you're still in main.js, add the following above the init function:

  1. background: new ig.Image("media/background.png"),

This sets up the background image, but it won't be drawn yet. To draw it you'll want to replace the this.parent line in the draw function with the following:

  1. // Draw the background

  2. this.background.draw(0, 0);

  3. // Draw all entities

  4. for(var i = 0; i < this.entities.length; i++) {

  5. this.entities[i].draw();

  6. };

This replaces the built in method for drawing game entities with one that you have a little more control over.

Still, before you can see it, you'll need to move the background.png file from the game assets into the media folder. The result should be a nice starry background to your game.

Figure 9

Adding keyboard controls

Even though you've added the player entity, you can't actually move it. That's not good, so let's work out how to add keyboard controls to the game.

Event listeners

The first step is to add the event listeners that will detect when a key is being pressed. Add the following code within main.js and place it at the top of the init function:

  1. ig.input.bind(ig.KEY.LEFT_ARROW, "left");

  2. ig.input.bind(ig.KEY.RIGHT_ARROW, "right");

  3. ig.input.bind(ig.KEY.UP_ARROW, "up");

  4. ig.input.bind(ig.KEY.ENTER, "play");

It should be fairly obvious as to which keys you're listening for here; left, right, up for moving the player, and enter for resetting the game when it's over. The names given to each event listener (left, right, up, and play) can actually be changed to any string that you want. However, I suggest that you leave them be, as you'll be using them again in a moment.

Moving the player

The whole point of adding the keyboard controls is to move the player around the game. Doing that is surprisingly straight forward, and shows the ease at which Impact can handle these things.

Jump into the player.js entity file and add the following code underneath the offset property at the top:

  1. // Angle, in degrees for more rotation granularity

  2. angle: 0,

  3. // Thrust, dictating how much to accelerate

  4. thrust: 0,

And add the following code above this.parent into the update function:

  1. // "input.pressed" is called once for every key press

  2. // "input.state" is called on every frame that the key is held down for

  3. if (ig.input.state("left")) {

  4. this.angle -= 3;

  5. };

  6. if (ig.input.state("right")) {

  7. this.angle += 3;

  8. };

  9. if (ig.input.state("up")) {

  10. // Accelerate the player in the right direction

  11. this.accel.x = Math.sin(this.angle*Math.PI/180)*this.thrust;

  12. this.accel.y = -(Math.cos(this.angle*Math.PI/180)*this.thrust);

  13. this.currentAnim = this.anims.thrust;

  14. } else {

  15. this.accel.x = 0;

  16. this.accel.y = 0;

  17. this.currentAnim = this.anims.idle;

  18. };

  19. // Set the angle for the current animation

  20. this.currentAnim.angle = this.angle*(Math.PI/180);

This may look like a lot, but it's surprisingly little for adding full control over the player movement. Let me explain what's going on.

The first conditional statement is looking at ig.input.state("left"), which means that it is requesting the current state of the keyboard event that you called "left" in the previous section (this is why it was important not to change those names). If that key is currently being pressed down, then the ig.input.state method will return true, else false.

In the case of the left and right keys, you're increasing or decreasing the angle property of the player depending on which key is being pressed. Then, in the case of the up key, you're using that angle, along with the thrust property, to calculate the acceleration of the player in the angle that they're headed. This is based on fairly standard trigonometry, which I suggest you learn about to fully understand.

Also, with the up key you're switching the animation of the player to the "thrust" animation if the key is being pressed (the player is moving), and then back to the "idle" animation if the key isn't being pressed (the player is still).

Finally, you use the angle property of the player to set the angle of the sprite image. This line is important, as the image won't change angle otherwise. The crazy formula at the end is just converting the angle from degrees to radians, as that is what JavaScript works in.

If all went well, you should now be able to rotate the player with the left and right keys, and trigger the flame animation with the up key.

Figure 10

But why isn't the player moving forward? This is because you haven't set the thrust property to something other than zero. Head back into the main.js file and change the playerSettings line to the following:

  1. var playerSettings = {thrust: 250, maxVel: {x: 300, y: 300}};

The maxVel property is used to limit how fast the entity can travel, which is very useful for stopping the player from accelerating to near the speed of light.

Give this a go in the browser; you should now be able to fly the rocket around the screen with some pretty realistic feeling physics. Nice one!

Figure 11

Page 3 of 4

Previous Page
1 2 3 4
Next Page

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
  • Html5 Logo