-1

所以我对编程很陌生。我目前正在开发地形生成程序,除此之外一切都很好:

    public static class Desert
    {
        public const int iChance = 15;
        public static int chance = iChance;
        public static int chancepoint = 0;
        public const int octaves = 4;
        public const int lengthMin = 60;
        public const int lengthMax = 90;
        public const float scaleMin = 250;
        public const float scaleMax = 350;
        public const float persistenceMin = 0.5f;
        public const float persistenceMax = 0.9f;
        public const pType ptype = pType.Lowland;
        public const bTag[] tags = { bTag.desert };
    }
    public static class Meadow
    {
        public const int iChance = 45;
        public static int chance = iChance;
        public static int chancepoint = 0;
        public const int octaves = 4;
        public const int lengthMin = 45;
        public const int lengthMax = 70;
        public const float scaleMin = 200;
        public const float scaleMax = 470;
        public const float persistenceMin = 0.35f;
        public const float persistenceMax = 0.70f;
        public const pType ptype = pType.noAbs;
        public const bTag[] tags = { bTag.lush };
    }

这些是每种不同类型的“生物群系”的属性。

我目前大约有 7 个,除了每个字段的值之外,它们都完全相同。

有没有办法可以缩短代码?我研究了继承,但最终出现了错误,我有点困惑。><

如果我要写的只是:

public static class Desert
    {
        iChance = 15;
        chance = iChance;
        chancepoint = 0;
        octaves = 4;
        lengthMin = 60;
        lengthMax = 90;
        scaleMin = 250;
        scaleMax = 350;
        persistenceMin = 0.5f;
        persistenceMax = 0.9f;
        ptype = pType.Lowland;
        strongTags = { bTag.desert };
    }

提前致谢。

哦,对这个问题的尖锐表示抱歉,如果你看到程序的其余部分,你可能会尖叫我的代码有多糟糕。XD

编辑:告诉你我永远不会再改变课堂上的东西,除了“机会”的价值之外,这可能是明智的。

4

9 回答 9

3

您可以使用非静态类,而不是使用静态类。

public class Biome {
    // Instance fields with default values
    public int iChance = 15;
    public int chance = iChance;
    public int chancepoint = 0;
    public int octaves = 4;
    public int lengthMin = 60;
    public int lengthMax = 90;
    public float scaleMin = 250;
    public float scaleMax = 350;
    public float persistenceMin = 0.5f;
    public float persistenceMax = 0.9f;
    public pType ptype = pType.Lowland;
    public bTag[] tags = { bTag.desert };
}

这里使用构造函数进行初始化:

public Biome(int iChance, int chance, int chancepoint, int octaves, public int lengthMin, int lengthMax, float scaleMin, float scaleMax, float persistenceMin, float persistenceMax,pType ptype, bTag[] tags) {
    // init fields here
}

然后调用构造函数:

Biome bimoe = new Biome(15, iChance, 0, 4, 60, 90, 250, 350, 0.5f, 0.9f, pType.Lowland, { bTag.desert });

有了这个,很难看出哪个参数去哪个字段,但它要短得多。

如果字段必须是只读的,您可以使属性只有公共get而没有set访问器。例子:

public Chance { get { return chance; } }

在这种情况下,将字段设为私有:

private int chance = iChance;

(就个人而言,对于这种情况,我会将所有数据放在一个文件中)

于 2013-05-20T08:19:04.970 回答
1

以下内容会更短:

public const int iChance = 15, octaves = 4, lengthMin = 60, lengthMax = 90;
public const float scaleMin = 250, scaleMax = 350, persistenceMin = 0.5f,
                   persistenceMax = 0.9f;
public static int chance = iChance, chancepoint = 0;

然而......这些看起来真的不像应该是static字段的东西,甚至很可能不是const。它们看起来像应该是实例属性的东西。也许是这样的:

public class Terrain {
   public int Chance {get;private set;}
   public int LengthMin {get;private set;}
   // ...
   private Terrain(int chance, int lengthMin, ...) {
       Chance = chance;
       LengthMin = lengthMin;
       // ...
   }
   private static readonly Terrain
       desert = new Terrain(45, 45, ...),
       meadow = new Terrain(15, 60, ...),
       ...;
   public static Terrain Desert { get { return desert;}}
   public static Terrain Meadow { get { return meadow;}}
}
于 2013-05-20T08:22:26.973 回答
1

我不太了解地形生成程序,但您应该将数据存储在数据库中。然后创建类以将该数据映射到您的应用程序。我建议您查找“数据结构”,看看哪一个最适合您的应用程序。

于 2013-05-20T08:28:54.297 回答
0

最好只使用一个没有继承甚至结构的类。Desert、Meadow 等在逻辑上不是类,它必须是对象(可能是常量)。

于 2013-05-20T08:19:50.270 回答
0

您可以做的是使用一个名为 Terrain 的类,并使用静态构造函数多次初始化:

   public class Terrain
    {
            public int IChance { get; private set; }
    public int Chancepoint { get; private set; }
    public int Octaves { get; private set; }
    public int LengthMin { get; private set; }
    public int LengthMax { get; private set; }
    public float ScaleMin { get; private set; }
    public float ScaleMax { get; private set; }
    public float PersistenceMin { get; private set; }
    public float PersistenceMax { get; private set; }
    public pType Ptype { get; private set; }
    public bTag[] Tags { get; private set; }

        public static Terrain Desert()
        {
            return new Terrain
                {
                    IChance = 15,
                    Chancepoint = 0,
                    Octaves = 4,
                    LengthMin = 60,
                    LengthMax = 90,
                    ScaleMin = 250,
                    ScaleMax = 350,
                    PersistenceMin = 0.5f,
                    PersistenceMax = 0.9f,
                    Ptype = pType.Lowland,
                    Tags = new bTag[] {bTag.Desert}
                };
        }
}
于 2013-05-20T08:26:01.027 回答
0

joe 的回答很好,但是构造函数调用有太多未命名的参数 - 350 是什么意思?

这是数据驱动设计的理想选择。

与其在代码中定义所有 Biome 类型,不如将 Biome 类型的所有数据放入一个文件并在运行时读取该文件。C# 语言有很多东西可以帮助你做到这一点,要搜索的关键词是序列化(这里是 MSDN 的链接)。

最大的优势是您可以更改数据值而无需重新编译代码。

缺点是需要更多的代码来定义第一个实例,但在那之后,您可以轻松地创建任意数量的实例。

于 2013-05-20T08:26:34.883 回答
0

你可以做一些像这样声明一个抽象类然后继承它的事情:

    public abstract class Terrain
    {
        public int iChance;
        public int chance;
        public int chancepoint;
        public int octaves;
        public int lengthMin;
        public int lengthMax;
        public float scaleMin;
        public float scaleMax;
        public float persistenceMin;
        public float persistenceMax;
        public pType ptype;
        public Tag[] strongTags;
    }

    public class Desert : Terrain
    {

    }

    public enum pType
    {
        Desert = 1,
        LowLand = 2
    }

    public enum Tag
    {
        desert = 1,
        lush = 2
    }

然后,您可以像这样实例化沙漠:

var desert = new Desert()
            {
                iChance = 15
                ,chance = 15
                ,chancepoint = 0
                ,octaves = 4
                ,lengthMin = 60
                ,lengthMax = 90
                ,scaleMin = 250
                ,scaleMax = 350
                ,persistenceMin = 0.5f
                ,persistenceMax = 0.9f 
                ,ptype = pType.Desert
                ,strongTags = new Tag[]{Tag.desert}
            };
于 2013-05-20T08:29:48.557 回答
0

不确定您的确切要求是什么,但这不是更好的方法:

public abstract class BiomeBase
{
    public int Chance      { get; set; }
    public int Chancepoint { get; set; }
    public int Octaves     { get; set; }
    // you get the idea ...
}

然后你有DesertMeadow继承:

public class Desert : BiomeBase
{
    // everything is inherited ...
    // you can also add your own properties meant for Desert only (if needed)
}

public class Meadow : BiomeBase
{
    // everything is inherited ...
}

现在Desert拥有一切Biome,您可以像这样使用它:

var desert = new Desert
{
    Chance = 5,
    Octaves = 1, 
    /// etc
};
于 2013-05-20T08:30:20.093 回答
-2

首先,您不能对静态类进行继承。所以你必须开始使用实例。

其次,如果您想扩展对象,您将使用继承。例如,如果您想将新属性“bool HasScorpions”添加到沙漠而不是草甸。

由于您使用相同的属性但想使用不同的值,我个人使用接口。这样,您可以使属性只读等,同时仍然可以轻松设置值。

public interface Terrain
{
    int iChance = {get { return 15; private set; } ..and repeat.
    int chance = iChance;
    int chancepoint = 0;
    int octaves = 4;
    int lengthMin = 60;
    int lengthMax = 90;
    float scaleMin = 250;
    float scaleMax = 350;
    float persistenceMin = 0.5f;
    float persistenceMax = 0.9f;
    pType ptype = pType.Lowland;
    bTag[] tags = { bTag.desert };
}
于 2013-05-20T08:21:40.823 回答