Phaser AE

Swinging rope

Free packv3.0.0-12DPhysics

A rope for a body to fire and swing on, on a `physics-2d` world: a ninja rope that wraps round corners, a grappling hook, or a straight grapple arm that climbs ledges. The body, the world and its walking and jumping are your game's; this is the rope.

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

Released October 19, 2026

Swinging rope: 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

ropeSwing

function ropeSwing(): Pack<{ ropeSwing: RopeSwingApi }>

The rope-swing pack: game.ropeSwing, swinging ropes for bodies on a physics-2d world.

Functions

createRopeSwing

function createRopeSwing(world: World, body: number, options: RopeSwingOptions): RopeSwing

Make a rope for a body on a world.

segmentEnters

function segmentEnters(ax: number, ay: number, bx: number, by: number, s: SwingSurface): number | null

Where a segment first enters a convex surface, as a fraction along it, or null when it does not. Edges do not count.

surfaceCorners

function surfaceCorners(s: SwingSurface): [number, number][]

A surface's corners, in order.

Constants

ropeSwingPresets

const ropeSwingPresets: { readonly ninja: { readonly range: 420; readonly wrap: true; readonly payOut: true; readonly mantle: 0; readonly reelSpeed: 220; }; readonly grapple: { readonly range: 340; readonly wrap: false; readonly payOut: false; readonly mantle: 64; readonly reelSpeed: 260; }; }

The two presets: the Worms ninja rope, and a straight grapple arm with a mantle.

Types

RopeSwing

interface RopeSwing

The rope, live.

  • readonly attached: boolean — Whether the rope is hooked.
  • readonly mantling: boolean — Whether the body is climbing onto a ledge (a mantle); the rope has let go once it is up.
  • fire(target: SwingPoint): { surface: string; x: number; y: number } | null — Fire at a point: hook the first hookable surface along the line within range. Lets go of any rope first.
  • release(): void — Let go: the body keeps its momentum.
  • reel(direction: number, dt: number): void — Reel in (1) or pay out (-1), any amount between, for dt seconds.
  • step(dt: number): void — After each world step: wrap and unwrap, move the bend, set the length.
  • readonly length: number — The rope's whole length (hook to body, along its bends), or 0 when not hooked.
  • line(): SwingPoint[] — The rope's line: hook, bends, then the body; empty when not hooked.
  • readonly taut: boolean — Whether it is pulled straight between its last bend and the body.
  • readonly hook: { surface: string; x: number; y: number } | null — Where it is hooked, and to what.
  • drain(): RopeSwingEvent[] — What happened since the last drain, oldest first.

RopeSwingApi

interface RopeSwingApi

What the rope-swing pack adds to a game: game.ropeSwing.

  • create: typeof createRopeSwing — Make a rope for a body on a physics-2d world.
  • presets: typeof ropeSwingPresets — The ninja rope and the grapple arm.

RopeSwingEvent

type RopeSwingEvent = | { kind: 'hook'; surface: string; x: number; y: number } | { kind: 'miss' } | { kind: 'wrap'; x: number; y: number } | { kind: 'unwrap'; x: number; y: number } | { kind: 'release' } | { kind: 'jam' } | { kind: 'mantle'; surface: string }

What happened, for the caller and the presenter.

RopeSwingOptions

interface RopeSwingOptions

How the rope behaves.

  • surfaces: SwingSurface[] — The surfaces it hooks and wraps round. A surface is hookable unless it says hookable: false.
  • range?: number — The furthest it reaches, and the longest it pays out to. Default 420.
  • shortest?: number — The shortest it reels in to, beyond its bends. Default 16.
  • reelSpeed?: number — How fast it reels, units per second. Default 220.
  • wrap?: boolean — Wrap round corners (the ninja rope). False is a straight arm that lets go when terrain crosses it. Default true.
  • payOut?: boolean — Allow paying out, past the length it hooked at. Default true.
  • mantle?: number — Mantle: reeled in to within this of a hook on a ledge's top, or near one of its top corners (within 40 on any face), the body climbs up over the edge onto the top and lets go. Default 0 (off). The grapple preset uses 64: a body pressed against the ledge below its hook is about that far from it.
  • mantleTime?: number — Seconds a mantle takes. Default 0.3.
  • bends?: number — The most bends the rope keeps; past it the rope jams and lets go. Default 24.

SwingPoint

interface SwingPoint

A point.

  • x: number — Across.
  • y: number — Down.

SwingSurface

type SwingSurface = | { id: string; kind: 'box'; x: number; y: number; width: number; height: number; hookable?: boolean } | { id: string; kind: 'polygon'; points: ReadonlyArray<readonly [number, number]>; hookable?: boolean }

A surface the rope can hook and wrap round: a convex polygon, or a box (centre and size, unturned).