0

XNA ゲームの状態マネージャーとしてスイッチを使用しています。スイッチはメインの更新メソッドの一部であるため、フレームごとに実行されます。タイマー値を設定する必要がある場合がありますが、メソッド呼び出しごとに 1 回だけ設定する必要があります。ケースごとにタイマーを設定する方法は複数あるため、現在および以前の状態番号を使用して、以前の時間を上書きしてもよいかどうかを確認することはできません。

case "state 34": {
SetTime(theTime); // should run only once
// other things
if (TheTimeisRight(time)) // runs every call
    {
        SetTime(theTime); // should run only once
        if (TheTimeisRight(time)) 
        { /*  some methods  */ }
    }
break; }

どうすればこれを機能させることができますか、またはスイッチの外に出ずにこれを行うためのより良い方法はありますか? (SetTime メソッドの変更は問題ありませんが、追加のコードでスイッチを混乱させたくありません)

4

4 に答える 4

1

別のメソッド:呼び出したいメソッドのラッパーを導入します。

    public sealed class RunOnceAction
    {
        private readonly Action F;
        private bool hasRun;

        public RunOnceAction(Action f)
        {
            F = f;
        }

        public void run()
        {
            if (hasRun) return;
            F();
            hasRun = true;
        }
    }

次にvar setTimeOnce = new RunOnceAction(() => SetTime(theTime));、switchステートメントの前に作成し、そこでをとして呼び出しますsetTimeOnce.run()。必要に応じてパラメータ/戻り値を調整します。

于 2012-10-19T05:26:56.047 に答える
0

呼び出しをループの外に置きます。
実行する必要があるかどうかを判断するために別の条件ステートメントが必要になる場合がありますが、フラグやその他のさまざまな臭いコードのアプローチを使用して呼び出しの繰り返しを制御するよりも、はるかに優れている必要があります。

編集:

これが、スイッチの外側の1つの場所に配置することの意味です。

if (someCondition && someOtherCondition && yetAnotherCondition)  
    setTime(theTime); // just one call, in one place, gets executed once

switch(someValue) 
{
    case "state 34": {
        //SetTime(theTime); // no longer necessary
        // other things
        if (TheTimeisRight(time)) // runs every call
        {
            //SetTime(theTime); // no longer necessary
            if (TheTimeisRight(time)) 
            { /*  some methods  */ }
        }
        break;

    ...etc...
}

アドバイス:文字列ではなく、スイッチ値に列挙型を使用してください。

残酷に正直に言うと、これは、より完全なコードサンプルを見なくても、誰もが現実的にこれを手伝うことができるのとほぼ同じです(あなたが私たちに提供したサンプルは、いくらか工夫されており、あなたが持っているものに対して完全に正確ではないと思いますか?)。この問題を回避する最善の方法は、switchステートメントを分解してやり直すことです。これは、ステートマシンを維持することがこの状況を処理する最善の方法ではないか、他の状態を導入する必要があるためです。

于 2012-10-19T05:21:16.607 に答える
0

ブール変数alaをいじりたくない場合はhasSetTimeAlready、いつでもメソッドを呼び出す別の状態を導入してから、元の状態に進むことができます。

于 2012-10-19T05:22:55.423 に答える
0

HashSet<int>を使用して、現在のSetTime(time, num)メソッドが以前に呼び出されていないかどうかを確認することに頼りましたif (!hashSet.Contains(num))

void SetTime(int time, int num)
{
    if (!hashSet.Contains(num))
        {
            theTime = time;
            hashSet.Add(num);
        }
}

確かにあまりクールに見えませんが、機能し、メソッド呼び出しを (視覚的に) あまり損なうことがないため、スイッチの可読性は保たれます。

于 2012-10-19T15:49:42.907 に答える