エンティティ コンポーネント スタイルのデザイン パターンに従ってゲームを作成していて、解決できた問題に遭遇しましたが、それがベスト プラクティスであるかどうか (またはそのようなものがあるかどうか) はわかりません。
ゲームの主要な状態 (メニュー、レベル内、一時停止、バックグラウンド) を処理するステート マシンと、より断片的なゲーム状態 (新しいレベル、レベル オーバー、次へ) を処理するゲームプレイ コンポーネントの 1 つの内部ステート マシンがあります。レベル、ゲーム オーバー、概要)。内側のコンポーネントからゲームが終了したことを外側のステート マシンに知らせたいのですが、メイン コントローラー クラスへの参照がありません。通常、私はプロトコルを使用して情報をチェーンに委任しますが、ECS の経験が限られている私には、これはパラダイムを壊すように思えます。私がやっていることは、ウィンドウのルート ビュー コントローラーのアプリ デリゲートにクエリを実行し、内部状態に応じて便利なメソッドを呼び出すことです...これは MVC を行うには恐ろしい方法ですが、ECS では問題ないようです。
これが私が思っているほどひどいものではないことを誰かが確認できますか、またはそうである場合は、新しいパラダイムを推奨できますか? それは大歓迎です。
基本的には次のように動作します (全体を投稿するにはコードが多すぎると思います):
MainMenuViewController には、ステート マシンを含む ApplicationLifecycleComponent を持つ ApplicationEntity があります。「ゲーム開始」ボタンを押すと、ステート マシンは ApplicationGameState に渡されます。
ApplicationGameState は、MainMenu VC (ルート) への弱い参照を使用して、SpriteKit シーンをロードする GameViewController を提示します。ゲーム ロジックは、最終的に「ゲーム オーバー」を報告する一連の内部コンポーネントとステート マシンを通じて発生します。
ゲーム オーバーで、ApplicationLifecycle のステート マシンは ApplicationGameState を終了し、MainMenuState (または必要に応じて他の状態) に入る必要がありますが、シーンからルート VC に到達できないため、AppDelegate にルート VC を要求し、キャストします。 MainMenuViewController として、そのエンティティを取得し、ライフサイクル コンポーネントに状態を変更するように指示します。
if let applicationController = UIApplication.sharedApplication().keyWindow?.rootViewController as? MainMenuViewController {
applicationController.applicationEntity.applicationLifecycleComponent.enterMenuState()
}
質問を言い換えると、ルート ビュー コントローラーの弱い参照をアプリケーションの開始からチェーンにプッシュして、この状態にする必要がありますか? 何かが起こったことをより高いレベルのエンティティに通知するためのベスト プラクティスはありますか?
参考までに、これは ECS への初めての進出です。