1

誰かがこれを手伝ってくれるかどうかはわかりませんが、ここに行きます. 私は現在、RequireJS を使用するためにCraftyJS (優れたコンポーネント ベースのゲーム エンジン) で書いているゲームをリファクタリングしています。すべて順調に進んでいるのに、突然、問題が発生しました。モジュールを作成しました。このモジュールでは、基本的にイベント リスニングのボトルネックにすぎない小さな Crafty コンポーネントを定義します。コールバックの 1 つで、ローカル モジュールで定義されているいくつかの関数を呼び出します。私はこのパターンを RequireJS で多くのコンテキストで使用してきましたが、常にうまく機能しています。何らかの理由で、この場合、一部の関数が未定義です。それらのすべてではありません。ほんの少し。ここにいくつかのコードがあります:

コンポーネント:

Crafty.c("TurnStateMachineObserver", {
    startListening: function() {
...
        this.bind(POST+PHASE_CHANGE, function(e) {
            // this is called after the phase change has already been 
            // applied. now, switch to the next phase, if appropriate.

            var curPhase = currentPhase();
            var nextPhase = nextPhase();

            if (nextPhase === PHASE_TURN_START)
                _triggerPlayerChange(nextPlayer());
            else if (curPhase !== PHASE_MAIN)
                _triggerPhaseChange(nextPhase());
        })
        .bind(POST+RESET, function(e) {
            reset();
        });
    },
...
});

Crafty に慣れていない方のために説明すると、Crafty.c後でインスタンス化できるコンポーネントが作成されます。2 番目の引数として渡されたオブジェクト リテラルはTurnStateMachineObserver、コンポーネントの 1 つとしてインクルードされている (つまり を使用している) オブジェクトに追加 (拡張?) されますCrafty.e("TurnStateMachineObserver")

コンポーネント内で使用される関数は、後で同じファイルで定義されます (ファイル全体がdefine()呼び出しでラップされます)。

//  Function: currentPhase
//      The current <Turn Phase>.
function currentPhase() {
    if (_currentPhaseIndex < 0) _currentPhaseIndex = 0;
    return PHASES[_currentPhaseIndex];
}

//  Function: nextPhase
//      The phase following the <currentPhase>. Order follows the 
//      <PHASES> list.
function nextPhase() {
    var phaseIndex = _currentPhaseIndex + 1;
    phaseIndex %= PHASES.length;

    return PHASES[phaseIndex];
}

これで、POST+PHASE_CHANGEイベントが発生すると、 への呼び出しで例外がスローされますが、 !nextPhase()への呼び出しではスローされません。currentPhase()いくつかのデバッグの後、実際、モジュールで定義されたすべての関数は、define()本体が最初に入力されたときに適切に定義されていますが、それらのほとんどはコンポーネントのコールバック内で未定義であることがわかりました。実際、コンポーネントがこのようにインスタンス化されると、

if (!_observer)
    _observer = Crafty.e("TurnStateMachineObserver");
_observer.startListening();

init関数 (モジュールが返す) では、nextPhase()が定義されていますが、 にステップインする_observer.startListening()と、そうではありませんcurrentPhase()。ああ!この上に残っている髪を引っ張っています。私を本当に混乱させたのは、これらの関数が兄弟であるということです。より高いスコープの関数を定義し、他の関数を定義しない方法はありますか?!

4

1 に答える 1

1

Wow, stupid. The problem, obviously, was that I was overwriting the function with the variable. When I change it to

...
var curPhaseVal = currentPhase();
var nextPhaseVal = nextPhase();
...

suddenly everything works. That should have been a no-brainer, but it still took me a week to find. Oh well, back to work!

于 2013-06-14T17:30:10.077 に答える