Sunday, 20 January 2013

Enemies

The game's developing a bit of a lonely feel. Just you, in space, wandering around uninhabited space mazes. Let's make things more interesting by adding enemies.

I've gone into a bit more detail than usual on this post. Also, if you're using a recent Chrome, Firefox or Safari, there are animated diagrams!

So. The first thing to think about is how the enemies should move. There are a few obvious patterns:

  • Move up and down
  • Move from side to side
  • Go straight and turn when hitting a wall.
  • Follow the left wall or the right wall.
  • Follow the player.
  • Move randomly.

For the patterns that involve turning left or right, we can define two versions of that enemy, a "left-handed" one which turns left and a "right-handed" one which turns right.

So, let's think about how to implement these enemies. What do they all have in common? Well, they all need to decide where to go next as soon as they enter a new square. The difference is in how each enemy makes that decision. Let's start with the simplest, the up-and-down enemy.

Here is a first-draft "decision function" for this enemy:

  • If you can go forward, go forward.
  • If not, turn around.

Looking at this, you can see that it would work not only for the up-and-down enemy but also the side-to-side one; the only difference is the initial direction. So, we can consider both these enemies to have the same movement pattern; let's call it the Oscillator.

The Oscillator

If we use to mean "go forward" and to mean "turn around", we can summarize this enemy's movement pattern as ↑↓.

To see how the Oscillator uses its movement pattern to move back and forth, here's an animation:

The Flyer

The next enemy type is also pretty straightforward:

  • If you can go forward, go forward.
  • If not, turn left or right.

We can define a left-handed and right-handed version of this enemy by changing which direction it turns in the second step. In fact, we can define a third version that choses randomly. Collectively, let's call these enemies Flyers, and summarize their movement patterns thus:

↑↱↓ — Right-handed
↑↰↓ — Left-handed
↑? — Random

The Wall-Follower

Now for the wall-followers. This isn't as obvious:

↱↑↰↓ — Right-handed
↰↑↱↓ — Left-handed

The Player-Follower

The obvious way to define a player-follower in this system would be to introduce a new command called "follow player" and have the player-follower's list consist only of that command.

We can do better, though. After all, it might be nice to be able to retreat from the player as well as follow them; or follow or avoid a different object, something other than the player.

With one small change, we can create enemies that behave like this using only the forward, backward and turn commands we've already defined.

First, we define a "relative axis" for each enemy type. All the enemies introduced so far have their relative axis pointing forwards, from their point of view. For the player-follower and the player-avoider, the relative axis points from it to the player.

Next, we interpret the results of the decision function differently: forward now means move in the direction of the relative axis; backward means go in the opposite direction, and left and right mean turn relative to the relative axis.

This way, the existing enemies' behaviour is unchanged, but we can define a player-follower with a decision function of and a player-avoider with . We can also define enemies that follow or avoid any item we like. How about a moth-like enemy that's drawn to a light, or an enemy that's scared of other enemies?

It might be interesting to see how and behave in combination with the relative axis; perhaps it will yield some sort of orbiting behaviour?

Also, there may be other ways to play with the relative axis besides pointing it to some sort of target object.

5 comments:

  1. Amazing "relative axis" sysytem !
    Quote:"For the player-follower and the player-avoider, the relative axis points from it to the player."
    But sometimes, the axis is neither horizon nor vertical, but slant, especially 45°to horizon and verital, so how to deal with it?
    I have several ideas about the game elements,but I cannot find your Email Address.....

    ReplyDelete
    Replies
    1. If the axis is slanted after transforming it by the relative axis, what I do is split it into an X and a Y component. Then the enemy picks whichever of these is longer and tries to move that way, or, failing that, tries to move along the shorter axis. If they are the same length (i.e. 45º) then it picks one arbitrarily. Only if both are blocked does it move onto the next direction in its decision function.

      If you want to drop me an email my address is roblovski@gmail.com

      Delete
  2. Thank you for your kind reply! I'll send my ideas with Email to you.

    ReplyDelete
  3. Nice to see what's going on :-)
    Until now, I haven't thought about how many things could be done.
    How do you think about an enemy that mimics your movement? Maybe that could make for some interesting puzzles as well.
    Oh, now that you showed me how the enemies choose their directions, I get it why (in netshift) you could trick a vertical oscillator into a horizontal movement by using a moving walkway and a teleporter.

    Btw, the animated diagrams work with Opera as well.

    In hope you don't feel lonely anymore,
    Wunk

    ReplyDelete
  4. Thanks for the demonstration on how you program movements and the decision making process. On the player-follower, you did have that in the original version as well as blackshift - that irritating fish! Ha ha ha. Nice to see the web page up again Rob. SSB would be nice as well whilst we await what should be an epic game!

    ReplyDelete