Curves And Paths
Use this skill when working with curves and paths in Phaser 4. Covers splines, bezier curves, lines, ellipses, path followers, and mathematical curve types. Triggers on: curve, path, spline, bezier, path follower.
- Skill ID
- phaserjs/phaser/curves-and-paths
- Publisher
- phaserjs
- Repository
- phaser
- Installs
- 0
- Files
- 1
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
phaserjs/phaser/curves-and-pathsInstalls these files- SKILL.md
What this skill tells the agent
Curves and Paths
Creating paths from curves, getting points along them, drawing them with Graphics, and making sprites follow paths automatically using PathFollower in Phaser 4.
Key source paths: src/curves/, src/curves/path/, src/gameobjects/pathfollower/, src/gameobjects/components/PathFollower.js Related skills: ../sprites-and-images/SKILL.md, ../graphics-and-shapes/SKILL.md, ../tweens/SKILL.md
Quick Start
// In a Scene's create() method:
// 1. Create a Path starting at (50, 300)
const path = this.add.path(50, 300);
// 2. Add curves to the path
path.lineTo(200, 100);
path.splineTo([ new Phaser.Math.Vector2(300, 400), new Phaser.Math.Vector2(500, 200) ]);
path.lineTo(700, 300);
// 3. Draw the path using Graphics
const graphics = this.add.graphics();
graphics.lineStyle(2, 0xffffff, 1);
path.draw(graphics, 64);
// 4. Create a PathFollower sprite that moves along the path
const follower = this.add.follower(path, 50, 300, 'ship');
follower.startFollow({
duration: 5000,
rotateToPath: true,
repeat: -1,
yoyo: true
});Core Concepts
Path
A Phaser.Curves.Path is a container that combines multiple Curves into one continuous compound curve. Curves in a Path do not need to be connected end-to-end. Only the order of curves affects point calculations along the path.
Created via factory: this.add.path(x, y) where x/y is the starting point.
Key properties:
curves-- array ofPhaser.Curves.Curveobjects in the PathstartPoint--Vector2, the defined starting positionautoClose-- boolean, if truegetPoints()appends the first point at the enddefaultDivisions-- number (default: 12), divisions per curve when callinggetPoints()name-- string, empty by default, for developer use
Curves
All curve types extend Phaser.Curves.Curve (the base class). Every curve supports:
getPoint(t, out)-- get a point at position t (0-1) based on curve parameterizationgetPointAt(u, out)-- get a point at position u (0-1) based on arc length (evenly spaced)getPoints(divisions, stepRate, out)-- array of points along the curvegetSpacedPoints(divisions, stepRate, out)-- array of equidistant points by arc lengthgetDistancePoints(distance)-- points spaced by pixel distancegetLength()-- total arc length in pixelsgetBounds(out, accuracy)-- bounding RectanglegetTangent(t, out)/getTangentAt(u, out)-- unit tangent vectorgetStartPoint(out)/getEndPoint(out)-- first/last pointsgetRandomPoint(out)-- random point on the curvedraw(graphics, pointsTotal)-- render the curve onto a Graphics objectactive-- boolean, when false the parent Path skips this curve
PathFollower
A Phaser.GameObjects.PathFollower is a Sprite with the Components.PathFollower mixin. It uses an internal Tween (a number counter from 0 to 1) to advance along a Path each frame.
Created via factory: this.add.follower(path, x, y, texture, frame)
The PathFollower component provides:
path-- thePhaser.Curves.Pathbeing followedpathTween-- the internal Tween driving movementpathOffset--Vector2, offset added to path coordinatespathVector--Vector2, current position on the pathpathDelta--Vector2, distance traveled since last framerotateToPath-- boolean, auto-rotate to face path directionpathRotationOffset-- number (degrees), added to auto-rotation
Common Patterns
Creating Paths with Chained Curves
Path has convenience methods that create curves starting from the previous end point:
const path = this.add.path(100, 500);
path.lineTo(300, 100); // straight line
path.cubicBezierTo(500, 100, 350, 50, 450, 50); // cubic bezier (endX, endY, cp1X, cp1Y, cp2X, cp2Y)
path.quadraticBezierTo(700, 400, 600, 100); // quadratic bezier (endX, endY, cpX, cpY)
path.splineTo([ // spline through points
new Phaser.Math.Vector2(750, 300),
new Phaser.Math.Vector2(600, 500)
]);
path.ellipseTo(50, 80, 0, 270, false, 0); // ellipse arc (xRadius, yRadius, startAngle, endAngle, clockwise, rotation)
path.circleTo(40); // shortcut for ellipseTo with equal radii and 0-360
// Jump to a new position without drawing (creates a gap)
path.moveTo(400, 400);
path.lineTo(500, 400);
// Close the path by connecting end to start
path.closePath();Adding Standalone Curve Objects
const path = new Phaser.Curves.Path(0, 0);
// Add pre-constructed curve objects
const line = new Phaser.Curves.Line(new Phaser.Math.Vector2(0, 0), new Phaser.Math.Vector2(200, 200));
path.add(line);
const spline = new Phaser.Curves.Spline([ 200, 200, 300, 100, 400, 300 ]);
path.add(spline);
const ellipse = new Phaser.Curves.Ellipse(400, 300, 100, 60, 0, 360, false, 0);
path.add(ellipse);Getting Points Along a Path
// Array of points (uses defaultDivisions per curve)
const points = path.getPoints();
// With explicit divisions per curve
const detailed = path.getPoints(32);
// Equally spaced points along the entire path
const spaced = path.getSpacedPoints(100);
// Single point at normalized position (0-1)
const midpoint = path.getPoint(0.5);
// Tangent vector at a position
const tangent = path.getTangent(0.5);
// Total path length in pixels
const length = path.getLength();
// Bounding rectangle
const bounds = path.getBounds();Drawing Paths with Graphics
const graphics = this.add.graphics();
// Draw entire path
graphics.lineStyle(2, 0x00ff00, 1);
path.draw(graphics, 64); // 64 = points per curve for smoothness
// Draw individual curves
graphics.lineStyle(1, 0xff0000, 1);
path.curves[0].draw(graphics, 32);
// Draw debug points
const points = path.getSpacedPoints(50);
points.forEach(p => {
graphics.fillStyle(0xffff00, 1);
graphics.fillCircle(p.x, p.y, 3);
});PathFollower Sprite
const path = this.add.path(100, 200);
path.lineTo(400, 400);
path.lineTo(700, 200);
// Create follower
const enemy = this.add.follower(path, 100, 200, 'enemy');
// Start following with config
enemy.startFollow({
duration: 3000, // ms to traverse path
positionOnPath: true, // snap to path start position
rotateToPath: true, // auto-rotate to face direction
rotationOffset: 90, // offset added to auto-rotation (degrees)
repeat: -1, // -1 = infinite repeat
yoyo: true, // reverse on each repeat
from: 0, // start position on path (0-1)
to: 1, // end position on path (0-1)
startAt: 0, // initial seek position
ease: 'Sine.easeInOut' // any valid Phaser ease
});
// Control during playback
enemy.pauseFollow();
enemy.resumeFollow();
enemy.stopFollow();
enemy.isFollowing(); // returns boolean
// Change path at runtime
enemy.setPath(newPath);
enemy.setPath(newPath, { duration: 2000 }); // auto-starts
// Set rotation independently
enemy.setRotateToPath(true, 90); // (value, offsetDegrees)PathFollower with Simple Duration
// Shorthand: pass just a duration number
enemy.startFollow(5000);
// Equivalent to:
enemy.startFollow({ duration: 5000 });All Curve Types
| Curve | Class | Constructor Params | Description |
|---|---|---|---|
| Line | Phaser.Curves.Line | (p0, p1) Vector2 endpoints, or ([x0,y0,x1,y1]) | Straight line segment between two points |
| Spline | Phaser.Curves.Spline | (points) array of Vector2, flat numbers, or nested arrays | Catmull-Rom spline through control points |
| CubicBezier | Phaser.Curves.CubicBezier | (p0, p1, p2, p3) or ([x0,y0,...x3,y3]) | Cubic Bezier with start, 2 control points, end |
| QuadraticBezier | Phaser.Curves.QuadraticBezier | (p0, p1, p2) or ([x0,y0,...x2,y2]) | Quadratic Bezier with start, 1 control point, end |
More from phaserjs
Use this skill in a project
Open any RiverX project, search the Skills panel for phaserjs/phaser/curves-and-paths, and install it in one click.
