curves-and-paths について
Phaser 4 で曲線を組み合わせたパスを作成し、点の取得や描画、PathFollower によるスプライトの移動を行う開発スキルです。曲線ルートやパスに沿った動きを実装するゲーム開発者向けです。
主な機能
- 01直線、スプライン、ベジェ、楕円によるパス作成
- 02パラメーター、弧長、距離による点の取得
- 03Graphics によるパス描画
- 04PathFollower によるスプライト移動
- 05追従時間、オフセット、回転の制御
活用シーン
- 01ゲームオブジェクトの曲線ルート作成
- 02パスの可視化やゲーム内描画
- 03時間指定でスプライトを移動・回転
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ phaserjs/ phaser --skill curves-and-pathsインストール後、Claude Code で/curves-and-pathsを入力して読み込まれたか確認します。
詳細
曲線とパス
曲線からパスを作成し、その上の点を取得し、Graphics で描画し、Phaser 4 の PathFollower を使ってスプライトをパスに自動的に追従させる方法。
主要なソースパス: src/curves/、src/curves/path/、src/gameobjects/pathfollower/、src/gameobjects/components/PathFollower.js
関連スキル: ../sprites-and-images/SKILL.md、../graphics-and-shapes/SKILL.md、../tweens/SKILL.md
クイックスタート
// 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
});
基本概念
パス
Phaser.Curves.Path は、複数の曲線を 1 つの連続した複合曲線にまとめるコンテナです。パス内の曲線は端から端まで接続されている必要はありません。曲線の順序だけが、パスに沿った点の計算に影響します。
ファクトリで作成します: this.add.path(x, y)。ここで x/y は始点です。
主なプロパティ:
curves-- パス内のPhaser.Curves.Curveオブジェクトの配列startPoint--Vector2、定義された開始位置autoClose-- boolean、true の場合getPoints()が最初の点を末尾に追加しますdefaultDivisions-- number(デフォルト: 12)、getPoints()呼び出し時の曲線ごとの分割数name-- string、デフォルトでは空、開発者用
曲線
すべての曲線タイプは Phaser.Curves.Curve(基底クラス)を継承します。すべての曲線は以下をサポートします:
getPoint(t, out)-- 曲線のパラメータ化に基づいて位置 t(0〜1)の点を取得しますgetPointAt(u, out)-- 弧長に基づいて位置 u(0〜1)の点を取得します(等間隔)getPoints(divisions, stepRate, out)-- 曲線に沿った点の配列getSpacedPoints(divisions, stepRate, out)-- 弧長により等距離に配置された点の配列getDistancePoints(distance)-- ピクセル距離で間隔を空けた点getLength()-- 合計弧長(ピクセル単位)getBounds(out, accuracy)-- 境界 RectanglegetTangent(t, out)/getTangentAt(u, out)-- 単位接線ベクトルgetStartPoint(out)/getEndPoint(out)-- 最初/最後の点getRandomPoint(out)-- 曲線上のランダムな点draw(graphics, pointsTotal)-- 曲線を Graphics オブジェクトにレンダリングしますactive-- boolean、false の場合、親 Path はこの曲線をスキップします
PathFollower
Phaser.GameObjects.PathFollower は、Components.PathFollower ミックスインを持つ Sprite です。内部の Tween(0 から 1 への数値カウンター)を使用して、毎フレーム Path に沿って進みます。
ファクトリで作成します: this.add.follower(path, x, y, texture, frame)
PathFollower コンポーネントが提供するもの:
path-- 追従しているPhaser.Curves.PathpathTween-- 移動を駆動する内部 TweenpathOffset--Vector2、パス座標に加算されるオフセットpathVector--Vector2、パス上の現在位置pathDelta--Vector2、前フレームからの移動距離rotateToPath-- boolean、パスの方向を向くように自動回転pathRotationOffset-- number(度)、自動回転に加算される値
一般的なパターン
連鎖した曲線でパスを作成する
Path には、前の終点から始まる曲線を作成する便利なメソッドがあります:
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();
単独の曲線オブジェクトを追加する
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);
パスに沿った点を取得する
// 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();
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 スプライト
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)
シンプルな duration を持つ PathFollower
// Shorthand: pass just a duration number
enemy.startFollow(5000);
// Equivalent to:
enemy.startFollow({ duration: 5000 });
すべてのカーブタイプ
| カーブ | クラス | コンストラクターパラメーター | 説明 |
|---|---|---|---|
| Line | Phaser.Curves.Line | (p0, p1) の Vector2 端点、または ([x0,y0,x1,y1]) | 2 点間の直線セグメント |
| Spline | Phaser.Curves.Spline | (points) の Vector2 配列、フラットな数値、またはネストされた配列 | 制御点を通る Catmull-Rom スプライン |
| CubicBezier | Phaser.Curves.CubicBezier | (p0, p1, p2, p3) または ([x0,y0,...x3,y3]) | 始点、2 つの制御点、終点を持つ 3 次ベジェ |
| QuadraticBezier | Phaser.Curves.QuadraticBezier | (p0, p1, p2) または ([x0,y0,...x2,y2]) | 始点、1 つの制御点、終点を持つ 2 次ベジェ |
| Ellipse | Phaser.Curves.Ellipse | (x, y, xRadius, yRadius, startAngle, endAngle, clockwise, rotation) または設定オブジェクト | 楕円弧。角度は度数法。yRadius はデフォルトで xRadius になります |
Ellipse カーブのプロパティ
Ellipse カーブには、実行時に変更するための get/set プロパティがあります:
x、y-- 中心位置xRadius、yRadius-- 半径startAngle、endAngle-- 度数法(get/set は内部的にラジアンとの変換を行います)clockwise-- ブール値rotation-- ラジアンangle-- 度数法での回転(rotationの代替)setWidth(value)/setHeight(value)-- 半径を value/2 に設定します
API クイックリファレンス
Path (Phaser.Curves.Path)
| API | 型 | 説明 |
|---|---|---|
add(curve) | メソッド | 任意の Curve をパスに追加します |
lineTo(x, y) | メソッド | 現在の終点から Line を追加します |
splineTo(points) | メソッド | 現在の終点から Spline を追加します |
cubicBezierTo(x, y, cp1X, cp1Y, cp2X, cp2Y) | メソッド | 現在の終点から CubicBezier を追加します |
quadraticBezierTo(x, y, cpX, cpY) | メソッド | 現在の終点から QuadraticBezier を追加します |
ellipseTo(xR, yR, start, end, cw, rot) | メソッド | 現在の終点から Ellipse 弧を追加します |
circleTo(radius, clockwise, rotation) | メソッド | 等しい半径での ellipseTo のショートカット |
moveTo(x, y) | メソッド | 描画せずに終点を移動します(ギャップを作成します) |
closePath() | メソッド | まだ閉じていない場合、終点から始点へ Line を追加します |
getPoint(t, out) | メソッド | パス全体上の正規化された位置(0-1)の点 |
getPoints(divisions, stepRate) | メソッド | 点の配列。divisions はカーブごと |
getSpacedPoints(divisions) | メソッド | パス全体に沿った等間隔の点 |
getRandomPoint(out) | メソッド | パス上の任意のランダムな点 |
getStartPoint(out) | メソッド | パスの始点 |
getEndPoint(out) | メソッド | パスの終点 |
getTangent(t, out) | メソッド | 位置 t における単位接線ベクトル |
getCurveAt(t) | メソッド | 正規化された位置 t の Curve を返します |
getLength() | メソッド | ピクセル単位のパス全体の長さ |
getCurveLengths() | メソッド | 累積カーブ長の配列 |
getBounds(out, accuracy) | メソッド | 境界 Rectangle |
draw(graphics, pointsTotal) | メソッド | すべてのカーブを Graphics オブジェクトに描画します |
toJSON() / fromJSON(data) | メソッド | シリアライズ |
updateArcLengths() | メソッド | キャッシュされた長さの再計算を強制します |
destroy() | メソッド | 内部参照をクリアします |
基本カーブ (Phaser.Curves.Curve)
| API | 型 | 説明 |
|---|---|---|
getPoint(t, out) | メソッド | パラメータ t (0-1) の点 -- 抽象メソッド、各サブクラスが実装 |
getPointAt(u, out) | メソッド | 弧長位置 u (0-1) の点 -- 均等間隔 |
getPoints(divisions, stepRate, out) | メソッド | 点の配列 |
getSpacedPoints(divisions, stepRate, out) | メソッド | 弧長による等距離の点 |
getDistancePoints(distance) | メソッド | ピクセル距離で間隔を空けた点 |
getLength() | メソッド | カーブの総弧長 |
getTangent(t, out) / getTangentAt(u, out) | メソッド | 単位接線ベクトル |
getTFromDistance(distance) | メソッド | ピクセル距離を t 値に変換 |
draw(graphics, pointsTotal) | メソッド | Graphics に描画 (デフォルト 32 点) |
getBounds(out, accuracy) | メソッド | 境界矩形 |
active | boolean | false の場合、親 Path はこのカーブをスキップします |
defaultDivisions | number | 単体カーブの場合のデフォルトは 5 |
arcLengthDivisions | number | 弧長計算の精度 (デフォルト 100) |
PathFollower コンポーネント
| API | 型 | 説明 |
|---|---|---|
setPath(path, config) | メソッド | 新しい Path を設定 (オプションで自動開始) |
startFollow(config, startAt) | メソッド | 追従を開始; config = duration の数値または PathConfig |
pauseFollow() | メソッド | 移動を一時停止 |
resumeFollow() | メソッド | 一時停止した移動を再開 |
stopFollow() | メソッド | 追従を停止 |
isFollowing() | メソッド | パス上を実際に移動中の場合 true を返します |
setRotateToPath(value, offset) | メソッド | オフセット付きの自動回転を有効/無効化 |
path | Path | 現在のパス参照 |
pathTween | Tween | 移動を駆動する内部トゥイーン |
pathOffset | Vector2 | パス座標からのオフセット |
pathVector | Vector2 | パス上の現在位置 |
pathDelta | Vector2 | 前回の更新以降の移動差分 |
rotateToPath | boolean | パスの方向へ自動回転 |
pathRotationOffset | number | 度数での回転オフセット |
PathConfig (Phaser.Types.GameObjects.PathFollower.PathConfig)
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
duration | number | 1000 | パスを移動する時間 (ミリ秒) |
from | number | 0 | パス上の開始位置 (0-1) |
to | number | 1 | パス上の終了位置 (0-1) |
positionOnPath | boolean | false | 開始時に追従オブジェクトをパス開始位置にスナップ |
rotateToPath | boolean | false | パスの方向を向くよう自動回転 |
rotationOffset | number | 0 | 自動回転に加算される度数 |
startAt | number | 0 | パス上の初期シーク位置 (0-1) |
この config はすべての標準的な Tween プロパティも受け付けます: ease、repeat、yoyo、delay、hold、onComplete など。
注意点
-
曲線における
getPoint(t)とgetPointAt(u)の違い。getPointは生の曲線パラメータ t を使用するため、ほとんどの曲線タイプで均等に配置された点を生成しません。getPointAtは弧長を介してマッピングし、均等に配置します。Path では、getPointはすでにパス全体の弧長を考慮しています。 -
Path の
moveToは非アクティブな曲線を作成します。MoveTo疑似曲線はactive: falseで長さがゼロです。次の曲線のために終点を再配置するだけです。何も描画せず、getPoints()およびdraw()ではスキップされます。 -
PathFollower は内部的に Tween を使用します。
startFollowの設定はscene.tweens.addCounter()に渡されます。すべての Tween プロパティ(ease、delay、repeat、yoyo、コールバック)が機能します。Tween は自動的にpersist: trueに設定されます。 -
PathFollower のオフセットの挙動。
positionOnPath: false(デフォルト)の場合、フォロワーの現在位置がパス開始点からのオフセットになります。positionOnPath: trueの場合、フォロワーはパスの開始点にスナップし、オフセットはゼロになります。 -
Ellipse の角度は度数法です。 コンストラクタおよび
startAngle/endAngleプロパティは度数法を受け付けます。内部的にはラジアンとして保存されます。rotationプロパティはラジアンですが、angleは度数法です。 -
closePathとautoCloseの違い。closePath()は終点から始点への明示的な Line 曲線を追加します。autoClose = trueはgetPoints()およびgetSpacedPoints()の出力に最初の点を追加するだけで、曲線は追加しません。 -
キャッシュされた長さは古くなる可能性があります。
getCurveLengths()は配列の長さのみに基づいて結果をキャッシュします。曲線の制御点を変更した場合は、path.updateArcLengths()を呼び出して再計算を強制してください。 -
数値を使った
cubicBezierToのパラメータ順序。 数値を渡す場合:cubicBezierTo(endX, endY, cp1X, cp1Y, cp2X, cp2Y)。制御点ではなく終点が最初に来ます。Vector2 オブジェクトを渡す場合:cubicBezierTo(cp1, cp2, endPoint)。 -
Spline には少なくとも 4 つの点が必要です。 Spline で使用される Catmull-Rom 補間は 4 つ以上の点で最もうまく機能します。点が少ないと、曲線が期待どおりに動作しない可能性があります。
-
Line 曲線の
arcLengthDivisionsは 1 です。 他の曲線(デフォルト 100)とは異なり、Line は線が本質的に均一であるためこれを 1 に上書きしています。調整する必要はありません。
ソースファイルマップ
| ファイル | 目的 |
|---|---|
src/curves/path/Path.js | Path クラス -- 複数の曲線を組み合わせ、ファクトリは this.add.path として登録 |
src/curves/path/MoveTo.js | パスに隙間を作るための MoveTo 疑似曲線 |
src/curves/Curve.js | 基底 Curve クラス -- すべての曲線タイプで共有されるメソッド |
src/curves/LineCurve.js | Line 曲線(2 点間のセグメント) |
src/curves/SplineCurve.js | Spline 曲線(複数の点を通る Catmull-Rom) |
src/curves/CubicBezierCurve.js | 三次ベジェ曲線(4 つの制御点) |
src/curves/QuadraticBezierCurve.js | 二次ベジェ曲線(3 つの制御点) |
src/curves/EllipseCurve.js | 角度と回転をサポートする楕円/円弧曲線 |
src/gameobjects/pathfollower/PathFollower.js | PathFollower ゲームオブジェクト(Sprite + PathFollower ミックスインを継承) |
src/gameobjects/pathfollower/PathFollowerFactory.js | this.add.follower ファクトリ登録 |
src/gameobjects/components/PathFollower.js | PathFollower コンポーネントミックスイン(setPath、startFollow、pathUpdate など) |
src/gameobjects/pathfollower/typedefs/PathConfig.js | PathConfig typedef |