Skip to main content

Hold The Line

Now that I have an animation system, why don't I use it to try and implement a new enemy type with minimal code? I'm going to implement an XY Zapper enemy. This is an enemy that periodically spams out a horizontal or vertical laser beam that instantly fries everything in it's path. The Zapper tracks the player's position and homes in on it, which makes it hard for the player to sit still in one place on the screen. This is good as it helps to stop the player from being lazy, sitting still and exploiting holes in the bullet patterns.


Looks

The Zapper has two states: moving and firing. Moving is just a repeated animation of four steps:
The length of this animation (it's 230 frame, or just under four seconds long) determines the length of the move state for the zapper - I'll talk about what that means in a minute...

The firing animation is a little more interesting. It includes a short "charge up" phase to telegraph to the player that the Zapper is about to fire and a "charge down" phase afterwards. The beam is only actually fatal when it is bright red:

The collision for the firing phase is also animated, like this:
The nice thing here is that only one step of the animation actually has any collision map attached to it. This means that I can rely on the animation system to turn the collision on and off at the right time, without having to do anything extra in code.

Brains

Remember that the Zapper has two states: moving and firing.

In the moving state the algorithm for the Zapper's movement is pretty simple. The Zapper has a heading (the direction of travel) and a velocity. On each update, I change the heading and the velocity and then move the Zapper's position at velocity speed in heading direction. To get the new heading, I take the current heading and I move it slightly towards the direction to the player. This means that the Zapper is always turning to face the player. The velocity at which the Zapper moves is based on its the distance from the player - when the Zapper is very close to the player it moves slowly, and when it is farther away it moves faster. As with heading, the target velocity is calculated each update, and the current velocity is nudged slightly towards it.

In the firing state, the logic is even simpler - the Zapper just continues moving in the same direction (ie: it doesn't turn) and it slows to a halt.

The lengths of the states are controlled by the lengths of animations. When the moving animation ends, it automatically goes into the firing animation, and when that ends it goes back to the moving animation. The Zapper's update() function figures out which animation is currently active and does the appropriate type of update logic

The code for all of this behaviour is in the update() function for the Zapper object. Here's a version that's slightly simplified for readability:

Note that I only talked about the X Zapper here - the Y Zapper has exactly the same logic but the graphics are in a vertical orientation.

Wrapping Up

I added a new enemy type to the game. I used the animation system that I added in the last update to drive the states of the enemy, which made it easy to implement the control logic.

I also added and changed a few other small part of the code, and you can check out the whole code online. The playable version is also available online.

Next Time

The game currently feels a little aimless - sure, you can try to get a high score but when you have unlimited time it's no big challenge. One thing that I want to implement to make high score chasing more of a challenge is to put a time limit on the levels, so that's what I'll work on next.

I also want to be heading towards adding a level editor so that you can design your own levels. Soon I will start heading towards making that happen.

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 Move

I'm going to get started on the level editor now. I'll start off simple with object selection and re-positioning using the mouse. Before I get to the editor code itself, there are a couple of things that I need to add first..

Heavy Loaded Head

Most games work best when you have more than one level, but ip until now that's all I've had - one level. Even worse, that level has been created directly from code written into the game itself - to change it I have to rewrite the code. What I need is data driven level loading - the levels should be defined by a data file. In this post I will be defining a level format and writing code to load it into the game. Let's start by talking about how the data will be laid out..