10. 複数の武器を持つ

はじめに

現在、プレイヤーは手裏剣を持っていますが、武器の種類を増やして、同時に複数の武器で攻撃できるようにします。

まずは雷魔法を追加してみます。手裏剣はプレイヤー前方に投げますが、雷魔法はプレイヤー周囲に3つの雷を落とすことにします。

今までは武器が1種類だけだったので、Playerが弾(Projectile)を生成していましたが、 武器の種類が増えるとこの方法では困難です。

整理

武器(Weapon)と弾(Projectile)について。

  • 武器(Weapon)
    • プレイヤーが保持しています
    • Cooldownを持ち、定期的に弾(Projectile)を生成します
    • スプライトを持ちません(将来的には表示するかも)
    • 武器1種類につきゲーム中に1個だけ登場します
  • 弾(Projectile)
    • 武器から発射されます
    • スプライトを持ちます
    • ゲーム中に大量に存在します

方針

  • プレイヤーが武器を取得したときには、武器Entityを生成する
  • 武器Systemにて、武器Entityごとに弾の発射処理を行う

という設計にしました。

また、武器Entityは以下のコンポーネントを持ちます。

  • WeaponTag … 武器Entityであることのタグ
  • CooldownComponent … 武器ごとにクールダウン
  • ShurikenComponent / ThunderComponent … 各武器に固有の情報

実装

武器Entityの生成

// 手裏剣(武器)を生成
export function createShurikenWeapon() {
  const entity = EntityManager.createEntity();
  ComponentManager.set("weaponTag", entity, {});
  ComponentManager.set("shuriken", entity, { scale: 1, damage: 10, speed: 300, pierce: 2 });
  ComponentManager.set("cooldown", entity, { cooldown: 1500, cooldownTimer: 1500 });
  return entity;
}

// 雷(武器)を生成
export function createThunderWeapon() {
  const entity = EntityManager.createEntity();
  ComponentManager.set("weaponTag", entity, {});
  ComponentManager.set("thunder", entity, { scale: 1, damage: 10, count: 3, lifespan: 500 });
  ComponentManager.set("cooldown", entity, { cooldown: 2000, cooldownTimer: 2000 });
  return entity;
}

武器System

  update(delta: number) {
    // 武器ごとに弾を発射
    const weaponEntities = ComponentManager.entries("weaponTag");
    for (const [weaponEntity] of weaponEntities) {
      const cooldown = ComponentManager.get("cooldown", weaponEntity);
      cooldown.cooldownTimer -= delta;
      if (cooldown.cooldownTimer <= 0) {
        // 武器の種類によって処理を分ける
        if (ComponentManager.has("shuriken", weaponEntity)) {
          createShurikenProjectiles(this.scene, weaponEntity); // 手裏剣(弾)Entityの生成
        } else if (ComponentManager.has("thunder", weaponEntity)) {
          createThunderProjectiles(this.scene, weaponEntity); // 雷(弾)Entityの生成
        }
        cooldown.cooldownTimer = cooldown.cooldown; // クールダウンリセット
      }
    }
  }

まとめ

複数の武器で攻撃できるようになりました。

注意:この記事の前に、コンポーネントやシステムなど大幅に整理して、コード修正しています。
体力バーや経過時間などUIも変更しました。 画像ではわかりませんが、GameOver等の演出も増えています。