1

我已经为游戏实现了一种转向行为形式,并且每次使用编辑器时,设计师应该能够选择(当前)七个参数,无论它们应该是 0、随机还是设定数量,以及在以下情况下后两者,随机应该落在哪个范围内或变量应该得到哪个设定量。设置将保存在文件中,并且必须能够随时加载。

我最终看到的是构造函数和一大堆字段和属性是痛苦的。 我正在寻找一种更智能的方法来解决这个问题,尤其是在以后添加更多参数时。

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
    }

以及每个参数的以下块,因此也是七次。

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

使用设置对象 - 将这些参数重构为一个类并将该类传入。您可以添加其他参数而不会出现问题。

这称为参数对象重构,并且已在 BCL 中的多个地方使用 -ProcessStartInfo类就是其中之一。

这种方法的另一个好处是您可以将设置与使用它们的类分开序列化和反序列化。

于 2012-05-12T15:09:36.463 回答
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 回答
2

最明显的解决方案是在参数中寻找模式。我看到的是,你有SteerTypeint代表速度的组合。然后,您可以多次使用这种组合,每次用于几种不同的状态。

鉴于此,您可以将这两件事组合成一个类:

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)
    {
        ...
    }

一种更激进的方法是采用它并创建一个代表您的各种状态的新枚举,并在 a 中使用它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 req'ed):

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 回答