アクションRPG Day5 衝突

f:id:naosim:20181010064547p:plain 前回はアニメーションをやりました

naosim.hatenablog.jp

今回は壁との衝突です
Phaserの衝突は優秀で、プレイヤと壁それぞれに衝突する領域を定義したら後は勝手に計算してくれます

プレイヤーの衝突定義

プレイヤークラスのcreateメソッドをいじります
何も設定しないと判定領域はspriteのサイズ通り32x32になりますが、それだとちょっと大きいのでもう少し小さい領域にします

class Player {
  ...
  create() {
    this.sprite = this.scene.physics.add.sprite(32, 32, 'player');
    this.sprite.body.setSize(16, 24);
    this.sprite.body.offset.y = 8;
    this.sprite.setCollideWorldBounds(true);
  }
  ...
}

sprite.bodyとは物理演算に使うオブジェクトです sprite.bodyは物理演算にarcadeを使っているのでPhaser.Physics.Arcade. Bodyです

Phaser 3 API Documentation - Class: Body

this.sprite.body.setSize(16, 24);

ここで衝突の領域サイズを指定します
領域は中央寄せになります
今回は足が地についたところきっちり判定したいので、足から領域が始まるようにoffsetを指定します

this.sprite.body.offset.y = 8;

Groundの衝突定義

背景はtiledmapで作っていますが、mapの絵に衝突判定して欲しい部分と無視して欲しい部分があるのでそれを指定します Groundクラスのcreateをいじります

Ground {
  create() {
    const map = this.scene.make.tilemap({ data: this.level, tileWidth: 16, tileHeight: 16 });
    this.layer = map.createStaticLayer(0, map.addTilesetImage("ground"), 0, 0);
    this.layer.setCollisionBetween(6, 44);// 追加
  }
}

Phaser 3 API Documentation - Class: StaticTilemapLayer ポイントはsetCollisionBetween(6, 44)
衝突判定するインデックスを範囲指定します
指定の仕方は他にもあるのでいろいろやってみたら良さそう
実は今回はsetCollisionByExclusionの方が正しい気がしてきたし

プレイヤーとGroundの衝突判定をする

createメソッドに1行書くだけです

this.physics.add.collider(player.sprite, ground.layer);

衝突判定はこれで終わり
すげぇ...

以上

jsdo.it

プレイヤーが壁に当たるとちゃんと止まります
ゲームらしくなってきたな