Friday, June 15, 2012

Making Mario 2 - Let's animate!

When I last left off, I had devised a way to generate pixel sprites using CSS and jQuery. (See the blog post here)

But notably, it didn't _do_ anything.

So, how do we manage animation with divs?
This was slightly more difficult than I thought it would be. Because most of the animation would be event driven, I had to come up with a good scheme to manage it all. The biggest hurdle was making it non-sprite specific. I wanted to have a generic method to deal with all my sprites animation needs.

I decided that to facilitate the animation, I would stack the frames on top of each other, and then simply hide the inactive frames and show only the active one. It appears to work fairly well.

The basic flow is this:
Press key -> animate -> release key -> kill animation

There is a few exceptions, but we'll cover those in a minute.

First and foremost, a number of sprites could be animated at any given time, so I needed to create a queue to handle them all. It's a simple struct that will store a bit of information about the sprite:
  • The frame order for the animation. This is stored in an array and will contain the div names. i.e. ["marioStartWalk", "marioMidWalk"]
  • If the animation is reversed or not. (Difference between facing left or right. The reverse sprites _must_ end with "Reverse" i.e. marioStartWalkReverse, etc...)
  • The prefix for the divs. (All sprite divs or "frames" related to the animation need to start with the same prefix. i.e. marioStartWalk, marioEndWalk, etc...)
  • The current frame that needs shown. This will always start with zero as it's the first array element.
  • Whether the animation is active.
  • The stop frame. This is the div that will be shown when the animation stops.
Here's what I came up with for the animate() method:

The takeaway here is that we add the sprite to the queue, turn it to active and display the appropriate frame.

Why am I managing it this way? Well, Javascript is notoriously difficult to manage simultaneous keyboard inputs with. So, I had to come up with a way to account for things like holding run and then hitting the jump button. In essence, I'm threading.

Here's an example:

There is a couple interesting things going on here. I'm using setInterval() for the animation calls. This is so I don't lock the browser waiting for the animation to finish and preventing the user from doing things like hitting the jump while walking / running. I'm also using an array to manage the key strokes. When the jump animation thread kicks off, it loses scope of the right / left arrow key presses. So, I check an array stack to see if the key is still being held down. If it is, and it was the same key that was being held prior to the jump, then Mario will continue walking / running when the jump animation ceases.

The final (and simplest) piece is stopping the animation:

And here it is put together. Controls are simple: Left and right arrows for movement animation. 'X' for jump.

I know what you're thinking: "Why the heck doesn't it MOVE?" Well, movement will be next weeks post ^__^. Here, I was simply dealing with animation. Believe it or not, they're unrelated. For me, this was really cool. We have graphics, and animation, using divs. Neat!

Hope you enjoyed this. If you want clarification on anything, feel free to leave comments in the post.
Final Note: Blogger keeps stripping my Javascript. If the game panel displays as a black line, let me know and I'll get it fixed.


  1. One thing to note...if you quickly try to switch between moving left and right (and maybe don't completely release the left arrow before pushing the right arrow), it doesn't pickup the right arrow event. Probably a problem with browsers, but I thought you'd like to know in-case you get serious about turning this into a real game. :)

  2. I visited your site & after visiting i found that it is very informational for everyone you have done really a great job thank you.
    aeration services toronto

  3. Thank you for the great article I did enjoyed reading it, I will be sure to bookmark your blog and definitely will come back from again. I want to encourage that you continue your great job, have a good day.

    POS iPad


Follow by Email