1

私はゲーム用のステアリング動作のフォームを実装しました。エディターを使用するたびに、デザイナーは (現在) 7 つのパラメーターを 0、ランダム、または設定量のいずれにするかを選択できる必要があります。後者の 2 つは、ランダムがどの範囲に収まるか、または変数が取得する量を設定するかです。設定はファイルに保存され、いつでもロードできる必要があります。

私が最終的に得たのは、コンストラクターと、非常に多くのフィールドとプロパティを見るのが苦痛です。 特に後でパラメーターを追加するときに、この問題を解決するためのよりインテリジェントなアプローチを探しています。

public enum SteerType
{
    None,
    Random,
    Variable
}

public IdleSteering(SteerType rotationOnIntervalType, int rotationOnInterval, 
                    SteerType rotationOnCollisionType, int rotationOnCollision,
                    SteerType breakIntervalType, int breakInterval,  
                    SteerType breakTimeType, int breakTime, 
                    SteerType rotationOnBreakType, int rotationOnBreak, 
                    SteerType rangeFromSpawnType, int rangeFromSpawn, 
                    SteerType speedType, int speed)
    {
        _rotationOnIntervalType = rotationOnIntervalType;
        _rotationOnInterval = rotationOnInterval;

        _rotationOnCollisionType = rotationOnCollisionType;
        _rotationOnCollision = rotationOnCollision;

        <...> //And this five more times
    }

そして、すべての単一パラメーターの次のチャンクなので、7 回も同様です。

private SteerType _rotationOnIntervalType;
    private float _randomRotationOnInterval;
    private float _rotationOnInterval;
    public float RotationOnInterval
    {
        get
        {
            switch (_rotationOnIntervalType)
            {
                case SteerType.None:
                    return 0;
                case SteerType.Random:
                    if (_randomRotationOnInterval.Equals(0))
                        _randomRotationOnInterval =
                            MathHelper.ToRadians((float)(-Static.Random.NextDouble() + Static.Random.NextDouble()) * _rotationOnInterval);
                    return _randomRotationOnInterval;
                case SteerType.Variable:
                    return _rotationOnInterval;
            }
            return 0;
        }
    }
4

5 に答える 5

3

2/paired 値を保持するクラスを作成してから、コレクションにグループ化することを提案します。

public class Steering
{
    public SteerType SteerType{get;set}
    public int Amount{get;set}
}

List<Steering> userSteering = new List<Steering>
  {
     //initialize your list
  };

//pass that list into a constructor.

IdleSteering クラスで:

private List<Steering> steeringValues;

public IdleSteering(List<Steering> userSteering)
{
    steeringValues = userSteering;
}

//we can now use LINQ to find any particular steering value.
int braking = steeringValues.SingleOrDefault(x=>x.SteerType==Random).Amount;

すべてのメソッド間でそのコレクションを渡して使用します。

于 2012-05-12T15:11:37.383 に答える
3

設定オブジェクトを使用する - これらのパラメーターをクラスにリファクタリングし、そのクラスに渡します。問題なくパラメーターを追加できます。

これはパラメーター オブジェクトのリファクタリングと呼ばれ、BCL のいくつかの場所で使用されています (ProcessStartInfoクラスは 1 つです)。

このアプローチの追加のボーナスは、設定を使用するクラスとは別に、設定をシリアライズおよびデシリアライズできることです。

于 2012-05-12T15:09:36.463 に答える
2

最も明白な解決策は、パラメーターでパターンを探すことです。私が見ているのは、速度を表すSteerTypeと の組み合わせがあることです。int次に、この組み合わせを数回、いくつかの異なる状態ごとに 1 回ずつ行います。

それを考えると、これら 2 つのことを 1 つのクラスに組み合わせることができます。

public class SteerSettings
{
    public SteerType Type { get; private set; }
    public int Interval { get; private set; }

    public SteerSettings(SteerType type, int interval)
    {
        Type = type;
        Interval = interval;
    }
}

次に、コンストラクターを次のように変更します。

public IdleSteering(SteerSettings rotationOn, SteerSettings collision, 
                    SteerSettings break,  SteerSettings breakTime, 
                    SteerSettings rotationOnBreak, SteerSettings rangeFromSpawn, 
                    SteerSettings speed)
    {
        ...
    }

より積極的なアプローチは、それを利用してさまざまな状態を表す新しい列挙型を作成し、それを使用してDictionary各状態のさまざまな設定を指定することです。

public enum SteerState
{
    RotationOn,
    Collision,
    Break,
    BreakTime,
    RotationOnBreak,
    RangeFromSpawn,
    Speed
}

public IdleSteering(IDictionary<SteerState, SteerSettings> settings)
{
    ...
}
于 2012-05-12T15:12:23.807 に答える
0

さまざまなパラメーターで構成される、潜在的に無限の長さのコレクションがあるようです。

次のように、辞書で作成してみませんか。

public IdleSteering(IDictionary<SteerType,int> steerSettings)

次に、辞書のキーを調べて値を設定および取得します。

?!?

于 2012-05-12T15:14:57.883 に答える
0

SteerType と RotationValue (および必要に応じて仮想の getter) を使用して別の Rotation を作成し、次のようにコンストラクターでパラメーターをデフォルト設定します (.NET 4.0 が必要です)。

public IdleSteering(Rotation interval=null, Rotation collission=null)
    {

        _rotationOnIntervalType = rotationOnIntervalType??new Rotation(...);
        _rotationOnInterval = rotationOnInterval??new Rotation(...);
        ...
    }

次に、次のように呼び出します。

var idleSteering = new IdleSteering();

もちろん、プロパティをデフォルトにできる場合...

于 2012-05-12T15:19:39.003 に答える