2014-10-20 6 views
2

Примечание: Я немного начинаю с 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; 
} 

Я знаю, что там, наверное, миллион вещей в моем коде здесь, что можно сделать лучше, и я с удовольствием слушаю, если у вас есть предложения, но я хочу спросить:

Как я могу получить все значения из каждого класса, используя, возможно, только одно имя? Ex. Вместо того, чтобы делать, как я делаю сейчас, есть способ, так что я могу сделать что-то похожее на это:

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

Проблема здесь заключается в методе setValues, некоторые из уровней имеет довольно много настроек, которые я хочу но я сомневаюсь, что метод захочет взять 15 параметров, и я не уверен, что делать, когда некоторые уровни не используют настройки, используемые другими уровнями.

Как мне изменить код, поэтому мне не нужно использовать каждое значение в качестве параметра?

ответ

3

Вы можете использовать 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; 
    } 
} 

You затем заполнить свой словарь как

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

UPDATE

Заметка об абстрактных классах

Вы упомянули абстрактные классы в ваших комментариях. Они полезны, если все ваши уровни имеют общее поведение, но некоторые из них также имеют специализированное поведение. Они часто будут использоваться в играх для вещей, которые могут перемещаться в игре, например. что-то вроде

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); 
     } 

    } 
} 
+1

Просто вызывать действительно важное различие между этим и исходным кодом; методы были реорганизованы в * auto-properties *; который, безусловно, правильный путь, но изменение не может быть очевидным, если вы не обращали внимания. – BradleyDotNET

+0

Спасибо, что позвонили. –

+0

Спасибо. Я не уверен, как используется Словарь, поэтому я посмотрю, как это сделать. У меня есть два вопроса: 1. Не потребовалось бы, чтобы я назначил каждое значение в классе формы? 2. Что делать, если у меня есть уровень, который не используется, скажем, MaxPoints. – Jokuc

1

один способ, возможно, использовать словарь.

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<string,object> и добавить некоторые проверки типа и другие вещи, чтобы заставить его работать гладко, но, надеюсь, вы можете начать работу с этим

+0

Спасибо. а также! Чтобы добавить 2D-массив int внутри Словаря (как в моем примере там), я просто положил после словаря ключевое слово? Как я могу добавить это: int [,] position = new int [boardSize, boardSize]; положение [1, 1] = 1; в Словарь? – Jokuc

+0

честно говоря, я оставил бы это сам и напишу методы, чтобы изменить его. если ваши уровни не имеют более одного игрового поля. – RadioSpace

+0

Как вы это понимаете? (Извините за то, что я так глуп, я новичок в этих вещах.) Я использую одну плату (выглядит как контрольная доска, за исключением того, что количество ячеек изменяется для каждого уровня). – Jokuc

Смежные вопросы