12. フローチャート

はじめに

システム、コンポーネント、イベントが増えてきて、自分でも把握が難しくなってきました。

Mermaid記法でフローチャートを書いて整理してみます。

プレイヤー

プレイヤー生成

flowchart TD
  subgraph GameScene.create
    CallCreatePlayer[createPlayerを呼び出し]
  end

  CallCreatePlayer --> createPlayer

  subgraph createPlayer
    Entity追加 -->
    Component追加 -->
    emitPlayerCreated[PlayerCreatedイベント発火]
  end

  emitPlayerCreated -.-> handler

  subgraph handler[CollisionSystem.onPlayerCreated]
    マップとのコリジョン設定
  end

プレイヤー移動

flowchart TD
  subgraph playerInputSystem.update
    if{deadFlag} -->|false| inputからvelocity計算 -->
    sprite.setVelocity
  end

  subgraph RenderSystem.update
    A["sprite.velocityからdirection or stopを取得"] -->
    isStop{stop}
    isStop --> |true| lastDirectionの停止アニメを設定
    isStop --> |false| directionの歩行アニメを設定 -->
    lastDirectionを更新
  end

ダメージ&死亡

flowchart TD
  subgraph CollisionSystem.onEnemyCreated
    subgraph onOverlap
      IF{isCooldown} -->|false| emitOnPlayerHit[onPlayerHitイベント発火]
    end
  end

  emitOnPlayerHit -.-> HealthSystem.onPlayerHit
  emitOnPlayerHit -.-> CooldownSystem.onPlayerHit

  subgraph HealthSystem.onPlayerHit
    ダメージ計算&更新 -->
    emitDamage[Damageイベント発火] -->
    if{HP<=0} -->
    |true| emitPlayerDied[PlayerDiedイベント発火] -->
    DeadFlag[DeadFlagをtrueに設定]
  end

  subgraph CooldownSystem.onPlayerHit
    cooldownスタート
  end

  emitDamage -.-> DESHandler
  emitDamage -.-> UISHandler

  subgraph DESHandler[DamageEffectSystem.onDamage]
    ダメージ演出
  end

  subgraph UISHandler[UIScene.onDamage]
    HPバーを更新
  end

  emitPlayerDied -.-> DSHandler

  subgraph DSHandler[DeathSystem.onPlayerDied]
    UISceneを停止 -->
    プレイヤーの死亡演出開始 -->
    |演出が終了| GameOverSceneに移動
  end

  DeadFlag -.-> WeaponSystemで発射を止める
  DeadFlag -.-> PlayerInputSystemで入力を止める

敵生成

flowchart TD
    subgraph WaveSystem
      subgraph WSUpdate[update]
        Wave設定の読み込み -->
        spawnTimer処理 --> if1{次のspawn} --> |true| CallSpawn[spawnEnemyByPoolを呼び出し]
      end

      CallSpawn --> spawnEnemyByPool

      subgraph spawnEnemyByPool
        次の敵を取得 -->
        WSCall[createEnemy呼び出し]
      end
    end

    WSCall --> createEnemy

    subgraph createEnemy
      敵Entity生成 -->
      タイプ別のsprite追加 -->
      タイプ別のcomponents追加 -->
      emitEnemyCreated[EnemyCreatedイベント発火]
    end

    emitEnemyCreated -.-> CSHandler
    emitEnemyCreated -.-> UIHandler

    subgraph CSHandler[CollisionSystem.onEnemyCreated]
      CSH1[spriteにコリジョン設定]
      CSH1 --> onOverlap
      subgraph onOverlap
        inv{isCooldown} -->
        |false| emitPlayerHit[PlayerHitイベント発火]
      end
    end

    subgraph UIHandler[UIScene.onEnemyCreated<br>※未実装]
      敵カウント更新
    end

    emitPlayerHit -.-> HealthSystem.onPlayerHit
    emitPlayerHit -.-> CooldownSystem.onPlayerHit

敵移動

  • createEnemy で敵タイプごとに MovementStrategyComponent を設定して追加している
flowchart TD
  subgraph EnemyAISystem
    subgraph update
      A{{すべての敵についてループ}} -->
      Call[movementStrategyに応じてupdateXXXMovement呼び出し]
    end

    Call -.-> updateXXXMovement

    subgraph updateXXXMovement
      direction TB
      velocity計算 -->
      movmentStrategy.state更新 -->
      sprite.setVelocity
    end
  end

敵ダメージ&死亡

flowchart TD
  subgraph HealthSystem.onEnemyHit
    ダメージ計算&更新 -->
    emitDamage[Damageイベント発火] -->
    if{HP<=0} -->
    |true| emitEnemyDied[EnemyDiedイベント発火]
  end

  emitEnemyDied -.-> DTS

  subgraph DTS[DeathSystem.onEnemyDied]
    敵の死亡演出 -->
    destroyEntity
  end

  emitDamage -.-> DES

  subgraph DES[DamageEffectSystem.onDamage]
    ダメージ演出
  end

武器と弾

武器生成

flowchart TD
  subgraph createPlayer
    初期武器の設定 -->
    CPCall[createWeapon呼び出し]
  end

  CPCall --> createWeapon

  subgraph IS["ItemSystem ※未実装"]
    if{武器を取得} --> |yes| ISCall[createWeapon呼び出し]
  end

  ISCall --> createWeapon

  subgraph createWeapon
    武器Entity生成 -->
    タイプ別のcomponents追加
  end

弾生成

flowchart TD
  subgraph WeaponSystem.update
    A{{すべての武器についてループ}} -->
    IF{武器.isCooldown} --> |false| Call[createXXXProjectiles呼び出し]
  end

  Call --> createXXXProjectiles

  subgraph createXXXProjectiles
    createEntity -->
    sprite追加 -->
    components追加 -->
    emit[ProjectileCreatedイベント発火]
  end

  emit -.-> CSHandler

  subgraph CSHandler[CollisionSystem.onProjectileCreated]
    spriteにコリジョン設定 --> onOverwrap
    subgraph onOverwrap
      IF2{弾.isCooldown} -->
      |false| emitEnemyHit[EnemyHitイベント発火]
    end
  end

  emitEnemyHit -.-> ProjectileSystem.onEnemyHit
  emitEnemyHit -.-> HealthSystem.onEnemyHit
  emitEnemyHit -.-> CooldownSystem.onEnemyHit

弾の消滅

flowchart TD
  subgraph ProjectileSystem
    subgraph PSUpdate[update]
      direction TB
      if{lifespan<=0<br>or<br>pierce<=0} --> |true| Entry削除
    end
    subgraph onEnemyHit
      pierce減らす
    end
  end

  subgraph LifespanSystem
    subgraph LSUpdate[update]
      lifespan更新
    end
  end

まとめ

かなりややこしくなってきましたが、これでやっと整理できました。