0

Flex/Actionscript を使用したことがないので、明らかなことを尋ねている場合は申し訳ありませんが、この投稿を書く前に 3 日間 (Google とスタックオーバーフローの検索を含む) 作業を行っています。

Mini-IoC ベースの MVC フレームワークで作成された Flex 4 で作成されたゲームを変更するよう依頼されました。私が作成を依頼された 2 つの MOD は、ゲーム オーバー画面です。これは、最終的なスコアを表示し、導入画面に難易度の選択を表示します。ゲームオーバー画面を作成し、ゲームタイマーが切れたときにコントローラーを表示させることに成功しました。

今のところ、ゲームの構造は次のようになります。

Intro View -> Game View -> Game Over View

    ^                            |
    |__________ (retry?) ________|

最初の問題は、スコアを mainGame ActionScript ファイルからゲーム オーバー画面に渡すことです。

私が試したこと:

  • gameOverViewBase に mainGame をインポートし、gameOverView mxml ファイルで mainGame.score 変数を呼び出します。

-編集!!!= 上記の方法は、mainGame のスコア変数を定数に変更すると機能しますが、変数のままだと、コントローラーは gameOverView をロードせず、ゲームは空の mainGame ビューに置かれます。

  • ゲーム中にプレーヤーが得点するたびに、gameOverViewBase の新しいスコア変数に追加する関数を作成します。
  • MainGame の終了時にスコアをパラメーターとして GameOverView に渡す

controller.loadGameOver(score);

これが最も論理的な方法のように思えました。そのため、メインのゲーム アクション スクリプト ファイルに到達するまで、パラメーターとして整数を取るように loadGameOver を設定して、ゲームの他のコンポーネントを通じて関数をたどりました。

public function loadGameOver(score:int) : void
    {
        loadView(GameOverView);
    }

loadView 関数 (以下に示す) は、'score' パラメーターを渡す場所がわからないため、行き詰まる場所です。次のようになります。

private function loadView(viewClass:Class, modelClass:Class = null) : void
    {

        var view:View = new viewClass();
        if(!view) throw new Error("Could not load view");

        viewContainer.removeAllElements();
        viewContainer.addElement(view);         

        view.controller = this;

    }

2つ目の問題は、導入画面での難易度選択。mxml ファイルの 3 つのボタン (イージー、ノーマル、ハード) と、ActionScript のすべてのボタンでこれを行いました。

protected function onEasyButtonClick() : void
    {
        set = "easy"
        controller.loadMainGame(set);
    }

繰り返しますが、上記の loadView 関数に行き着きます。

要約すると、ビューとモデルの間でデータを渡す方法を知る必要があります。それが理想的な方法ではない場合、私はあなたがより良いと思う他の方法を受け入れます.

ありがとう!

ベン

PS私は助けたい人に私のソースコードを送ることができます:)

4

1 に答える 1

2

どの MVC フレームワークを使用しているかは指定しません。ただし、スコアは間違いなくモデルのプロパティである必要があり、モデル データは、おそらくバインド (weltraumpirat に感謝) を介して、または何らかの中間クラスを介して、ビューから直接アクセスできる必要があります。

既存のビュー クラスのいくつかを見て、モデル データがどのように供給されているかを把握することをお勧めします。このアプローチを使用して、ビューに必要なデータを取得できます。

[編集]:

mainGameインスタンスでプロパティが設定されていないため、バインディングまたはトレースを介してそのプロパティにGameOverViewアクセスできません。scoreコントローラー クラスのメソッドは、 newで使用される新しいインスタンスを構築するために使用するクラス参照をloadView受け入れます。残念ながら、これは、インスタンスが作成された(および現在のスコアを含む) 必要があるため、役に立ちません。ModelModelViewGameOverViewMainGameMainGameView

以下が使用しているフレームワークの哲学に当てはまるかどうかはわかりません。ただし、クラス参照ではなくloadViewのインスタンスを受け入れるようにメソッドを変更し、コントローラーがインスタンス化されたときに のインスタンスへの参照を作成してキャッシュします。そうすれば、作成時にとの両方に同じ参照を渡すことができます。ModelMainGameModelMainGameViewGameOverView

    public class WhackAMoleBase extends Application implements IGameController
    {
        public var viewContainer:Group;
        private var mainGame:MainGame

        public function WhackAMoleBase() : void
        {
            super();

            // Create and cache an instance of the main game Model
            mainGame = new MainGame();

            addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
        }

        public function loadIntroduction() : void
        {
            loadView(IntroductionView);
        }

        public function loadMainGame() : void
        {
            loadView(MainGameView, mainGame);
        }

        public function loadGameOver() : void
        {
            // Use the same instance of MainGame which the MainGameView 
            // has been using as the Model for the GameOverView
            loadView(GameOverView, mainGame);
        }

        // Accept a Model instance rather than a class Reference
        private function loadView(viewClass:Class, model:Model = null) : void
        {
            //Create a new instance of the supplied view
            var view:View = new viewClass();
            if(!view) throw new Error("Could not load view");

            //Clear any previous views in the container and add
            viewContainer.removeAllElements();
            viewContainer.addElement(view);

            //Property based dependency injection 
            view.controller = this;

            //There may or may not be a model required for the
            //requested view; check and instantiate appropriately
            if(model)
            {               
                //Give model reference to the controller
                //and link the view up to the model
                model.controller = this;
                view.model = model;
            }
        }

        private function onCreationComplete(event:FlexEvent) : void
        {
            //When the application is first created, we want to show the introductory view 
            loadView(IntroductionView);
        }

    }
于 2012-07-07T00:42:20.583 に答える