【问题标题】:Assign multiple values to one object(?)为一个对象分配多个值(?)
【发布时间】:2014-12-15 20:03:46
【问题描述】:

注意:我有点 C# 的初学者。

我正在开发一款包含许多不同关卡的小游戏。每个级别都有自己的类,其中包含变量(和其他不相关的代码)。因为我需要将这些值传递给主类(我的表单),所以我将它们全部变成了返回我想要的值的方法(因为我想不出更好的解决方案)。示例:

class Level01
{
    public int Boxes() { return 3; }
    public int MaxPoints() { return 46; }
    public int Health() { return 63; }
    public int[,] SolidBoxes()
    {
        int[,] position = new int[Boxes(), Boxes()];
        position[1, 1] = 1;
        return position;
    }
}

当我从我的表单类中访问这些值时,我会这样做

int boxes;
int maxPoints;
int health;
int[,] solidBoxes;

void readLevelData() //Starts each new level
{
    //Reads the correct level
    switch (levelNo)
    {
        case 1: 
        setValues(Lvl01.Boxes(), Lvl01.MaxPoints(), Lvl01.Health(), Lvl01.SolidBoxes()); 
        break;
        //The same case 2:, 3: for Level02,03..
    }
}

void setValues(int getBoxes, int getMaxPoints, int getHealth, int[,] getSolidBoxes)
{
    boxes = getBoxes;
    maxPoints = getMaxPoints;
    health = getHealth;
    solidBoxes = getSolidBoxes;
}

我知道我的代码中可能有一百万个地方可以做得更好,如果您有任何建议,我很乐意倾听,但我想问的是:

如何仅使用一个名称从每个类中获取所有值?前任。而不是像我现在做的那样,有没有办法让我可以做类似的事情:

case 1: 
    setValues(Lvl01.Values); 
    break;

这里的问题出在 setValues 方法中,一些关卡有很多我想使用的设置,但我怀疑该方法是否需要 15 个参数,我不知道该怎么做当某些关卡不使用其他关卡使用的设置时。

我应该如何更改我的代码,这样我就不必将每个值都用作参数?

【问题讨论】:

    标签: c# variables parameters arguments


    【解决方案1】:

    您可以使用Dictionary<int, Level> 来查找代表每个级别的对象。而不是开关/案例,你会做类似的事情

    Level level = myLevelDictionary[currentLevel];
    

    这需要您将您的课程从每个级别一个课程更改为一个代表任何级别的课程,例如:

    class Level
    {
        public int Boxes { get; set; }
        public int MaxPoints { get; set; }
        public int Health { get; set; }
        public int[,] SolidBoxes()
        {
            int[,] position = new int[boardSize, boardSize];
            position[1, 1] = 1;
            return position;
        }
    }
    

    然后你会像这样填充你的字典

    Dictionary<int, Level> myLevelDictionary = new Dictionary<int, Level>()
    {
        { 1, new Level() { Boxes = 3, MaxPoints = 46, Health = 63 } },
        // etc.
    };
    

    更新

    关于抽象类的说明

    您在 cmets 中提到了抽象类。如果您的所有关卡都有一些共同的行为,但有些关卡也有专门的行为,它们会很有用。它们通常用于游戏中可以在游戏中移动的东西,例如。像

    abstract class Character
    {
        // Something everyone has
        public int HitPoints { get; set; }
        // Something everyone does, but does differently
        public abstract void Attack(Character target);    
    }
    
    public class Fighter : Character
    {
        public int SwordDamage { get; set; }
    
        public void Attack(Character target)
        {
            target.Damage(this.SwordDamage - target.PhysicalDamageResistance);
        }
    }
    
    public class Mage : Character
    {
        public int MagicFireDamage { get; set; }
        public int MagicColdDamage { get; set; }
    
        public void Attack(Character target)
        {
            if (UseFireDamage()) // e.g. roll random chance that the mage uses a fire spell
            {
                target.Damage(this.SwordDamage - target.FireDamageResistance);
            }
            else
            {
                target.Damage(this.SwordDamage - target.ColdDamageResistance);
            }
    
        }
    }
    

    【讨论】:

    • 只是指出这与原始代码之间的一个非常重要的区别;这些方法已被重构为 auto-properties;这无疑是正确的方法,但除非您注意,否则变化可能并不明显。
    • 感谢您的来电。
    • 谢谢。我不确定 Dictionary 是如何使用的,所以我会在一段时间内查找它。不过我有两个问题: 1. 那不需要我在表单类中分配每个值吗? 2. 如果我有一个不使用的关卡怎么办,比如 MaxPoints。
    • 词典为您提供了一个地方来存储您以后想要获得的东西(关卡)。获得它们后,您可以使用键(级别编号)查找它们。
    • @Jokuc:不可变的意思是对象初始化后值不能改变。它可以保护程序的其他部分免于意外更改不应更改的内容。虽然它是一个重要的高级概念,但我不建议您过分担心它,除非您对不太高级的主题有信心。
    【解决方案2】:

    一种方法可能是使用字典。

    class Level01
    {
    Dictionary<string,int> values;
    
    public level01()
    {
       values.Add("Boxes",3);
       values.Add("MaxPoints",3);
       values.Add("Health",3);
    
    }
     //indexer
    public int this[string s] {get{return values[s];} set {values[s] = value;}}
    
    }
    

    并像这样使用:

    Level01 lv = new Level01();
    somemethod(lv["Boxes"]); //passes 3 to some method
    

    虽然您确实想使用 Dictionary&lt;string,object&gt; 并添加一些类型检查和其他内容以使其顺利运行,但希望您可以开始使用它

    【讨论】:

    • 也谢谢您!要在 Dictionary 中添加一个二维整数数组(如我上面的示例),我是否只需将 放在 Dictionary 关键字之后?我该如何添加: int[,] position = new int[boardSize, boardSize];位置[1, 1] = 1;到词典?
    • 老实说,我会自己留下它并编写方法来修改它。除非您的关卡有多个游戏板。
    • 你是什么意思? (抱歉这么愚蠢,我对这些东西很陌生。)我使用一个棋盘(看起来像棋盘,只是每个级别的盒子数量都会变化)
    • int GetCell(int x, int y)void ChangeCell(int x, int y, int val) 等方法用于使用游戏板
    • @Jokuc opps 在我最后的评论中没有@你
    猜你喜欢
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 2016-06-24
    • 2019-12-27
    • 1970-01-01
    • 2012-01-06
    相关资源
    最近更新 更多