アクションRPG Day4 アニメーション
前回はプレイヤーを表示しました
ただ動かした時にアニメーションがなかったので今回はそれを追加します
アニメーションを追加ためにクマが「右方向に歩く絵」と「左方向に歩く絵」が必要なので、プレイヤーの画像を変更しました
preloadで読み込む画像の変更
プレイヤーの画像を変更します
this.load.spritesheet('player', 'http://jsrun.it/assets/W/0/B/U/W0BU0.png', { frameWidth: 32, frameHeight: 32 });
Player.create()でアニメーションを定義する
class Player { ... create() { this.sprite = this.scene.physics.add.sprite(32, 32, 'player'); // ここにアニメーションの設定を追加する } ... }
上記のコメントの部分に下記の4つのアニメーションを追加します
- 右向きに立ってる絵
- 左向きに立ってる絵
- 右向きに歩いている絵
- 左向きに歩いている絵
右向きに立ってる絵
this.scene.anims.create({ key: 'turn-right', frames: [ { key: 'player', frame: 4 } ], frameRate: 20 });
this.scene.anims.create
のドキュメントはこれ
Phaser 3 API Documentation - Class: AnimationManager
引数: AnimationConfig
keyには適当な名前をつける
frameに渡す整数は画像をframeWidthとframeHeightで分割した状態で左上から数えた数
今回の画像の場合、右向きの絵は左から5番目で数値はゼロオリジンなので4を指定する
左向きに立ってる絵
考え方は右向きと同じ
this.scene.anims.create({ key: 'turn-left', frames: [ { key: 'player', frame: 3 } ], frameRate: 20 });
右向きに歩いている絵
this.scene.anims.create({ key: 'right', frames:this.scene.anims.generateFrameNumbers('player', { frames:[ 5, 4, 6, 4] }), frameRate: 10, repeat: -1 });
framesの指定でgenerateFrameNumbers
を使う
generateFrameNumbers
frames
で指定した順番に絵をアニメーション表示してくれる
このメソッドが何を返してるのかが気になったので、戻り値をログ出力してみたらこんなオブジェクトを返してた
[ {key: "player", frame: 5}, {key: "player", frame: 4}, {key: "player", frame: 6}, {key: "player", frame: 4} ]
要するにただのファクトリメソッドみたいw
frames: [5, 4, 6, 4].map(v => ({key:'player', frame: v}))
これでええやん
まぁいいや
左向きに歩いている絵
ほぼ一緒
this.scene.anims.create({ key: 'left', frames:this.scene.anims.generateFrameNumbers('player', { frames:[2, 3, 1, 3] }), frameRate: 10, repeat: -1 });
createメソッドの最終形
class Player { ... create() { this.sprite = this.scene.physics.add.sprite(32, 32, 'player'); this.lastDirection = 'right'; this.scene.anims.create({ key: 'turn-right', frames: [ { key: 'player', frame: 4 } ], frameRate: 20 }); this.scene.anims.create({ key: 'turn-left', frames: [ { key: 'player', frame: 3 } ], frameRate: 20 }); this.scene.anims.create({ key: 'right', frames:this.scene.anims.generateFrameNumbers('player', { frames:[ 5, 4, 6, 4] }), frameRate: 10, repeat: -1 }); this.scene.anims.create({ key: 'left', frames:this.scene.anims.generateFrameNumbers('player', { frames:[ 2, 3, 1, 3] }), frameRate: 10, repeat: -1 }); } ... }
Player.update()でアニメーションを設定する
先ほど定義したアニメーションを動作に合わせて設定します
update () { if (this.cursors.left.isDown) { this.sprite.setVelocityX(-160); // 左向きに歩くアニメ this.sprite.anims.play('left', true); this.lastDirection = 'left'; } else if (this.cursors.right.isDown) { this.sprite.setVelocityX(160); // 左向きに歩くアニメ this.sprite.anims.play('right', true); this.lastDirection = 'right'; } else { this.sprite.setVelocityX(0); this.sprite.anims.play(this.lastDirection && this.lastDirection == 'left' ? 'turn-left' : 'turn-right'); } if (this.cursors.up.isDown) { this.sprite.setVelocityY(-160); } else if(this.cursors.down.isDown) { this.sprite.setVelocityY(160); } else { this.sprite.setVelocityY(0); } }
アニメーションを再生するplayメソッドの仕様はこれ
play(key [, ignoreIfPlaying] [, startFrame])
今の実装ではupdateが呼ばれるたびに毎回playメソッドをコールするので、playメソッドの第2引数のignoreIfPlaying
をtrueにしておきます
そうしないと例えば右ボタンを押してる時はupdateのたびに右・右・右...と実行されるので、画面上は右に歩くアニメの1フーレム目がずーっと表示されることになり、歩く感じになってくれません
ここらへんをフレームワークで吸収してくれるのは助かるなぁ
以上
プレイヤーが左右に歩くアニメーションができました
次回は壁の衝突判定をやります