Let’s build an HTML5 game! (Beginner Tutorial, Part 2)

Let’s build an HTML5 game! (Beginner Tutorial, Part 2)

In our last tutorial, we covered prototyping a game with JS Bin. JS Bin is a great tool for testing pieces of javascript and playing around with ideas. Now that we have the basics of our HTML5 game, we should probably move to a more suitable IDE.

Note: This is the second article in a series. Feel free to start from the beginning.

Cloud Development with Codio

I’ve recently discovered an online cloud based IDE called Codio. You can get the skinny here at Web App List or just head over to Codio directly. We will be using Codio to finish off our HTML5 game tutorial. If you want, you can just continue using JS Bin, but this tutorial will include instructions on using Codio. The basic account is free for public projects, so go ahead and sign up. I used the GitHub account option.

Once you are signed in:

  1. Click the “New Project” button.
  2. Give your project a name. I used “Simple HTML5 Game”.
  3. Leave the Public project type selected.
  4. It should be defaulted, otherwise choose the “HTML5 Boiler Plate” Template
  5. Create!

After you click the “Create” button the IDE will load and a list of files will display on the left side of Codio. Open the index.html page. Once open, use the live preview option which is a dropdown just to the left of your name in the top control panel.

codio-preview-button

This will preview the index.html page for you in a preview pane.

codio-preview-pane

Ok, there are a few steps we need to do before we start coding again. We need to:

  1. Copy our HTML code into the index.html file.
  2. Create a separate javascript file for our jquery-nearest plugin.
  3. Create a new javascript file to hold our game code.
  4. Create a new css file.
  5. Link our new javascript and css files in our index.html page.

So first of all, let’s open our JS Bin page from Part 1. Copy the contents of the body tag (which is only one DIV  element) and paste it over the sample comment and HTML in the Codio index.html file. Note that we ONLY want to replace these two lines:

With this line:  <div id=stage> </div>

 

Leave all the other code intact inside the body  tag. Next, copy our script  tag for including GSAP. You will note that jQuery is already included, so we won’t need to copy/paste that one. Just paste in this line below the jQuery script  tag.

Now, let’s right-click on the js folder and create a new file which we will name “jquery-nearest.js” and choose “javascript file” for the file type.

Inside this file, paste our jquery-nearest code that we placed inside of a <script>  tag in the HTML tab of our JS Bin project.

The project already has an empty javascript file created and linked for us, called main.js inside the js folder. Let’s paste all of our javascript from the JS tab in JS Bin into that file. Normally I like to separate my code into several files, but for the sake of this tutorial, I will keep it all together.

Let’s right click on the css folder and create a file named “game.css”. In here we will paste the css code from our CSS tab from JS Bin.

Inside the <head> tag in our Codio index.html paste the following link:

and then paste this link to our jquery-nearest plugin right above the main.js script tag:

NOTE: We could have just pasted the jquery-nearest code into the plugins.js file, but the traditionalist in me likes to keep things separate during development.

Ok! Refresh your preview page and you should the prototype game working as we left in JS Bin.

Now, we can move on to some simple collision detection. We are using square objects, so collision detection is rather trivial for us.

If we take a look at the GSAP TweenMax.to documentation, we see that there is an optional onUpdate parameter for this function and a related onUpdateParams parameter as well. This parameter takes a javascript function which is called once every update cycle, or once per frame.

Wait, what happened to the Game Loop?

Let me pause here fro a brief moment to discuss an important topic. Most games traditionally have what is called a “game loop” which is called once per frame to update all the game logic. While this approach is used in most games, I use what I call an “event driven” approach to casual HTML5 games. Please note that this approach is not the best approach for every game type, but in my honest opinion, it works very well for casual HTML5 games. GSAP will handle using the best approach to rendering our animations, so we won’t have to worry about the lower lever stuff it does under the hood.

Event Driven Game Method

So, with that said, we are going to attach a listener to each object that we wish to perform collision detection on and let each object handle that itself.

Back to our TweenMax.to function. We are going to let our bullet object do the dirty work here. Let’s review the animation code for our bullet.

The onUpdate  and onUpdateParams  are actually part of the VARS object in our TweenMax.to  function, so these will get added to our comma delimited vars list along with the top and left properties. Let’s expand our function to look like this:

We added our onUpdate  param with a value of detectBulletCollision , which you can see is a new function we will add as well. The onUpdateParams  param is an array [ ]  with, in this case, only one item; a reference to our jQuery bullet object.

Each time the bullet updates now, we can use our detectBulletCollision function to determine if the bullet is colliding with an enemy. I will point out here that each active bullet will have its own collision detection routine running. Let’s check now for collisions.

The basic method of detecting collisions is this:

  1. Get a reference to all enemy objects
  2. Check to see if our bullet resides within the bounds of each enemy
  3. If it does, remove both the enemy and the bullet.

I usually optimize my detection routine to only check enemy objects that are close to my object which has the update function, but again, for simplicity I will just check each enemy object for this tutorial. If you are interested in more advanced methods, please leave a comment and I will try and make that the subject of another tutorial.

So, step one: Get a reference to all enemy objects. For this step, we are going to utilize jQuery to quickly loop through all of our enemy objects.

This is jQuery’s each  function. It grabs all of the DOM elements that match the given selector and loops through all of them one at a time. It exposes the counter which we see here as the parameter index. While we don’t always need the counter, I include it here for those that might not know it exists.

Now, step two: Check to see if our bullet resides within the bounds of each enemy. Here we need a little math:

The jQuery position() function doesn’t provide a right or bottom property, so we calculate those by using left + width and top + height. To make things a tad more readable, we use a new variable named $e  to refer to our current enemy object. $(this)  refers to the current enemy object as we loop through our enemy list. A good refactoring would be to create a Rect Object with all four properties and use those to pass to a generic collision detection routine. Homework!

If you open your developer tools (depending on which browser you are using) and view the console output, you will see the word ‘collision’ printed each time a bullet enters the same space as an enemy. Typically you will see multiple instances as it will update several times before it pass through to the other side of the enemy.

Now for step 3: Remove both the enemy and the bullet.

For this exercise, we will simple hide both of the objects and handle removing them later. Replace the console.log(‘collision’); line with these two lines:

Now when you run the code, the enemies are vanquished from site upon collision!

Let’s tidy things up just a tad and only check collisions on enemies that are visible and only fire bullets if there are visible enemies. Add a :visible  attribute to our .enemy  selector to take care of the first one. Our collision detection now looks like this:

Jump back to our fireBullet function and add an if statement like so:

When jQuery is given a selector and returns, it will have a length  property regardless of whether or not it found something. If this is greater than zero, we know we have visible enemies, otherwise, nothing to shoot at!

Adding Drag-n-Drop

Now, lets pizaz up our game by adding some drag and drop functionality for adding defense objects.

First off, let’s add some more javascript files. Add these two lines under our TweenMax script on our index.html file:

This will include the Draggable plugin from GSAP.

Now, we will modify our original HTML and add a new container below our stage. Our lonely stage DIV expands to become this:

And we will add this to our game.css file:

We will need to remove or comment out two lines from the top of our main.js file:

These will get added again in a bit, but from within our drag and drop routine. Let’s create a function called initToolBox  with a parameter of level . Each level, we will add another defense object.

Below the two lines we just commented out, add this:

This will add one defense object to our toolbox and allows for more to be added later. Now, we need to setup our Draggable plugin.

Right after our appendTo function and before we increment our y variable, add the following code:

This transforms our defense object that we just added to the toolbox into a GSAP Draggable object, which allows us to click and drag (or touch and drag on a touch screen) our defense object onto the stage. You notice we have an onDragEnd  attribute with a supplied function, so let’s setup that function too.

This function does a few things. First, we get a reference to our Draggable object. Then, we add a new defense object. This purpose of this is to have the defense object reside as a child of our stage. Coordinate calculations are just easier this way. Then, disable the Draggable and hide/detach our draggble defense object from the DOM.

Now, we just expand this and modify our fireBullet function from Part 1 in order to start firing bullets again. Let’s go ahead and un-comment our setInterval  statement:  window.setInterval(fireBullet, 1000); so that it executes again.

We will make the following modification to our fireBullet and animateBullet  functions as well:

We’ve changed up how we add the bullet. We now tween (animate) the bullet to the correct location in order to better animate it and we changed numbers inside our animateBullet  call to further tweak where the bullet finishes its animation. We are aiming for the center of the enemy. The extra 12 takes us 12 pixels to the right of the left side of the box. The box is 25 pixels wide so that is 1/2 a pixel from center. The 70 additional pixels on the y axis ensure the enemy doesn’t run away from our bullet. You can tweak these further to better suit your tastes.

Our animateBullet function has been updated to use x/y instead of left/top.

We also updated our createDefense  function as well:

We are adding two HTML attributes, x  and y , so we can retrieve the real position of our object. I’ve also updated the variable name as I didn’t change it when I copied it from the createEnemy function in Part 1 and added the active-defense  class.

Wrapping it up

So, what have we accomplished here? We moved our prototype to a better IDE. The reason I start with JS Bin is that I find it easier to throw away bad ideas. Once I fiddle my way into an idea I want to continue exploring, then I move to something more serious.

We have explored some simple collision detection by determining if one rectangle is not overlapping another rectangle.

Then we spiced things up with a bit of drag and drop. In our next tutorial, Part 3, we will look at adding levels and keeping score. I hope you enjoyed this series so far and please let me know what you think in the comments below.

Feel free to discuss this in our forums.

 

 

agrothe (9 Posts)

Andrew Grothe is an enterprise developer with an interest in HTML5 mobile and game development. Andrew is current working on a casual HTML5 game at http://spacecutegame.com and maintains the http://webapplist.info website.