Skip to content

Moving Enemies with Waypoints

Getting enemies to move tends to be one of the more difficult things for me to get right. It just doesn’t always seem natural. And I’m not talking about moving with any type of AI. Just moving around the screen in a pattern.

Sure, straight lines are pretty easy. But games get really boring if all the enemies just go from right to left or left to right.

For this post we’re going to explore moving an enemy through a series of waypoints using ActionScript 3. I’m going to create a movie clip symbol in Flash named Enemy_mc.

Let’s see it

Doesn’t do much good to explain with words. This is what we’re going to create.

One minor difference. I set this demo up to loop so the enemy goes back to its starting position and sets its current waypoint back to 0 when it gets to the last one. The real deal will remove the enemy from the stage.

The code

Below is the code for moving the enemy. An explanation will come next.

import flash.geom.Point;
import flash.events.Event;

stage.addEventListener(Event.ENTER_FRAME, eFrame);

var enemy:Enemy_mc = new Enemy_mc();
var waypoints:Array = [
	new Point(550, 0),
	new Point(0, 100),
	new Point(550, 200),
	new Point(0, 300),
	new Point(550, 400)
	];

enemy.x = 600;
enemy.y = 0;
enemy.currentWaypoint = 0;
enemy.speed = 5;
stage.addChild(enemy);

function eFrame(evt:Event):void {
	if (!stage.contains(enemy)) {
		return;
	}
	var dir:Number = Math.atan2(waypoints[enemy.currentWaypoint].y - enemy.y, waypoints[enemy.currentWaypoint].x - enemy.x);

	enemy.x = enemy.x + Math.cos(dir) * enemy.speed;
	enemy.y = enemy.y + Math.sin(dir) * enemy.speed;

	var distance:int = Point.distance(new Point(enemy.x, enemy.y), new Point(waypoints[enemy.currentWaypoint].x, waypoints[enemy.currentWaypoint].y));
	if (distance < 5) {
		++enemy.currentWaypoint;
		if (enemy.currentWaypoint < waypoints.length - 1) {
			stage.removeChild(enemy);
		}
	}
}

Explanation

Lines 1 & 2 are the imports for classes we’ll need. flash.geom.Point is a very simple class that gives us an x and y instance variable. We’ll also use it in a bit to get the distance between two points.

Line 4 adds our event listener that will call the eFrame function each time the frame loops.

Lines 6 and 15-19 create an enemy instance, put it off the right side of the stage, and add two new variables to store the current waypoint and the speed.

Lines 7 – 13 create an array of waypoints using the Point class.

Lines 21 – 37 are the eFrame callback function that fires on every frame.

Lines 22 – 24 just check to make sure the enemy is on the stage. If it’s not, the function returns and nothing happens.

Line 25 gets the angle between the enemy’s current point and the next waypoint.

Lines 27 & 28 use a bit of trig to get the x and y deltas that match the speed. Speed is the hypotenuse of the triangle, but we can’t move diagonally without knowing the x and y deltas.

Line 30 uses the Point class to get the distance between the enemy’s current point and the next waypoint.

Lines 31 – 36 check to see if the enemy is within 5 pixels of the next waypoint. If it is, the enemy moves on to the next waypoint. If adding one to the current waypoint takes it past the number of waypoints (line 33) then the enemy is removed from the stage.

In the real world

This bit of code isn’t the “correct” way to do this. Real world would probably be more object oriented.

If I were using this technique in a game, and I have, I would create the enemy as a class, store the array of waypoints as a static variable, and the current waypoint as an instance variable. The frame handler code would also be inside the enemy class. Then it’s just a matter of adding as many enemies as I want to the stage.

Published inCoding

2 Comments

    • You’re right, though not really a typo. It’s the editor in WordPress converting the < symbol to its HTML entity code.

Leave a Reply

Your email address will not be published. Required fields are marked *