The pack
cutRope
function cutRope(): Pack<{ cutRope: CutRopeApi }>
The cut-rope pack: game.cutRope, Cut the Rope's rules on a rope world of the game's own per level.
Functions
alongPath
function alongPath(points: ReadonlyArray<RopeVec>, distance: number, mode: 'pingpong' | 'loop' = 'pingpong'): RopeVec
The point distance along a polyline, going back and forth ('pingpong') or round it ('loop').
createCutRope
function createCutRope(level: CutRopeLevel, options: CutRopeOptions = {}): CutRopeGame
Make a game of a level. Throws, listing every problem, on a level validateCutRopeLevel refuses.
validateCutRopeLevel
function validateCutRopeLevel(level: CutRopeLevel, kinds: ReadonlyArray<string> = []): string[]
Check a level and say what is wrong with it, as plain sentences; empty when it can be played.
Constants
cutRopeDefaults
const cutRopeDefaults: { readonly candyRadius: 16; readonly candyMass: 10; readonly ropeMass: 0.5; readonly ropeRadius: 3; readonly slack: 0.05; readonly mouthRadius: 32; readonly starRadius: 18; readonly bubbleRadius: 34; ... 7 more ...; readonly margin: 60; } …
The defaults every level element falls back on.
cutRopeLevels
const cutRopeLevels: { readonly classic: readonly CutRopeLevel[]; readonly tower: readonly CutRopeLevel[] }
The built-in levels, by box.
Types
CutRopeApi
interface CutRopeApi
What the cut-rope pack adds to a game: game.cutRope.
create: typeof createCutRope— Make a game of a level.validate: typeof validateCutRopeLevel— Check a level; empty when it can be played.levels: typeof cutRopeLevels— The built-in box of levels, a preset to start from.defaults: typeof cutRopeDefaults— The defaults level elements fall back on.alongPath: typeof alongPath— A point along a hook's path.
CutRopeBubble
interface CutRopeBubble
A bubble: a candy that drifts into it floats away from gravity at rise units per second until it is tapped.
x: number— Where it is, across.y: number— Where it is, down.radius?: number— Its radius. Default 34.rise?: number— How fast it floats, units per second. Default 150.
CutRopeCandy
interface CutRopeCandy
A candy: what the ropes hold and a mouth eats.
id: string— Its id, unique in the level.x: number— Where it starts, across.y: number— Where it starts, down.radius?: number— Its radius. Default 16.mass?: number— Its mass, against the ropes' (each rope weighs 0.5). Default 10.
CutRopeContext
interface CutRopeContext
What a registered element can reach.
readonly world: RopeWorld— The rope world: ropes, loads, colliders.readonly candies: ReadonlyMap<string, RopeLoad>— The candies still in play, by id.readonly level: Readonly<CutRopeLevel>— The level being played.readonly state: Readonly<CutRopeState>— The game's state.emit(name: string, detail?: unknown): void— Tell the presenter something happened: anelementevent from this element.lose(candy: string): void— Lose the game: this candy is destroyed.
CutRopeCushion
interface CutRopeCushion
An air cushion: tapping it puffs every candy in front of it, within reach and spread radians of angle, with an
impulse of strength (mass times units per second) at the cushion that falls off to 40% at reach.
x: number— Where it is, across.y: number— Where it is, down.angle: number— Which way it blows, radians (0 is +x, y down).strength?: number— The impulse at the cushion's mouth. Default 4000: a 10-mass candy at 400 units per second.reach?: number— How far the puff reaches. Default 260.spread?: number— Half the puff's angle, radians. Default 0.5.size?: number— How near a tap must be to puff it. Default 40.
CutRopeElement
interface CutRopeElement
An element of a kind the game registered: kind names it, and the rest is that kind's data.
kind: string— The registered kind's name.[key: string]: unknown— The kind's own data.
CutRopeElementKind
interface CutRopeElementKind<S = unknown>
A kind of element a game adds to the level format: a teleport, a fan, a moving spike. One instance per level entry of that kind. Its state must be plain JSON, so saves can carry it.
create(entry: CutRopeElement, ctx: CutRopeContext): S— Make an instance's state from its level entry.step?(state: S, ctx: CutRopeContext, dt: number): void— Run every step, after the ropes moved and the built-in rules ran.tap?(state: S, ctx: CutRopeContext, point: RopeVec): boolean— A tap at a point. Return true when this element took it, so nothing else does.view?(state: S, ctx: CutRopeContext): unknown— What a presenter draws for it.
CutRopeEvent
type CutRopeEvent = | { kind: 'cut'; rope: string; cause: 'swipe' | 'tear' | 'call' } | { kind: 'star'; star: number; candy: string } | { kind: 'star-gone'; star: number } | { kind: 'tie'; pin: number; candy: string; rope: string } | { kind: 'bubble'; bubble: number; candy: string } | { kind: 'pop'; bubble: number; candy: string } | { kind: 'puff'; cushion: number } | { kind: 'gravity'; switch: number; down: boolean } | { kind: 'eat'; mouth: number; candy: string } | { kind: 'lost'; candy: string; cause: 'hazard' | 'out' } | { kind: 'won'; stars: number } | { kind: 'element'; element: number; name: string; detail?: unknown }
What happened, for the presenter to show and sound.
CutRopeGame
interface CutRopeGame
A game of Cut the Rope on one level.
readonly level: Readonly<CutRopeLevel>— The level, as played (a copy of the one given).readonly state: Readonly<CutRopeState>— The state, live.readonly world: RopeWorld— The rope world, for drawing or for a registered element. A restart or a restore replaces it.step(dt: number): void— Advance bydtseconds: the ropes, then the rules. Does nothing once the game is won or lost.swipe(path: ReadonlyArray<RopeVec>): number— Cut every rope the polyline crosses (this step or the last). Returns how many ropes it cut.tap(point: RopeVec): string | null— A tap: pop a bubble, puff a cushion, flip gravity, or whatever a registered element takes. What took it, or null.drain(): CutRopeEvent[]— What happened since the last drain, oldest first.view(): CutRopeView— Everything to draw.restart(): void— Start the level again.snapshot(): CutRopeSave— The game as plain JSON, to resume later on the same level.restore(save: CutRopeSave): void— Resume a snapshot of this level. Throws on one of another level, and the game is left as it was.
CutRopeHook
interface CutRopeHook
A hook a rope hangs from: still, sliding along a path, or going round a centre.
x: number— Where it is across: the hook itself, or the centre of an orbit.y: number— Where it is down.path?: { points: ReadonlyArray<RopeVec>; speed: number; mode?: 'pingpong' | 'loop'; offset?: number }— Slide along these points atspeedunits per second, back and forth ('pingpong', the default) or round and round ('loop'), startingoffsetunits along.orbit?: { radius: number; speed: number; phase?: number }— Go round (x, y) atradius,speedturns per second (negative is anticlockwise), starting atphaseturns.
CutRopeLevel
interface CutRopeLevel
A level. Units are the game's, 2D with y down; a candy that leaves the play area by margin is lost.
id?: string— Its id, which saves carry.name?: string— A name to show.width: number— The play area's width, from x = 0. It may be larger than the screen: a tall or wide level scrolls.height: number— The play area's height, from y = 0.margin?: number— How far past the play area a candy may go before it is lost. Default 60.gravity?: number— Gravity, units per second squared, down. Default 900.candies: CutRopeCandy[]— The candies, at least one.mouths: CutRopeMouth[]— The mouths, at least one. The level is won when every candy is eaten.ropes: CutRopeRope[]— The ropes the level starts with (rope pins add more).stars?: CutRopeStar[]— Stars to collect, for a rating.pins?: CutRopePin[]— Rope pins.bubbles?: CutRopeBubble[]— Bubbles.cushions?: CutRopeCushion[]— Air cushions.switches?: CutRopeSwitch[]— Gravity switches.hazards?: RopeCollider[]— Shapes that destroy a candy that touches them: spikes, saws, electricity.walls?: RopeCollider[]— Solid shapes candies bounce off and ropes drape over.elements?: CutRopeElement[]— Elements of kinds the game registered.
CutRopeMouth
interface CutRopeMouth
A mouth (Om Nom): a candy that reaches it is eaten.
x: number— Where it is, across.y: number— Where it is, down.radius?: number— How close a candy's centre must come, plus half the candy's radius. Default 32.candy?: string— Eat only this candy: two mouths, two candies, each its own colour. Default any candy.angle?: number— Which way it faces, for drawing: radians,-Math.PI / 2(up, the default) sits on a ledge,Math.PI / 2hangs.
CutRopeOptions
interface CutRopeOptions
How a game is made.
elements?: Record<string, CutRopeElementKind<unknown>>— Element kinds beyond the built-in ones, by thekindlevel entries use.rope?: Omit<RopeWorldOptions, 'gravity' | 'flat'>— The rope world's options: step, iterations, substeps, damping. Gravity comes from the level.
CutRopePin
interface CutRopePin
A rope pin: when a candy comes within reach, a rope of that length ties itself from the pin to the candy, once.
x: number— Where it is, across.y: number— Where it is, down.reach: number— How near the candy must come; also the new rope's length unlesslengthsays otherwise.length?: number— The new rope's length. Defaultreach.
CutRopeRope
interface CutRopeRope
A rope from a hook to a candy.
id?: string— Its id, for events and hints. Defaultrope-<index>.hook: CutRopeHook— What it hangs from.candy?: string— The candy it holds. Default the level's first candy.length?: number— Its length. Default the distance from the hook to the candy, times1 + slack.slack?: number— Extra length as a fraction of the distance, whenlengthis not given. Default 0.05: just slack enough to hang.radius?: number— Its thickness, a radius. Default 3.
CutRopeSave
interface CutRopeSave
A saved game.
format: 'phaser-ae-cut-rope'— Always'phaser-ae-cut-rope'.version: 1— The save format's version, 1.level: string— The level's id ('' for a level without one).state: CutRopeState— The game's state.world: RopeSnapshot— The rope world.holds: [string, string][]— Which candy each rope in the world holds.pinsUsed: boolean[]— Which rope pins have tied their rope.bubbles: { candy: string | null; popped: boolean }[]— What each bubble holds, and whether it has popped.puffs: (number | null)[]— When each cushion last puffed, level seconds, or null.elements: unknown[]— Each registered element's state.
CutRopeStar
interface CutRopeStar
A star, collected when a candy passes through it.
x: number— Where it is, across.y: number— Where it is, down.radius?: number— Its radius. Default 18.timer?: number— A timed star: it is gone this many seconds into the level. Default never.
CutRopeState
interface CutRopeState
The game's state.
phase: 'playing' | 'won' | 'lost'—'playing'until every candy is eaten ('won') or one is lost ('lost').time: number— Seconds played.stars: number— Stars collected.taken: boolean[]— Which stars are collected, in level order.eaten: string[]— The candies eaten, by id.lost: { candy: string; cause: 'hazard' | 'out' } | null— How a lost game was lost.down: boolean— Whether gravity points down (it flips with a switch).
CutRopeSwitch
interface CutRopeSwitch
A gravity switch: tapping it turns gravity upside down, and back.
x: number— Where it is, across.y: number— Where it is, down.size?: number— How near a tap must be. Default 32.
CutRopeView
interface CutRopeView
Everything a presenter draws, in level units.
candies: { id: string; x: number; y: number; vx: number; vy: number; radius: number; bubble: number | null; eaten: boolean }[]— Every candy, eaten ones too, and which bubble holds it.mouths: { x: number; y: number; radius: number; angle: number; candy?: string; open: number }[]— Each mouth, and how wide open it is (0 to 1) as a candy it wants comes near.ropes: { id: string; candy: string; runs: number[][]; holding: boolean; radius: number }[]— Each rope's uncut stretches as[x0, y0, z0, x1, …](once its candy is eaten, only the one hanging from its hook), and whether it still holds its candy.hooks: { rope: string; x: number; y: number; moving: boolean }[]— Where each rope's hook is now.stars: { x: number; y: number; radius: number; taken: boolean; gone: boolean; left: number | null }[]— Each star: taken, gone (a timed star whose time is up), and seconds left (null for an untimed one).pins: { x: number; y: number; reach: number; used: boolean }[]— Each rope pin, and whether it has tied its rope.bubbles: { x: number; y: number; radius: number; candy: string | null; popped: boolean }[]— Each bubble: where it is (on its candy while it holds one), and whether it has popped.cushions: { x: number; y: number; angle: number; reach: number; spread: number; size: number; puffed: number }[]— Each cushion, and seconds since it last puffed (Infinity before the first).switches: { x: number; y: number; size: number }[]— Each gravity switch.hazards: RopeCollider[]— The hazards, as the level gave them.walls: RopeCollider[]— The walls, as the level gave them.elements: { kind: string; view: unknown }[]— What each registered element'sviewreturned, in level order.down: boolean— Whether gravity points down.


