Phaser AE

Geometry

Free packv3.0.0-32DLogic

The mathematics of 2D shapes, with nothing to do with drawing them. A shape is plain data with a `kind`, and one set of functions answers what a game needs to know about it: points along it, random points inside it, whether it contains a point, where a line crosses it and whether it overlaps another.

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

Released October 14, 2026 · updated October 20, 2026

Geometry: 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

geometry

function geometry(): Pack<{ geometry: GeometryApi }>

The geometry pack: shapes and curves as data with the maths on them — points along, random inside, contains, bounds, transforms, intersections. Headless, no columns, no passes. Particle zones, paths and AI read it.

Helpers

encircled

function encircled(path: ReadonlyArray<Vec2>, p: Vec2): boolean

Is the point inside the loop the trail has just closed? False while the trail has closed none.

encircledAll

function encircledAll<T extends Vec2>(path: ReadonlyArray<Vec2>, targets: ReadonlyArray<T>): T[]

Every target inside the loop the trail has just closed; none while it has closed none.

findLoop

function findLoop(path: ReadonlyArray<Vec2>): Vec2[] | null

The loop a trail has just closed, or null: when the trail's newest segment crosses an earlier one, the polygon from the crossing round the trail and back to it. Draw a lasso, encircle enemies (Quantum), close off territory.

points

function points(s: Shape, n: number, seamless = true): Vec2[]

n points along the outline or curve, evenly by length; seamless (default true) leaves out the closing duplicate on a closed shape.

scale

function scale(s: Shape, sx: number, sy = sx, ox = 0, oy = 0): Shape

Scale a shape about (ox, oy): a new shape. A circle scaled unevenly becomes an ellipse.

Functions

area

function area(s: Shape): number

The enclosed area; 0 for curves and lines. A polygon's is unsigned.

bake

function bake(s: Shape, samples = 128): { points: Float32Array; length: number; closed: boolean }

Bake a shape by ARC LENGTH: samples points (default 128, at least 2) spaced evenly along it, as a flat [x, y, …] Float32Array, with its length and whether it is closed (an area's outline). bakedAt on the result moves at constant speed, which pointAt on a bezier or spiral does not.

bakedAt

function bakedAt(b: { points: Float32Array; closed: boolean }, t: number, out: Vec2 = { x: 0, y: 0 }): Vec2

The point at t (0..1 by length) on a baked curve.

bounds

function bounds(s: Shape): Box

The axis-aligned bounding box. Curves are sampled.

centroid

function centroid(s: Shape): Vec2

The centroid: area-weighted for areas, the midpoint of the bounds for curves.

closestPoint

function closestPoint(s: Shape, x: number, y: number): Vec2

The closest point on the shape's outline (or curve) to (x, y); sampled for curves, exact for lines, circles and polygons.

contains

function contains(s: Shape, x: number, y: number): boolean

Does the shape contain the point? Curves, lines and points never do; a ring is the band between inner and r.

isCurve

function isCurve(s: Shape): boolean

Is the shape a curve or outline only (no inside)? Points, lines, arcs, beziers, open splines, spirals, waves, paths.

length

function length(s: Shape): number

The outline's length (perimeter), or the curve's length. Curves are measured by 64 samples.

lineIntersections

function lineIntersections(ax: number, ay: number, bx: number, by: number, s: Shape): Vec2[]

Where segment (ax, ay)→(bx, by) crosses the shape's outline, as points along the segment in order; empty when it does not. Lines, circles, rings and polygons exact; other shapes via 48 points on their outline. An area's outline is closed; an open curve (an arc, a bezier, an open spline, a spiral, a wave) is walked from one end to the other, never across the gap between its ends. A path is tested segment by segment, and a point is crossed only when the segment passes through it.

overlaps

function overlaps(a: Shape, b: Shape): boolean

Do two area shapes overlap (share any interior or touch)? Exact for circle/circle, circle/rect, rect/rect; everything else via polygons (separating axes for convex, edge tests plus containment otherwise). Curves never overlap.

pointAt

function pointAt(s: Shape, t: number, out: Vec2 = { x: 0, y: 0 }): Vec2

The point at t (0..1) along the shape's outline, or along the curve. Closed shapes wrap; a rect starts at its top-left and goes clockwise; a circle starts at its right (0°).

pointsByStep

function pointsByStep(s: Shape, step: number): Vec2[]

Points along the outline or curve spaced step units apart (by length).

randomPoint

function randomPoint(s: Shape, rng: Rng, out: Vec2 = { x: 0, y: 0 }): Vec2

A uniformly random point INSIDE an area shape, or ON a curve, line or point. Rejection-samples polygons against their bounds.

rotate

function rotate(s: Shape, deg: number, ox = 0, oy = 0): Shape

Rotate a shape about (ox, oy) by deg degrees: a new shape. Circles, rings and ellipses move but keep their axes; a rect becomes a polygon.

toPolygon

function toPolygon(s: Shape, samples = 32): Extract<Shape, { kind: 'polygon' }>

The outline as a polygon (curves and round shapes sampled with samples points).

translate

function translate(s: Shape, dx: number, dy: number): Shape

Move a shape by (dx, dy): a new shape.

Constants

geometryApi

const geometryApi: GeometryApi

The geometry API object, for packs that import rather than compose.

SHAPE_KINDS

const SHAPE_KINDS: ReadonlyArray<ShapeKind>

Every shape kind.

Types

Box

interface Box

An axis-aligned box.

  • x: number — Left.
  • y: number — Top.
  • w: number — Width.
  • h: number — Height.

GeometryApi

interface GeometryApi

game.geometry: every function of this module by name, plus the shape kinds.

  • pointAt: typeof pointAt — The point at t along the outline or curve.
  • length: typeof length — Outline or curve length.
  • area: typeof area — Enclosed area.
  • points: typeof points — n points along the outline, evenly by length.
  • pointsByStep: typeof pointsByStep — Points spaced step apart.
  • contains: typeof contains — Point-in-shape.
  • randomPoint: typeof randomPoint — A random point inside (or on a curve).
  • bounds: typeof bounds — Bounding box.
  • centroid: typeof centroid — Centroid.
  • closestPoint: typeof closestPoint — Closest outline point.
  • translate: typeof translate — Move.
  • rotate: typeof rotate — Rotate, degrees, about a point.
  • scale: typeof scale — Scale about a point.
  • toPolygon: typeof toPolygon — The outline as a polygon.
  • lineIntersections: typeof lineIntersections — Segment–outline crossings.
  • overlaps: typeof overlaps — Two areas overlap.
  • isCurve: typeof isCurve — Is it a curve (no inside)?
  • bake: typeof bake — Bake by arc length.
  • bakedAt: typeof bakedAt — A point on a baked curve.
  • findLoop: typeof findLoop — The loop a self-crossing trail has just closed.
  • encircled: typeof encircled — Is a point inside the loop the trail just closed?
  • encircledAll: typeof encircledAll — Every target inside the loop the trail just closed.
  • readonly kinds: ReadonlyArray<ShapeKind> — Every shape kind.

Shape

type Shape = | { kind: 'point'; x: number; y: number } | { kind: 'line'; x1: number; y1: number; x2: number; y2: number } | { kind: 'circle'; x: number; y: number; r: number } | { kind: 'ring'; x: number; y: number; r: number; inner: number } | { kind: 'arc'; x: number; y: number; r: number; start: number; end: number } | { kind: 'sector'; x: number; y: number; r: number; start: number; end: number } | { kind: 'ellipse'; x: number; y: number; rx: number; ry: number } | { kind: 'rect'; x: number; y: number; w: number; h: number } | { kind: 'triangle'; x1: number; y1: number; x2: number; y2: number; x3: number; y3: number } | { kind: 'polygon'; points: ReadonlyArray<number> } | { kind: 'quadratic'; x1: number; y1: number; cx: number; cy: number; x2: number; y2: number } | { kind: 'cubic'; x1: number; y1: number; c1x: number; c1y: number; c2x: number; c2y: number; x2: number; y2: number } | { kind: 'spline'; points: ReadonlyArray<number>; closed?: boolean } | { kind: 'spiral'; x: number; y: number; r1: number; r2: number; turns: number; start?: number } | { kind: 'wave'; x1: number; y1: number; x2: number; y2: number; amplitude: number; cycles: number; shape?: 'sine' | 'zigzag' | 'square' } | { kind: 'path'; segments: ReadonlyArray<Shape> }

A shape or curve, by kind. Angles in degrees (0 right, 90 down), positions in world units. points lists are flat [x, y, x, y…]. spiral winds from radius r1 to r2 over turns from angle start; wave runs from (x1, y1) to (x2, y2) with cycles oscillations of amplitude across it.

ShapeKind

type ShapeKind = Shape['kind']

A shape's kind name.

Vec2

interface Vec2

A point.

  • x: number — x.
  • y: number — y.