3. プレイヤーの移動
はじめに
プレイヤーの移動を実装しました。 キー入力で上下左右と斜めにも移動できるようにして、ついでにSHIFTキーで走るようにしました。
停止アニメーションの作成
前回、Phaser Editorで walk-down,walk-up,walk-left,walk-rightというアニメーションを作成しました。
停止時に足を上げたポーズで止まってしまうことを避けるため、新たに停止時のポーズを1フレームのアニメーションとして作成し、stop-down,stop-up,stop-left,stop-rightという名前で保存しました。
アニメーションといっても1フレームなので動きはありません。将来的に、停止時はあくびをするなどのアニメーションを設定することもできます。
コード
キー入力の取得
input.keyboard.createCursorKeysでキー入力を取得します。
export default class StartScene extends Phaser.Scene {
// ...
private cursors!: Phaser.Types.Input.Keyboard.CursorKeys;
// ...
create() {
this.cursors = this.input.keyboard!.createCursorKeys();
// ...
}
}キー入力をベクトルに変換
キーの押下状態から、[vx,vy]という長さspeedのベクトルに変換します。
斜め移動のときは速くなりすぎないように正規化(normalize)をしておきます。
// キー入力から移動速度を取得する関数
function getVelocity(
cursors: Phaser.Types.Input.Keyboard.CursorKeys,
speed: number
): [number, number] {
let vx = 0;
let vy = 0;
if (cursors.shift?.isDown) speed *= 2; // Shiftキーで速くなる
if (cursors.left?.isDown) vx = -speed;
if (cursors.right?.isDown) vx = speed;
if (cursors.up?.isDown) vy = -speed;
if (cursors.down?.isDown) vy = speed;
// 斜め移動時の速さ補正(√2で速くなりすぎないように)
if (vx !== 0 && vy !== 0) {
const vec = new Phaser.Math.Vector2(vx, vy).normalize().scale(speed);
vx = vec.x;
vy = vec.y;
}
return [vx, vy];
}ベクトルからプレイヤーの向きを取得
アニメーションのkeyを指定するために、プレイヤーの向きを文字列で取得します。
type Direction = "up" | "down" | "left" | "right";
// プレイヤーの移動方向を取得する関数
function getDirection(vx: number, vy: number): Direction | "stop" {
if (vx === 0 && vy === 0) {
return "stop";
}
if (Math.abs(vy) > Math.abs(vx)) {
// 縦方向優先
return vy < 0 ? "up" : "down";
} else {
// 横方向優先
return vx < 0 ? "left" : "right";
}
}スプライトの移動とアニメーションの設定
シーンのコードが多くなってきたので、Playerクラスとして切り出しました。
やっていることは、PlayerのspriteのsetVelocityとanims.playを呼ぶだけです。
アニメーションのkeyには、上下左右に動いている時はwalk-*を、止まっている時はlastDirectionを使ってstop-*を指定します。
export default class Player {
update(cursors: Phaser.Types.Input.Keyboard.CursorKeys): void {
// キー入力でそれぞれX/Y軸の速度を設定
const [vx, vy] = getVelocity(cursors, this.playerSpeed);
this.sprite.setVelocity(vx, vy);
// アニメーション切り替え & lastDirection 更新
const direction = getDirection(vx, vy);
if (direction != "stop") {
this.sprite.anims.play(`walk-${direction}`, true);
this.lastDirection = direction;
} else {
this.sprite.anims.play(`stop-${this.lastDirection}`, true);
}
// ...
}まとめ
以下を実装しました。
- プレイヤーが8方向に歩く
- SHIFTキーで走る(倍速)
- 停止する(停止ポーズ)
- デバッグ情報の表示
だんだんソースコードが増えてきました。コードの公開方法を考えたほうがいいかもしれません。
