Phaser AE

Projectile Patterns

Free packv3.0.0-32DArcade

Aimed, fan, ring, spiral, burst and staged volleys, with swept hits, piercing, ricochet, homing and grazes. It moves the projectiles and reports what they hit; your game draws them and decides what a hit costs.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 14, 2026 · updated October 20, 2026

Projectile Patterns: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

The pack

projectilePatterns

function projectilePatterns():Pack<{projectilePatterns:typeof rules}>

Install renderer-independent projectile patterns policies.

Helpers

createProjectiles

function createProjectiles()

Create an empty projectile system.

patternShots

function patternShots(p: ProjectilePattern, aim = 0): PatternShot[]

Pure pattern schedule, relative to emission. Aim is in radians; angles are never renderer coordinates.

Classes

Projectiles

class Projectiles

Owns emission, swept collisions, lifetime and per-projectile hit/graze sets. Damage is emitted for a combat adapter.

  • time: number — Seconds elapsed on this projectile clock.
  • shots: Projectile[] — The projectiles in flight; those still waiting to launch are not listed.
  • readonly events: ProjectileEvent[] — Events since the last drain, in order.
  • emit(pattern: ProjectilePattern, origin: Point, aim: number, team: string, damage = 1): number[] — Schedule a volley from origin along aim (radians) for team, each projectile carrying damage (default 1). Shots with no delay launch at once. Returns the ids of every projectile it schedules. Throws on a pattern value outside its bounds or a non-finite damage.
  • tick(dt: number, targets: readonly ProjectileTarget[] = [], walls: readonly Rect[] = [], graze = 8) — Advance by dt seconds (0 to 10) in substeps of at most 1/120 s: launch due shots, move them, hit living targets of other teams, stop or bounce them at walls (rectangles whose x, y are the top-left corner) and expire them. A near miss within graze world units (default 8) of a target's edge raises a graze event. Throws when dt is outside 0 to 10 or graze is negative.
  • drain() — Take the pending events and clear them.
  • clear() — Remove every projectile, pending launch and event; the clock and id counter keep their values.
  • snapshot() — A plain copy of the clock, the id counter, the projectiles and the pending launches.
  • restore(s: ReturnType<Projectiles['snapshot']>) — Replace the state with a snapshot's and clear the events. Throws when a time, id counter, position or life in it is out of range.

Types

PatternKind

type PatternKind = 'aimed' | 'fan' | 'ring' | 'spiral' | 'burst' | 'staged'

How a volley's shots are arranged: aimed (all along the aim), fan (spread across an arc), ring (evenly round a circle), spiral (one at a time, each turned from the last), burst (one at a time along the aim) or staged (several rings in turn).

PatternShot

interface PatternShot

One shot of a volley's schedule, relative to emission.

  • at: number — Seconds after emission that it launches.
  • angle: number — Launch direction in radians: the velocity is (cos, sin) times the speed, so 0 points along +x.

Projectile

interface Projectile extends Point

A projectile in flight; x and y are its position in world units.

  • id: number — Unique id within its Projectiles, counting up from 1.
  • team: string — The team that fired it; targets of the same team are ignored.
  • vx: number — Velocity along x, world units a second.
  • vy: number — Velocity along y, world units a second.
  • rot: number — Heading in radians, atan2(vy, vx), for facing a sprite.
  • r: number — Collision radius, world units.
  • life: number — Seconds of life left; it is removed at 0.
  • damage: number — Damage each hit event carries.
  • pierce: number — Further targets it can pass through before a hit stops it.
  • ricochet: number — Wall reflections it has left.
  • homing: number — Turn rate towards the nearest living target of another team, radians a second; 0 flies straight.
  • hits: string[] — Ids of the targets it has already hit; each is hit at most once.
  • grazed: string[] — Ids of the targets it has already grazed; each is grazed at most once.

ProjectileEvent

interface ProjectileEvent

Something that happened to a projectile, for a combat adapter, sound or effects.

  • kind: 'spawn' | 'hit' | 'graze' | 'bounce' | 'expired' — What happened: spawn (launched), hit, graze (a near miss), bounce (off a wall) or expired (life ran out or it was stopped).
  • projectile: number — Id of the projectile.
  • target: string — Id of the target hit or grazed; an empty string for the other kinds.
  • damage: number — Damage dealt by a hit; 0 for the other kinds.
  • time: number — Seconds on the Projectiles clock when it happened.

ProjectilePattern

interface ProjectilePattern

A volley: its arrangement, size, speed and what each projectile carries.

  • kind: PatternKind — The arrangement of the shots.
  • count: number — Shots per volley, or per ring for ring and staged; a whole number from 1 to 256.
  • speed: number — Projectile speed, world units a second; above 0.
  • spread?: number — fan only: the arc across which the shots spread, in radians from 0 to 2π, centred on the aim. Default 0.7.
  • interval?: number — Seconds between launches for burst and spiral (between shots) and staged (between rings). Default 0.12.
  • stages?: number — staged only: the number of rings, a whole number from 1 to 32. Default 3.
  • rotation?: number — Radians each step turns: between successive shots for spiral (default 0.4) and between rings for staged (default 0.24). Ignored by the other kinds.
  • radius?: number — Collision radius of each projectile, world units, at least 0.01. Default 4.
  • life?: number — Seconds a projectile lives, from 0.001 to 60. Default 5.
  • pierce?: number — Further targets a projectile passes through after its first hit, a whole number from 0 to 100. Default 0, which stops it at the first.
  • ricochet?: number — Wall reflections a projectile has, a whole number from 0 to 100. Default 0, which stops it at the first wall.
  • homing?: number — Turn rate towards the nearest living target of another team, radians a second; 0 flies straight. Default 0.

ProjectileTarget

interface ProjectileTarget extends Point

Something projectiles can hit: a circle at x, y in world units.

  • id: string — Unique id, reported in events.
  • team: string — Its team; projectiles ignore targets of their own team.
  • r: number — Collision radius, world units.
  • alive: boolean — Whether it can be hit; a target that is not alive is skipped.