Build a game using the DOM – Part 4

March 11th, 2012

Previously on Build a game using the DOM, in part 1 we made a block move around with the arrow keys, in part 2 we made our block shoot lasers and in part 3 we added enemies that we could shoot. We could stop here and call the game “Invincible laser shooting block” but I think that would get boring after a while. So, we’ll set it up so that if our block hits an enemy block, we reset the game back to the start positions. And then we’ll add a score and lives so the game isn’t infinite.

The first thing we’re going to do is add the ability for our game to check if our block is in contact with one of the enemies. We’ll do this by altering the moveEnemies function since we already have loop running that we can take advantage of.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function moveEnemies() {
   if (enemies.length < enemyTotal) {
       var enemy = new Enemy();
           enemies.push([enemy, enemyPos.y]);
           playArea.appendChild(enemies[enemies.length - 1][0]);
           enemies[enemies.length - 1][0].classList.add('enemy');
           enemies[enemies.length - 1][0].style.top = enemies[enemies.length - 1][1] + 'px';
           enemies[enemies.length - 1][0].style.left = Math.floor(Math.random() * 500) + 'px';
   }
   for (var i = 0; i < enemies.length; i++) {
       enemies[i][1] += enemySpeed;
       enemies[i][0].style.top = enemies[i][1] + 'px';
       
       // new stuff
       var ex = parseInt(enemies[i][0].style.left),
             ey = parseInt(enemies[i][0].style.top),
             ew = ex + parseInt(enemies[i][0].offsetWidth),
             eh = ey + parseInt(enemies[i][0].offsetHeight),
             sx = parseInt(ship.style.left),
             sy = parseInt(ship.style.top),
             sw = sx + parseInt(ship.offsetWidth),
             sh = sy + parseInt(ship.offsetHeight);

       if (parseInt(enemies[i][0].style.top) > (playArea.bottomBoundary + enemies[i][0].style.height)) {
           enemies[i][1] = enemyPos.y;
           enemies[i][0].style.top = enemies[i][1] + 'px';

       // new stuff
       } else if (sx >= ex && sx <= ew && sy >= ey && sy <= eh) {
           checkLives();
       } else if (sw <= ew && sw >= ex && sy >= ey && sy <= eh) {
           checkLives();
       } else if (sh >= ey && sy <= eh && sx >= ex && sx <= ew) {
           checkLives();
       } else if (sh >= ey && sh <= eh && sw <= ew && sw >= ex) {
           checkLives();
       }
   }
}

I’ve marked the new content with the ultra descriptive new stuff comment. Inside the for loop, we add a bunch of new variables that we use to get the position of the current enemy in the loop and the position of the player. The variable ex = the enemy’s x position and ew = the x position and the width of the enemy. Doing this with the y position and height as well enables us to figure out if the player overlaps any part of the enemy. We don’t have to declare variables for these values, we could just plug in the longer code in the next part, but this really simplifies it and makes it easier to read.

Next we add some else if statements to our existing if statement. Here is where we check if our player has overlapped the enemy block and if it has, then we run a function called checkLives. Why are there for if statements to check this? The way I think about it is we need to check for each corner of the player’s block and to do this we need an if statement for each corner. If you look at the code, we’re really checking if, as in the first one, the player’s x position is greater than the enemy’s x position but less than the enemy’s x position plus it width and if it’s y position is great than the enemy’s y position but less than it’s y position and it’s height. If this is true, then we know that the top left corner of our player’s block is inside the enemy and it’s a hit. Now we need to write the checkLives function.

First we need to add something to our variables at the top, you can add this up the other createElement variables to keep things organized:

1
gameOverText = document.createElement('h1')

This is for the text we’ll display when the player runs out of lives, which we also need to create a variable for. And finally we need to make a variable to check if the game is over:

1
2
lives = 3,
gameOver = false

Add that at the end of the variables at the top of the code. Now, on to the checkLives function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function checkLives() {
   if (lives > 1) {
       resetGame();
   } else {
       playArea.removeChild(ship);
       for (var i = 0; i < enemies.length; i++) {
           playArea.removeChild(enemies[i][0]);
       }
       if (lasers.length > 0) {
           for (var i = 0; i < lasers.length; i++) {
               playArea.removeChild(lasers[i][0]);
           }
       }
       gameOver = true;
       playArea.appendChild(gameOverText);
       gameOverText.classList.add('game-over');
       gameOverText.innerHTML = 'Game Over';
   }
   lives -= 1;
}

The purpose of the checkLives function is to see if the player has more than 0 lives. If they do, we run a function called resetGame, which we’ll write next, and subtract 1 life. If they don’t, then we remove everything from the play area, add the gameOverText which we set the innerHTML to equal ‘Game Over’ and set gameOver to true. Pretty simple.

Before we write the resetGame function, we need to add some variables and then we need to add a couple of lives of code where we set up the game. We have an object called shipPos that we use to position our player and it looks like this:

1
2
3
4
shipPos = {
   x: 0,
   y: 0
}

For the resetGame function to work, we need to get the starting position of the player and save it because at the beginning, we’re setting the start position dynamically based on the width and height of the play area. Update shipPos to this:

1
2
3
4
5
6
shipPos = {
   x: 0,
   y: 0,
   startX: 0,
   startY: 0
}

And then after where we set shipPos.x and shipPos.y, we need to add a couple of lines:

1
2
3
4
shipPos.x = (playArea.offsetWidth / 2) - (ship.offsetWidth / 2);
shipPos.y = playArea.offsetHeight - (ship.offsetHeight * 2);
shipPos.startX = shipPos.x; // new lines
shipPos.startY = shipPos.y; // new lines

Now that we have those set, we can reset the player to their starting position when they lose a life.

1
2
3
4
5
6
7
8
9
10
11
12
13
function resetGame() {
   shipPos.x = shipPos.startX;
   shipPos.y = shipPos.startY;
   ship.style.left = shipPos.x + 'px';
   ship.style.top = shipPos.y + 'px';
   enemyPos.x = 150;
   for (var i = 0; i < enemyTotal; i++) {
       enemies[i][1] = enemyPos.y;
       enemies[i][0].style.top = enemies[i][1] + 'px';
       enemies[i][0].style.left = enemyPos.x + 'px';
       enemyPos.x += 150;
   }
}

With resetGame, we reposition the player back to the starting position and then we reposition all the enemies back to their starting positions. And lastly for the lives part of this tutorial, we have a change to make to our loop function:

1
2
3
4
5
6
7
8
function loop() {
   if (gameOver === false) { // new stuff
       moveShip();
       moveEnemies();
       moveLasers();
   }
   requestAnimFrame(loop);
}

Now we only run the functions that move our elements around if gameOver is false, so when the player runs out of lives, we don’t run those functions that wouldn’t do anything. You’ll notice one other difference from part 3, instead of setTimeout, I’ve using requestAnimFrame to run the loop. This is a function created by Paul Irish to use the requestAnimationFrame if the browser can or else use setTimeout. I’ve just created a seperate JS file so I can just link to it when I need it for a project. Just make sure you link to it before the game code.

1
2
3
4
5
6
7
8
9
10
window.requestAnimFrame = (function(){
 return  window.requestAnimationFrame       ||
         window.webkitRequestAnimationFrame ||
         window.mozRequestAnimationFrame    ||
         window.oRequestAnimationFrame      ||
         window.msRequestAnimationFrame     ||
         function(/* function */ callback, /* DOMElement */ element){
           window.setTimeout(callback, 1000 / 60);
         };
})();

Next up is keeping track of the score and it’s probably a pretty good idea if the player knows how many lives they have left, so we’ll add that too. First thing we’ll do is add some CSS, including some styling for our game over text, which you might have noticed we gave the class of game-over to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.score-div {
   position:absolute;
   top:10px;
   left:10px;
}
.score-label, .lives-label {
   font-family:Arial, Helvetica, sans-serif;
   color:#fff;
   font-weight:bold;
   margin:0;
   font-size:20px;
}
.lives-div {
   position:absolute;
   top:40px;
   left:10px;
}
.game-over {
   font-family: Arial, Helvetica, sans-serif;
   margin-top:240px;
   text-align:center;
   color:#fff;
}

This will position our score and lives divs in the upper left corner and it will center the game over text when that’s on screen. Now the JavaScipt:

1
2
3
4
scoreDiv = document.createElement('div'),
scoreLabel = document.createElement('p'),
livesDiv = document.createElement('div'),
livesLabel = document.createElement('p')

Add these lines up with the other createElement variables and then add these at the end of the variables:

1
2
3
scoreText = 'Score: ',
score = 0,
livesText = 'Lives: '

Next, after the section where we set up the game, add this block of code:

1
2
3
4
5
6
7
8
document.body.appendChild(scoreDiv);
scoreDiv.classList.add('score-div');
scoreDiv.appendChild(scoreLabel);
scoreLabel.classList.add('score-label');
document.body.appendChild(livesDiv);
livesDiv.classList.add('lives-div');
livesDiv.appendChild(livesLabel);
livesLabel.classList.add('lives-label');

This code has the same stuff going on as when we’re creating the player and enemy blocks. We add the scoreDiv and the livesDiv to the body and give them the classes score-div and lives-div respectively. Then we add the labels which will hold our text inside the divs. Next, inside the checkHit function, inside the if statement where we remove the laser and enemy if it’s been hit, add this line:

1
score += 100;

Now, for every enemy that’s killed, the score will go up by 100 which is all well and good but we also need to update the score text so the player can see it.

1
2
3
4
function updateScore() {
   scoreLabel.innerHTML = scoreText + score;
   livesLabel.innerHTML = livesText + lives;
}

Really simple function here, we just update the text inside the scoreLabal and the livesLabal p tags. Of course, if we still have to call the function and we’ll do that in the loop function. Updated it to look like this:

1
2
3
4
5
6
7
8
9
function loop() {
   if (gameOver === false) { // new stuff
       moveShip();
       moveEnemies();
       moveLasers();
   }
   updateScore();
   requestAnimFrame(loop);
}

Now if you run the game, you’ll have score, lives and a game over screen. A fair amount of code, but none of it was too complicated, especially when compared to the previous steps. You can check out the demo here. I’ve marked all the new code in case you want to go through it.

Next time, we’ll finally add graphics, a start screen and a start over button on the game over screen.

If you’re on a journey to become a good developer, keep at it

March 4th, 2012

There’s a gap on the journey to being an expert developer that they don’t tell you about. It’s like a canyon you come across on your trip from beginner to expert. Imagine that learning to program is like walking from one town to another across a field and halfway there you come across a deep canyon. How many people get to this canyon, see how much work it will be to get across and turn back or just stay where they are? Think of when you first start to program, you do all the beginner tutorials and you look at all the amazing stuff being create by the best. And you see no reason why you can’t being creating things just as amazing soon. It’s just like walking across that field and seeing the great things in the distance but you can’t see the canyon yet.

When you start learning to code, you do the examples in a book or the tutorials on a website but you can’t build things on your own, you need an example. You come to the edge of that canyon the first time you need or want to build something that doesn’t have a step by step example. But even then, you could find something similar that someone else has built and if it’s possible, if it’s something build with JavaScript or even in Flash, you can take a look at what they did. But more times than not, you won’t be able to decipher what they’ve done. You’re looking at code that makes little sense to you. Or you know you want to create but the code you think should work, doesn’t.

For me, this felt like I was at the cliff face of that canyon and I knew if I was going to be as good as I wanted to be, I was going to have to climb down that wall, down into that deep canyon. Gone were the days of doing fun tutorials where I build a Twitter search app using jQuery, now I realized I had to learn why the code did what it did. I had to read the thousand page book and learn the proper syntax, learn the built in methods, learn the right way to write code. I’d entered that period where I knew enough to know how much I didn’t know. When you’re down on that canyon floor and you look up at where you want to be, it seems farther away then ever. This, to me at least, was the hardest point. This is when things can stop being fun, when it becomes a grind. This is when you look at what the experts are doing and think to yourself, “I’m never going to be able to do that”.

You’ll also discover something else at this point, remember all those beginner tutorials? There’s a ton of them out there so there should be a bunch of intermediate ones to help you get to the next level. But there’s not really. For the most part, you’ll find that besides those beginner tutorials, the rest are articles written by really smart people about complex things you kind of understand but not really. In fact, some of the stuff you’ll read will make you think that the side of the canyon you have to climb up is twice as high as the one you climbed down. I wonder how many people get to this point and give up. Perhaps you know enough to do some of the stuff you want to, and maybe you don’t plan on doing anything really complex.

There’s other factors too. When I first started learning ActionScript 3, gotoandlearn.com was a huge source of learning for. But then when I would do a tutorial by someone with a different coding style, I’d find myself getting lost. This can be even worse when you’re trying to learn something like JavaScript, which has some many different ways to do the same thing, sometimes you wonder if people are using the same language.

Maybe you don’t get out of that canyon, maybe most of us don’t. Most of us don’t work for Google or Mozilla, where our job is figuring out how to use the latest browser features. Instead, we are building things for clients and we get to figure out something new because a client wants a feature we’ve haven’t built before. Maybe it takes a while to get out because you’re like me and 95% of the experimental stuff you do is at home while you’re watching Fringe. You’re doing this because you love it. Maybe it doesn’t matter that you never get out of that canyon, just trying is enough.

You’re going to frustrated. You’re going to get depressed. You’re going to look at other people’s work and wonder if you’re ever going to be able to do that. Just remember, everyone was a beginner once. No one starts out as an expert. Keep hacking away, something will click and you’ll understand and then something else will click and you’ll understand even more. Don’t compare yourself to anyone else, just compare yourself to you yesterday or last week or a month ago. If you’re better now then you were then that’s all that matters.

Update content with contenteditable and jQuery

March 1st, 2012

Recently, I built a site for a client where they wanted to have the ability to make edits to some of the content on the site. Since I wasn’t using full blown content management system for it, they could just add events and news items, I didn’t want to have to write a huge WordPress like editing system. So I decided to see if it was possible to just let them edit the content right on the page if they were logged in as an admin. I’m not going to show any PHP for two reasons, if you don’t know anything about PHP, you probably shouldn’t be messing around with this yet and there’s a ton of tutorials out there to show you how to create an admin system and how to update a database. We’re going to focus on the jQuery because that’s the part that’s the most fun and it’ll make you cool at the office.

1
2
3
4
5
6
7
8
9
<div class="content">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
          tempor incididunt ut labore et dolore magna aliqua.</p>
    <p class="edit">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
          fugiat nulla pariatur. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
          nisi ut aliquip ex ea commodo consequat.</p>
    <p class="edit">Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
          deserunt mollit anim id est laborum.</p>
</div>

Here’s the HTML we’re going to work with. We have three paragraph tags inside a div with the class of content. Two of the paragraph tags have a class of edit. To make this work, we’ll do this, if the user is logged in, then our JavaScript file will be loaded and our jQuery will run. We’ll add set the contenteditable attribute of the paragraph tags with the class of edit to true and then add a save button for the user to click when they’re done editing.

1
2
3
4
5
6
(function() {
    var content = $('.content'),
          edit = $('.edit');
          edit.attr('contenteditable', 'true');
          content.append('<button>Save</button>');
})();

Now that there’s a save button on the page, we need to check to see when it’s been clicked, so we know when to save.

1
2
3
4
5
6
7
8
9
10
(function() {
    var content = $('.content'),
          edit = $('.edit');
          edit.attr('contenteditable', 'true');
          content.append('<button>Save</button>');

    $('button').on('click', function() {

    });
})();

When the button clicked, we want to get all the content that is in the paragraph tags with the edit class and use jQuery’s ajax method to send our content to the PHP file that will update the database. What we’ll do is, since the button is inside the same div as the paragraph tags, we’ll get the siblings of the button using jQuery.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(function() {
    var content = $('.content'),
          edit = $('.edit');
          edit.attr('contenteditable', 'true');
          content.append('<button>Save</button>');

    $('button').on('click', function() {
        var siblings = $(this).siblings(),
              content1 = $(siblings[1]).html(),
              content2 = $(siblings[2]).html(),
              dataString = 'content1=' + content1 + '&content2=' + content2;

    });
})();

So what’s going on in the four lines inside the button click function? First we’re getting the siblings of the button and assigning it to the variable siblings. You might be wondering why I’m using $(this).siblings(), it’s because this way you could have more than one block to edit, you could reuse this as a function and it will work with any of the buttons you have on the page. Next, since this is a simplified version to just show the functionality, we get the two editable siblings and assign them to variables content1 and content2. Finally, we have to send these somehow to the PHP file that will update the database, so we set a variable called dataString to the same thing as we’d send with a normal form with the method of post. Now to send it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(function() {
    var content = $('.content'),
          edit = $('.edit');
          edit.attr('contenteditable', 'true');
          content.append('<button>Save</button>');

    $('button').on('click', function() {
        var siblings = $(this).siblings(),
              content1 = $(siblings[1]).html(),
              content2 = $(siblings[2]).html(),
              dataString = 'content1=' + content1 + '&content2=' + content2;

        $.ajax({
            type: 'post',
            url: 'update.php',
            data: dataString
        });

    });
})();

We just jQuery’s ajax method and send dataString to a PHP, I’ve called it update.php, where you’d use an MySQL insert statement and update your database. You could add a gif animation or something similar in order to show the user that something is happening. Or you could set up a callback function on the ajax method to tell the user that the database has been successfully updated.

This is a very simple example of how this could be done. In a more complicated site, you could change it so that jQuery scans the page for all the elements with a certain class and grabs their content. The contenteditable attribute has been around for a while, so long this will even work in IE6!

Build a game using the DOM – Part 3

February 23rd, 2012

In part 2, we made our ship shoot lasers and while I’m sure some people would love to play a game that consisted entirely of shooting at nothing, I think we can do a bit better. Let’s add something to shoot at because I’d rather die than live in a world where the green boxes control us blue boxes (we’ll change these to real graphics in part 4).

First thing we need to do is add the variables we need for the enemies, just add them to the other ones at the top:

1
2
3
4
5
6
7
enemies = [],
enemySpeed = 2,
enemyTotal = 4,
enemyPos = {
    x: 150,
    y: -50
};

It’s pretty much the same stuff as the variables we used for the lasers with one more, enemyPos is used to get the starting position of our ships. The y position is set to negative fifty so that they start off screen. Next we need to create our enemy ships and add them to the play area, so we’ll do that with a for loop:

1
2
3
4
5
6
7
8
9
for (var i = 0; i < enemyTotal; i++) {
    var enemy = Enemy();
    enemies.push([enemy, enemyPos.y]);
    playArea.appendChild(enemies[i][0]);
    enemies[i][0].classList.add('enemy');
    enemies[i][0].style.top = enemies[i][1] + 'px';
    enemies[i][0].style.left = enemyPos.x + 'px';
    enemyPos.x += 150;
}

Since enemyTotal is set to 4, the loop runs four times and gives us four enemies. First, the variable called enemy is equal to Enemy(). Then it’s added to the enemies array as well as enemyPos.y. Next, it’s added to playArea with appendChild and given the class of enemy. Finally, we assign the top and left positions and the last thing we do is increase enemyPos.x by 150 which spreads the enemies out across the screen. If you ran this code now, you’d get an error because we’re calling a function called Enemy but that function doesn’t exist yet. So let’s create it:

1
2
3
function Enemy() {
    return document.createElement('div');
}

Exact same thing as our Laser function, so why don’t we use the same one? In a later part, we might need to use those functions for other things, and it keeps our code organised. Now that we have our enemies added, we need to make them move or this might be the easiest game ever made. Let’s make the moveEnemies function:

1
2
3
4
5
6
7
8
9
10
function moveEnemies() {
    for (var i = 0; i < enemies.length; i++) {
        enemies[i][1] += enemySpeed;
        enemies[i][0].style.top = enemies[i][1] + 'px';
        if (parseInt(enemies[i][0].style.top) > (playArea.bottomBoundary + enemies[i][0].style.height)) {
            enemies[i][1] = enemyPos.y;
            enemies[i][0].style.top = enemies[i][1] + 'px';
        }
    }
}

This is pretty much the same as our moveLaser function from part 2, just in the opposite direction. It move the enemies down the screen and if they pass beyond the bottom, then they are reset back to the top. Of course, this won’t work if we don’t call the function in our loop:

1
2
3
4
5
6
function loop() {
    moveShip();
    moveEnemies();
    moveLasers();
    setTimeout(loop, 1000/60);
}

Now for this to be any fun, we need to be able to shoot the bad guys, so to do that we need to create a new function and alter another one. First, let’s alter moveLaser, after we finished part 2, it looked like this:

1
2
3
4
5
6
7
8
9
10
function moveLasers() {
    for (var i = 0; i < lasers.length; i++) {
        lasers[i][1] -= laserSpeed;
        lasers[i][0].style.top = lasers[i][1] + 'px';
        if (parseInt(lasers[i][0].style.top) < playArea.topBoundary) {
            playArea.removeChild(lasers[i][0]);
            lasers.splice(i, 1);
        }
    }
}

And we need to change it to this:

1
2
3
4
5
6
7
8
9
10
11
12
function moveLasers() {
    for (var i = 0; i < lasers.length; i++) {
        if (parseInt(lasers[i][0].style.top) > playArea.topBoundary) {
            lasers[i][1] -= laserSpeed;
            lasers[i][0].style.top = lasers[i][1] + 'px';
            checkHit(i);
        } else {
            playArea.removeChild(lasers[i][0]);
            lasers.splice(i, 1);
        }
    }
}

What’s changed? First off, instead of checking to see if the laser has passed the top boundary of the play area, we’re checking to see if the laser is still in the play area and if it is, then we move it up, otherwise we remove it. We’re also calling a function called checkHit which we’re using to see if the laser has hit one of the enemies. One thing to notice is that we’re passing the value of i to the checkHit function so that we know which laser we’re checking.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function checkHit(l) {
    var lx = parseInt(lasers[l][0].style.left),
          ly = parseInt(lasers[l][0].style.top);
    for (var i = 0; i < enemies.length; i++) {
        var ex = parseInt(enemies[i][0].style.left),
              ey = parseInt(enemies[i][0].style.top),
              ew = enemies[i][0].offsetWidth,
              eh = enemies[i][0].offsetHeight;
            if (lx > ex && lx < ex + ew && ly > ey && ly < ey + eh) {
                playArea.removeChild(lasers[l][0]);
                playArea.removeChild(enemies[i][0]);
                lasers.splice(l, 1);
                enemies.splice(i, 1);
            }
      }
}

Wow, what’s going on here? First, we get the x and y position of our laser, then we run a loop where we check the laser’s position against the positions of all the enemies. And if the laser intersects one of the enemies, then we remove both the laser and the enemy from the play area and we remove them from the lasers and enemies arrays. Now, we need to make a change to the moveEnemies function or else this is going to be a pretty quick game. Right now, if you played the game, you’ll shoot the enemies, they’ll be removed from the game and then that’s it. Let’s add something to moveEnemies to add more enemies.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function moveEnemies() {
    if (enemies.length < enemyTotal) {
        var enemy = Enemy();
        enemies.push([enemy, enemyPos.y]);
        playArea.appendChild(enemies[enemies.length - 1][0]);
        enemies[enemies.length - 1][0].classList.add('enemy');
        enemies[enemies.length - 1][0].style.top = enemies[enemies.length - 1][1] + 'px';
        enemies[enemies.length - 1][0].style.left = Math.floor(Math.random() * 500) + 'px';
    }
    for (var i = 0; i < enemies.length; i++) {
        enemies[i][1] += enemySpeed;
        enemies[i][0].style.top = enemies[i][1] + 'px';
        if (parseInt(enemies[i][0].style.top) > (playArea.bottomBoundary + enemies[i][0].style.height)) {
            enemies[i][1] = enemyPos.y;
            enemies[i][0].style.top = enemies[i][1] + 'px';
        }
    }
}

This new code checks if the enemies array’s length is less than enemyTotal and if it is, it adds a new one to the play area. It’s the same as the loop we used to create the first batch of enemies with one difference, we generate a random number to assign the new enemy’s x or left position.

And that’s it for part 3. We’ve now got the bare bones of a shooter game now, check out the demo. In the next couple of parts, we’ll add things like actual graphics, a score and a start screen.

The simplest explanation of JavaScript prototypes I can think of

February 19th, 2012

If you really want to take an object oriented approach to coding in JavaScript, then you need to understand prototypes. And, to be honest, I’ve found prototypes to be one of the hardest things to grasp. How they work isn’t that hard to figure out, but for developers coming from class based languages, the why might be. And I want to thank Jeffrey Way and his jQuery series for finally showing me that one last piece of the puzzle that made it click.

Here’s an example that I think is pretty easy to understand. Let’s say we’re building a game and we are going to create multiple enemies. And we want those enemies to be able to move and shoot, so I’d write something like this:

1
2
3
4
5
6
7
8
var Enemy = function() {
    this.move = function() {
        console.log('Move!!');
    };
    this.shoot = function() {
        console.log('Shoot!!');
    };
};

And let’s say we want to create an alien for an enemy:

1
2
var alien = new Enemy();
console.log(alien);

Now, if we console.log alien, we get this:

Our alien has access to both the move and the shoot methods that we created inside the Enemy function. Instead of the console.log line, imagine a a bunch of code that tells our enemy what to do when those methods are called. Next, let’s say that we want to also have monsters in our game:

1
2
3
4
5
var alien = new Enemy();
var monster = new Enemy();

console.log('Alien: ', alien);
console.log('Monster: ', monster);

So what’s the problem? This all works right? Well, first of all, we all know that monsters don’t shoot lasers but if we check out monster object in the developer tools we see that our monster has the shoot method:

When we just have one line of code, it’s not that big of a deal, but let’s say that our shoot method is a bunch of code and we can have 20 monster in the game at one time. That’s a lot of memory we’re using up for those monster objects that we aren’t going to use. This is where we want to use our Enemy function’s prototype property. Take a look at this version of our Enemy function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var Enemy = function() {
    this.move = function() {
        console.log('Move!');
    };
}

Enemy.prototype.shoot = function() {
    console.log('Shoot!');
}

var alien = new Enemy();
var monster = new Enemy();

console.log('Alien: ', alien);
console.log('Monster: ', monster);

Now if you’re like me, you’re probably thinking, the other way was much simpler and now we’re just complicating things, but there is a really good reason to do it this way. Now, when we create both the alien and the monster, they’ll have the move method in their object but not the shoot method:

But because we added the shoot method to Enemy’s prototype so that we still have access to it with enemy.shoot(). It’s the same things as the push or splice methods on an Array. In this example, our monster can technically still call the shoot method but it’s not carrying it around in the memory of every instance of it in our game.

If you don’t get prototypes right away, don’t worry, it seems to be one of those things that takes while to grasp. Just keep reading and reading about them and one day it will click. This is the simplest way I can think to explain them. Essentially, they allow you to add methods to an object without that object having to carry it around in it’s memory if you aren’t using it, which when you have some methods that could be a fair amount of code, it can speed up your game or app.

Where to start learning JavaScript and jQuery

February 15th, 2012

Most of the emails I get from web developers ask me for advice on where they should start learning JavaScript or jQuery. Usually it’s questions about which books they should check out but, while I do like to learn from books, I’ve found I learn a lot from watching video tutorials. I thought I’d list some of the resources I’ve used over the last few of years to learn JS and jQuery.

When I first discovered jQuery, I had no idea what was going on with it and most of the articles and tutorials at the time where written by experienced programmers who assumed you had a certain level of programming knowledge. Plus, the actual jQuery site was a bit lacking in tutorials and examples.

Then I came across jQuery for Absolute Beginners by Jeffery Way. This video series is pretty old by web standards, the demos are using version 1.2.6 of jQuery, but this series is where I didn’t just learn jQuery, but I began to understand it. I wouldn’t recommend using this as your only source of learning jQuery, but it’s a pretty good series. Plus, it’s pretty entertaining watching Jeffery switch code editors every few videos.

Luckily for us, Jeffery Way is the guy in charge of Nettuts+ and currently has a new jQuery video series running called 30 Days to jQuery. I’ve been doing the videos daily since it started and even though I’ve been working with jQuery for a few years now, I’m still learning now things from it. In fact, I would recommend it to even experience web devs because the series covers some new features that were introduced in jQuery 1.7.

Now you might be surprised but Microsoft actually has some pretty good resources out there to learn not just their tech but also the awesome free ones, HTML, CSS and JavaScript. If you’re like me and like video tutorials, they’ve got a bunch of great ones. Script Junkie is a great site, although it’s been a while since they updated, their video page (Microsoft has moved the videos somewhere. At least I hope they didn’t just delete them) has great videos on both jQuery and straight JavaScript. jQuery is great but I think that every dev should know at least some vanilla JS.

Speaking of JavaScript, if you’re really serious about learning it for more than making pop ups and cool hover effects, then there’s two books you need to read. The first is JavaScript: The Definitive Guide. It’s huge and full of everything you need to know about JS and even a bunch of stuff that you probably didn’t. You might be intimidated by it if your brand new to programming but it starts at the beginning and doesn’t assume that you have experience programming before.

The other book you need to read is JavaScript: The Good Parts. It’s about a tenth the size of the Definitive Guide, if that, but it’s more a guide on how to properly write JS as opposed to actually teaching you the ends and the outs of the language. It’s the one book I’ve seen online that everyone agrees every web dev should read, multiple times.

If you need to look up specific functions or methods or really just have any questions related to JavaScript, then the Mozilla Developer Network is the best place to go. I visit it daily and it always shows me what I’m doing wrong. Plus, it tells you about any browser compatibility issues which anyone who’s built anything more than the simplest web page can tell you is frustrating beyond belief when you don’t know why it’s not working.

Everyone learns differently and comes from different, if any, programming backgrounds. I found JavaScript easy to pick up because I came from ActionScript 2.0 and 3.0, so JS was just a bit of a move back in time. If you’re not a fan of video tutorials, there’s tons of books and written tutorials out there. And then great thing about JavaScript is because it’s in every browser on every computer, there’s tons of people working with it and they’ve encountered every problem you can have and the nice ones have put their solutions out there somewhere.

Build a game using the DOM – Part 2

February 5th, 2012

In part two of building our game, we’re going to give our blue block or ship the ability to shoot lasers. But first we have to make a couple of changes in our code from part one in order to make the game easier to build and control the game’s elements. Right now, the play area and the ship are two separate elements in the body tag, but we’re going to change this so that the ship div is inside the playArea div. So, here’s our old block of code setting up the game:

1
2
3
4
5
6
7
8
9
10
document.body.appendChild(playArea);
playArea.classList.add('playArea');
document.body.appendChild(ship);
ship.classList.add('ship');
shipPos.x = (playArea.offsetWidth / 2 + playArea.offsetLeft) - (ship.offsetWidth / 2);
shipPos.y = (playArea.offsetHeight + playArea.offsetTop) - (ship.offsetHeight * 2);
playArea.leftBoundary = playArea.offsetLeft + 10;
playArea.rightBoundary = (playArea.offsetLeft + playArea.offsetWidth - 10) - ship.offsetWidth;
playArea.topBoundary = playArea.offsetTop + 10;
playArea.bottomBoundary = (playArea.offsetTop + playArea.offsetHeight - 10) - ship.offsetHeight;

Change it to this:

1
2
3
4
5
6
7
8
9
10
document.body.appendChild(playArea);
playArea.classList.add('playArea');
playArea.appendChild(ship);
ship.classList.add('ship');
shipPos.x = (playArea.offsetWidth / 2) - (ship.offsetWidth / 2);
shipPos.y = playArea.offsetHeight - (ship.offsetHeight * 2);
playArea.leftBoundary = 0;
playArea.rightBoundary = playArea.offsetWidth - ship.offsetWidth - 20;
playArea.topBoundary = 0;
playArea.bottomBoundary = playArea.offsetHeight - ship.offsetHeight - 20;

The main changes are, instead of document.body.appendChild(ship), we have playArea.appendChild(ship) which puts the ship div inside the playArea div. Next, we change how we set the boundaries of the play area because now that the ship div is inside, we don’t need to get the offsetLeft and offsetTop any more. But for this to work the way we want, we still need to update the CSS:

1
2
3
4
5
6
7
8
9
10
.playArea {
    width:800px;
    height:500px;
    background:#000;
    border:10px solid #333;
    margin:30px auto 0;
    box-shadow:5px 5px 10px #444;
    position:relative;
    overflow:hidden;
}

Setting the position to relative allows us to absolutely position elements inside the playArea div and setting overflow to hidden allows us to have elements move past the borders and not be seen anymore. Now, let’s add those lasers. First, we need some CSS:

1
2
3
4
5
6
.laser {
    width:4px;
    height:20px;
    background:red;
    position:absolute;
}

Pretty much the same as our ship class, except laser shaped. Next we need to add some variables to our JavaScript, add these to the end of the list of variables at the top of the code:

1
2
3
lasers = [],
laserSpeed = 4,
max_lasers = 5

First, we have an array to store our lasers in, so we can loop through it to update our lasers’ positions. Next, laserSpeed is self-explanatory, we set it up here so that it’s easier to change than if we had set it further down in the code. Also, this way we could alter it in game if we want to.

We set it so when the player presses the x key, the ship will fire a laser. Why x? Because the spacebar can be loud and annoying and x is always cool. Add this code to the bottom of the keyDown function:

1
2
3
4
5
6
7
8
9
10
if (e.keyCode === 88) {
    if (lasers.length < max_lasers) {
        var laser = Laser();
        lasers.push([laser, shipPos.y]);
        playArea.appendChild(lasers[lasers.length - 1][0]);
        lasers[lasers.length - 1][0].classList.add('laser');
        lasers[lasers.length - 1][0].style.top = lasers[lasers.length - 1][1] + 'px';
        lasers[lasers.length - 1][0].style.left = shipPos.x + 25 + 'px';
    }
}

So, if x, which has the keyCode of 88, is pressed and if the total amount of lasers in the lasers array is less than max_lasers, then we call a function called Laser, which we’ll write next. Then we push the variable laser into our lasers array along with the ship’s y position. Next, the laser is added to the playArea div using appendChild. Then we add the class of laser to that div and set it’s top and left position.

You might be wondering why it says lasers[lasers.length - 1]. Remember that a JavaScript array starts at zero, so the first element of an array is lasers[0]. So, if we want to get the newest element in the array, it will be the last one, but if our array has one element and we put lasers.length, that will equal one and give us lasers[1]. But that would give us the second element which doesn’t exist in this example, we want lasers[0], so lasers[lasers.length - 1] will always give us the one we want in this situation.

Now we need to write that Laser function:

1
2
3
function Laser() {
    return document.createElement('div');
}

Yes, it’s that simple and we could just put:

1
var laser = document.createElement('div');

But let’s say later on we need something else to happen when a div is fired, this will be the place to do it. Also, it helps to keep the code organized. Now, if you run the game, the lasers will be added but they’ll just sit there and that doesn’t make a very good offensive weapon. Now we need a function to move the lasers:

1
2
3
4
5
6
function moveLasers() {
    for (var i = 0; i < lasers.length; i++) {
        lasers[i][1] -= laserSpeed;
        lasers[i][0].style.top = lasers[i][1] + 'px';
    }
}

This function just runs a for loop that cycles through all the elements in the lasers array and moves them up the playArea at whatever laserSpeed is set to. Of course, to make this work, we need to call it in the loop function:

1
2
3
4
5
function loop() {
    moveShip();
    moveLasers();
    setTimeout(loop, 1000/60);
}

This works but we have one problem, when a laser goes past the top of the playArea, it keeps going forever and once five lasers are fired, the player can’t fire any more. We need to add something to our moveLasers function to check if a laser has left the viewable area.

1
2
3
4
5
6
7
8
9
10
function moveLasers() {
    for (var i = 0; i < lasers.length; i++) {
        lasers[i][1] -= laserSpeed;
        lasers[i][0].style.top = lasers[i][1] + 'px';
        if (parseInt(lasers[i][0].style.top) < playArea.topBoundary) {
            playArea.removeChild(lasers[i][0]);
            lasers.splice(i, 1);
        }
    }
}

All we need is an if statement that checks if the laser has passed the top of the playArea and if it has, it removes it from both the DOM and from the lasers array which allows the player to shoot another laser.

That’s it. Now we have a ship that looks like a blue square, for now, that shoots lasers that look like red rectangles, for now. You can check out the demo here. In part 3, we’ll add some enemies to shoot at or else this will be one of the most boring games of all time.

Get the style property’s value of an element using JavaScript

February 2nd, 2012

Here’s a quick one. Let’s say you need to get a style property value using JavaScript, it’s actually not that complicated. But, of course, in true JavaScript fashion, the names of the methods are a bit clunky. First we have a div:

1
<div class="box"></div>

Then we have our CSS:

1
2
3
4
5
.box {
    width: 400px;
    height: 300px;
    border: 10px solid black;
}

Now, let’s say that we want to get the width of the border that’s on our div with the class of box, we only need two lines to get it:

1
2
var box = document.querySelector('.box');
var borderWidth = window.getComputedStyle(box, null).getPropertyValue('border-width');

What’s going on here? First off, we’re finding our div in the DOM and assigning it to the variable box. Next, we’re declaring a new variable called borderWidth. Next we use a method called getComputedStyle and passing it our box variable, which gets all the style information of that element. Next we use the getPropertyValue method to get the value of the border width. Console.log that our and you’ll get ‘10px’. We could even turn this into a function that could be used any time we need it:

1
2
3
4
function getStyle(el, prop) {
    return window.getComputedStyle(el, null).getPropertyValue(prop);
}
var borderWidth = getStyle(box, 'border-width');

This was actually a bit tricky to figure out because I knew about the getPropertyValue method but I didn’t know about getComputedStyle, which you need for this to work.

Build a game using the DOM – Part 1

January 29th, 2012

When I first became interested in building games using the browser and not Flash, I saw the examples people had made using HTML5’s canvas element so I started learning to build things with that. But every once in a while I’d see someone saying, “Canvas is cool but I prefer using the DOM to build my game.” Use the DOM? The DOM is for displaying pictures and text, not for guys to jump on monsters or space ships to shoot lasers at giant octopus aliens. But then I noticed something, jQuery animations look pretty smooth, especially in Chrome and Firefox, so why couldn’t the browser render a ship flying around in space? So, let’s give it a shot. I’m going to use pretty much the same code as I used in my canvas game tutorial but adapt it for the DOM.

For the first part, we’re going to get a box that will eventually become a ship to move around a playing area. If you’re following this tutorial, I’m going to guess you’ve had a bit of experience with HTML and you’re thinking that we’ll be starting with some divs and go from there. We’re actually going to create everything using JavaScript and style it with CSS which I think will give us more control over what we’re displaying. First off, our CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
body {
    margin:0;
    padding:0;
    background:#888;
}
.playArea {
    width:800px;
    height:500px;
    background:#000;
    border:10px solid #333;
    margin:30px auto 0;
    box-shadow:5px 5px 10px #444;
}
.ship {
    width:50px;
    height:50px;
    background:blue;
    position:absolute;
}

Nothing special here, this just creates am 800 by 600 playing area and our ship will be a 50 by 50 blue box, just like a real space ship. Don’t worry, we’ll change it in a later part, this is to just get things going and prove it can work. Enough with boring CSS, let’s see some JavaScript! Here’s our variables:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(function () {
    var playArea = document.createElement('div'),
          ship = document.createElement('div'),
          shipPos = {
              x: 0,
              y: 0
          },
          shipSpeed = 4,
          key = {
              right: false,
              left: false,
              up: false,
              down: false
          },
          shipWidth = ship.offsetWidth,
          shipHeight = ship.offsetHeight;

})();

First off, all our JS is going to be inside an anonymous self calling function because that’s just a good practice. This way our variables won’t affect any other code that might be on the page. Our first variable is playArea which is a div that we’ve created using the createElement method. The same goes for ship. We’ve created these elements but we haven’t added them to the document yet, so if you run just this code, nothing will show up. Next is shipPos, which is an object that we’ll use to keep track of our ship’s x and y position. shipSpeed should be pretty obvious, it’s the speed our ship is set at. The key object is used to check which arrow key is being pressed so we can tell the code to move the ship around. Finally, shipWidth and shipHeight are there to help us keep the ship in the play area boundry and we’ll use it later to see if our ship has been hit by an enemy. offsetWidth and offsetHeight gives us the height of ship that was set in the CSS, so if we want to change it, we just change the CSS and it will update in the JS. Place this next block of code right after the variables:

1
2
3
4
5
6
7
8
9
10
document.body.appendChild(playArea);
playArea.classList.add('playArea');
document.body.appendChild(ship);
ship.classList.add('ship');
shipPos.x = (playArea.offsetWidth / 2 + playArea.offsetLeft) - (ship.offsetWidth / 2);
shipPos.y = (playArea.offsetHeight + playArea.offsetTop) - (ship.offsetHeight * 2);
playArea.leftBoundary = playArea.offsetLeft + 10;
playArea.rightBoundary = (playArea.offsetLeft + playArea.offsetWidth - 10) - ship.offsetWidth;
playArea.topBoundary = playArea.offsetTop + 10;
playArea.bottomBoundary = (playArea.offsetTop + playArea.offsetHeight - 10) - ship.offsetHeight;

What is going on here? The first line adds our playArea div to the document and the next line gives it the class of ‘playArea’. The next two lines do the same thing for ship. Then the ship’s position is figured out using the position and width of playArea. And the last four lines calculate the sides of playArea so we can check when our ship touches it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function keyDown(e) {
    if (e.keyCode === 39) {
        key.right = true;
    } else if (e.keyCode === 37) {
        key.left = true;
    }
    if (e.keyCode === 38) {
        key.up = true;
    } else if (e.keyCode === 40) {
        key.down = true;
    }
}

function keyUp(e) {
    if (e.keyCode === 39) {
        key.right = false;
    } else if (e.keyCode === 37) {
        key.left = false;
    }
    if (e.keyCode === 38) {
        key.up = false;
    } else if (e.keyCode === 40) {
        key.down = false;
    }
}

The function keyUp checks to see if one of the arrow keys has been pressed and changes the corresponding key boolean to true. keyUp checks for when that key is released and sets the value back to false. Now we have to move our ship:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function moveShip() {
    if (key.right === true) {
        shipPos.x += shipSpeed;
    } else if (key.left === true) {
        shipPos.x -= shipSpeed;
    }
    if (key.up === true) {
        shipPos.y -= shipSpeed;
    } else if (key.down === true) {
        shipPos.y += shipSpeed;
    }
    if (shipPos.x < playArea.leftBoundary) {
        shipPos.x = playArea.leftBoundary;
    }
    if (shipPos.x > playArea.rightBoundary) {
        shipPos.x = playArea.rightBoundary;
    }
    if (shipPos.y < playArea.topBoundary) {
        shipPos.y = playArea.topBoundary;
    }
    if (shipPos.y > playArea.bottomBoundary) {
        shipPos.y = playArea.bottomBoundary;
    }
    ship.style.left = shipPos.x + 'px';
    ship.style.top = shipPos.y + 'px';
}

The first part of moveShip checks to see if one of the direction values is true and then moves the ship in that direction at whatever value we’ve set shipSpeed to. The next part of the function checks to see if the ship has reached one of the edges of the playArea div, if it does then the ship is kept inside the div. Finally, the actual updated position of the ship is set on the ship div.

1
2
3
4
5
6
7
8
9
document.addEventListener('keydown', keyDown, false);
document.addEventListener('keyup', keyUp, false);

function loop() {
    moveShip();
    setTimeout(loop, 1000 / 60);
}

loop();

Finally, we add a couple of event listeners so that our game will register when a key is pressed or released and the right function is called. Next we have a function called loop which calls our moveShip function and then has a setTimeout to call loop 60 times a second. And then to get it all started, we call loop for the first time.

You can check out the demo here.

One thing, this doesn’t work in any version of Internet Explorer because classList isn’t in IE yet. Maybe in a later part, we’ll add some compatibility but for now, I think it’s fine if this just works in the other major browsers.

I really hope the future of the web is on my TV and not my phone

January 25th, 2012

I’m going to be honest with you, I hate browsing the web on my phone. I check Twitter on it, I check my email, the weather and Wikipedia but i never actually surf the web on it. And it’s not because I’m an old man and I can’t see what’s happening on the screen. It’s because there’s really only two kinds of designs you can make for small screens, ones that mimic an app or ones that are as simple a layout as you can make. Throw in the fact that some designers believe that the only devices out there are iPhones and iPads and screw the rest. Also, I think that Android phones have about a thousand different screen resolutions is going tho throw a monkey wrench in some plans.

So whenever I’m in the living room, looking something up on my phone and I realize there’s a giant screen sitting there in the room and half the time I’m barely paying attention to what it’s showing. I would love to build websites and apps for a 40” screen. I’m not talking about using a tv like it’s a giant monitor, I’m talking about something that’s a combination of the cable or satellite service we’re used to and the internet as we know it. Watch a show in fullscreen mode, see an actor you recognize but can’t remember their name, so you pop up the IMDb app and and it links to that episodes page. Or a commercial comes on, so you split the screen in half and check your RSS feed in Google Reader until your show comes back on.

I don’t know if any of this is even possible, I’ve done zero research on it. I just know what I would like and this is it. I’d love it if I could use a tablet to control the tv, a tablet that displays the controls I need to operate whatever I’m doing at the time. I’m not talking about using Apple TV and an iPad, I really think the world would be a better place if you could use any brand tv and any brand tablet. How about your coffee table has Microsoft’s Surface on it? Then you could be like the MI6 agents in Quantum of Solace!

Is the future of the web mobile? I don’t know. People have been saying to me that the desktop is dead for about 6 years now and I still see them for sale. And for about the last year or so, I’ve seen people say the laptop was dead too, killed by netbooks. Wait, that didn’t happen? Oh, right it was tablets. It’s one of those weird things, in some ways technology only moves as fast as the majority. I consider myself to be some what an early adopter and I know we aren’t the people companies make money off of. For major change to happen, the tech has to be good and affordable, I really believe Blu-ray took off because you could get a player inside your PS3, that’s the reason I have a Blu-ray player. And look at 3D tvs, they’re not taking off because everyone just bought hi-def flatscreens a couple of years ago.

So, what’s going to happen with the web? Will it be tablets? Maybe if the good ones don’t cost $800. But I’ll tell you this, if they make a tv that’s got a computer in it and I only need one cable to get both tv and the internet, that will be the future I want to live. Also, it would be nice if I could jetpack to work.