Skip to main content

World In Motion

In the last post I touched on how easy it is to score in this game - you can just camp out on the score bullet spawner and watch the points rack up. I'm going to add a little delay to the score bullets so that they start out in a deactivated and uncollectable state, and then change to active and collectable after a short time - say, half a second. To make it clear what state they are in I'm going to add code to let me change the look of Objects and allow them to be animated.


What Is An Animation?

Animation is simply the process of changing the image that I use to represent an Object over time to make it appear like it's alive. As an example, suppose I want the score bullet to start off looking inactive, and then I want to make it spring into life. I can do this by having two animations:
Inactive - Static and grey
Active - Flashing
So how do I describe these animations in code?

Defining An Animation

I'm going to have a very simple definition for an animation - a list of the images and how many frames each one is shown for. When the animation ends, it either stays on the last image or it jumps to another animation. So here are the definitions for these two animations:


As you can see, each animation has a name, a list of steps and an optional "next" parameter. Each step contains a length (how many frames it is shown for) and data. The data contains two values: the first is the name of the resource to use for the image, the second one is the collision map. This makes it easy for me to animate collision maps at the same time, and this comes in super handy because I can make the inactive score bullet impossible to collect by just setting its collision map to null.

The score_bullet_active animation has the next parameter set to itself. This just means that the animation will start again as soon as it finished.

How To Animate An Object?

I could do the animation manually by changing the score bullet's image and collsiion map properties in the update() function,  but I want it to be easy to add animation to any Object and, above all, I want the animation to be automatic. The way I do this is by having an Animator class that handles that animation, and I put one of these in the base Object class. Then in the base Object update() method I update the Animator object and set the new values to the Object's image and collisionMap variables. The Animator's code looks like this:

The important functions here are:
  1. The constructor on line 2 takes an integer number that tells the Animator how many data items it should expect in each animation step. For Objects we set this to 2 - one for the image and one for the collision map
  2. On line 7, set() is used to start a new animation. The animations are listed separately in animationsList.js. When an animation is set, it automatically starts at frame 0
  3. The get() on line 16 returns the current data. If no animation has been set() then this will just return nulls, otherwise it returns the data values (from this.currentData) for the current frame
  4. jumpToFrame() on line 19 is the heart of the Animator. This sets the animation to an arbitrary frame number and copies the data for that frame into this.currentData. While you can call this function directly, you are not supposed to - the proper way to animate is by calling..
  5. ..the update() function on line 61. This one is very simple: if there's an animation currently set, set the data for the current frame and then advance to the next frame
One thing to note here is that the Animator knows nothing about images or collision maps - it only knows about a number of generic "data" items. This means that I could re-use this class to animate anything - strings, colours, sounds, arbitrary data...

Activating The Score Bullet

Here's the new code for the Score Bullet. You can see it being set to active after a number of frames:

Wrapping Up

In this post I created an Animator object to handle animations and I added it to the base Object class so that any Object type can now be animated super easily. I also added animations to a couple of game objects: score bullets (which now flash when they are active) and spawners (look closely and you'll see them flash every time they spawn a bullet).

The code is online, as is the playable version of the game.

What's Next?

Bullets are fun, but they are very predictable. I'd like to add a new enemy type to the game - something completely different. I'm going to add something that, if you've played any of Jeff Minter's shooty games, will be instantly familiar to you - the XY Zapper. For those who don't know, an XY Zapper is a type of enemy that tracks your position while intermittently spamming a laser beam along the entire X or Y access of the screen (or both axis at once). They are easy to avoid if you keep moving (and they are a great gameplay device to stop you from sitting still for too long) but they can easily catch you unaware and kill you in a split second if you sleep on them.

Comments

Popular posts from this blog

Set The Controls For The Heart Of The Sun

When we last met, I had just started work on a level editor. I'd got as far as adding the ability to select an object and move it around, and then I added an undo/redo system using the command pattern. That was a good start, but dragging items around the level is only fun for so long. What I really want to be doing is.. ..editing the properties of the bullet spawners! And I want to be doing this in realtime as the game plays so that I can immediately see what effect my changes have made to the gameplay of the level.

The Long And Winding Road

I started this blog back in November of last year. My aim was to document the development of a Bullet Hell shoot-em-up, written in JavaScript. Here we are, six months later, and lots has happened. With 20 posts already written, I thought that now would be a good time to take stock of what I've already done, and to look to the future and see what's to come.