Skip to main content
Version: Next

Enemy patrol (Walker)

This example shows a patrolling enemy using Walker with draggable obstacles in the preview:

  • move along waypoints
  • obstacle avoidance
  • live route invalidation by dragging blockers
  • optional debug rendering

Enemy with a walker

import { GameObject, SquareHitbox, Vector, Walker } from "sliver-engine";

class PatrollingEnemy extends GameObject {
constructor(position: Vector) {
super("enemy", position);
this.addHitbox(new SquareHitbox(Vector.zero(), new Vector(16, 16), this));
this.setPhisics({ immovable: false });

const walker = new Walker(
this,
[new Vector(100, 100), new Vector(300, 100), new Vector(300, 220)],
90, // movement speed in pixels per second
true, // debug
true, // cyclic
{
avoidObstacles: true,
gridCellSize: 16,
recalculateEveryTicks: 30,
pathNotFoundBehavior: "snap",
snapTargetToEdgeDistance: 32,
}
);

this.setWalker(walker);
walker.start();
}
}

Drop it into your scene:

mainScene.addGameObject(new PatrollingEnemy(new Vector(100, 100)));

If you don’t want pathfinding, remove the pathfindingOptions (or set avoidObstacles: false).

Walker speed is time-based, so author it in pixels per second.

Interactive example

This sandbox runs a patrolling enemy with Walker.

  • Edit PatrollingEnemy.ts to tweak waypoints and walker options.
  • Drag the darker walls in the preview to invalidate the current path.
  • Press Run to apply changes.
import { GameObject, SquareHitbox, Vector, Walker } from "sliver-engine";

const ENEMY_SIZE = 18;

export class PatrollingEnemy extends GameObject {
	constructor(position: Vector) {
		super("enemy", position.clone());
		this.addHitbox(
			new SquareHitbox(Vector.zero(), new Vector(ENEMY_SIZE, ENEMY_SIZE), this, {
				solid: true,
				debug: false,
			}),
		);
		this.setPhisics({ immovable: false, affectedByGravity: false });

		this.setRenderFunction((obj, canvas) => {
			const pos = obj.getPosition();
			canvas
				.getShapeDrawer()
				.drawRectangle(pos.x, pos.y, ENEMY_SIZE, ENEMY_SIZE, "#f59e0b", true);
		});

		const walker = new Walker(
			this,
			[
				new Vector(92, 72),
				new Vector(398, 72),
				new Vector(398, 220),
				new Vector(92, 220),
			],
			96,
			true,
			true,
			{
				avoidObstacles: true,
				gridCellSize: 16,
				recalculateEveryTicks: 20,
				pathNotFoundBehavior: "snap",
				snapTargetToEdgeDistance: 32,
			},
		);

		this.setWalker(walker);
		walker.start();
	}
}