Как я могу использовать строку для вызова объекта в C #? - PullRequest
1 голос
/ 01 ноября 2019

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

Моя проблема в том, что я программирую первую битву, с которой столкнется игрок. Я сконструировал несколько видов оружия, и я хочу иметь возможность называть текущее оружие людей отдельной строкой, например, Мое текущее оружие - это кинжал или объект wp1, я хочу, чтобы мое «оружие» было прикреплено к wp1. каким-то образом, чтобы я мог сделать что-то вроде Console.WriteLine("Damage: " + weapon.dmg); вместо жесткого кодирования wp1.dmg, чтобы позже в процессе создания игры, когда у игрока была возможность приобрести лучшее оружие, я мог сделать это с переменными,например, у игрока теперь есть короткий меч (wp2)

private string weapon = "wp2"; ... Console.WriteLine("Damage: " + weapon.dmg);

, который я пытался просто указать, String weapon = wp1;

, а затем вызвать Weapon.dmg, ноэто не работает, потому что он думает, что я пытаюсь вызвать Weapon.DMG, а не wp1.dmg


//players base damage
int damage = 0;

//players strength attribute
int strength = 0;

//weapon constructor
class wp
        {
            public int dmg;
            public int cost;
            public string name;

            public wp(int d, int c, string n)
            {
                dmg = d;
                cost = c;
                name = n;
            }
        }

//three weapons that are constructed
wp wp1 = new wp(1, 25, "dg");
wp wp2 = new wp(3, 100, "ss");
wp wp3 = new wp(5, 250, "ls");

//the current weapon string
public string weapon = "wp1";

void attack()
{
   //calculates damage based off of the players damage, strength, and weapon
   int newDamage = damage * strength + (weapon.dmg);
}

Ожидаемый результат: программа должнаиспользовать текущее значение урона оружия игрока

Фактический результат, программа пытается найти значение урона оружия, но это невозможно, потому что «оружие» - это просто строка, поэтому выдает ошибку

Ответы [ 2 ]

6 голосов
/ 01 ноября 2019

Как я уже сказал в комментарии выше, приобретает хорошие привычки сейчас, как новичок , и вам не придется отказываться от этих привычек позже. Давайте посмотрим, как мы можем разработать вашу систему. Начните с хорошо разработанной иерархии классов. Допустим, у нас есть три вида оружия: мечи, кинжалы и дубины. Общее, что у них есть, входит в абстрактный базовый класс:

abstract class Weapon
{

Что у них общего? Ущерб, стоимость и имя. Сделайте абстрактные свойства только для чтения для них:

    public abstract int Damage { get; }
    public abstract decimal Cost { get; }
    public abstract string Name { get; }
}

Теперь создайте несколько производных классов. Планируете ли вы расширить их дальше? Если нет, запечатайте их:

sealed class Sword : Weapon 
{
    public override int Damage => 10;
    public override decimal Cost => 12.5m;
    public override string Name => "normal sword";
}

и т. Д.

Теперь сделайте то же самое для игрока. Допустим, мы можем изменить оружие игрока, но не его имя. Так что Name должно быть свойством только для чтения, а Weapon должно быть свойством только для чтения и записи:

sealed class Player
{
  public string Name { get; private set; }
  public Weapon Weapon { get; set; }
  public int Strength { get; private set; }
  public int BaseDamage { get; private set; }
  public Player(string name, Weapon weapon, int strength, int baseDamage)
  {
    this.Name = name;
    this.Weapon = weapon;
    this.Strength = strength;
    this.BaseDamage = baseDamage;
  }
}

Теперь мы можем сделать несколько видов оружия:

Weapon weapon1 = new Sword();
Weapon weapon2 = new Dagger();
Weapon weapon3 = new Club();
Player fighter = new Player("Bob", weapon3, 5, 10);

Или, лучше:

var weapons = new List<Weapon> { new Sword(), new Dagger(), new Club() };
// weapons is indexed 0, 1, 2.
Player fighter = new Player("Bob", weapons[2], 5, 10);

А теперь, если у вас в руках игрок:

static void Attack(Player p)
{
  int damage = p.BaseDamage * p.Strength + p.Weapon.Damage;
  string text = $"Player {p.Name} attacks with {p.Weapon.Name}";

Нет строк для ссылок на объекты! Не используйте строки ни для чего, кроме text . Ссылки на объекты должны быть ссылками на объекты, а не на строки.

Теперь только для продвинутых игроков , бывают случаи, когда вам нужно что-то искать по строке. То, как вы делаете это в C #:

var d = new Dictionary<string, Weapon> {
  { "weapon1", new Sword() },
  { "weapon2", new Dagger() },
  { "weapon3", new Club() } 
};
Weapon w = d["weapon1"]; // w is a Sword.

Но не делают этого по умолчанию . Это не обычный способ ссылаться на что-то в C #.

0 голосов
/ 01 ноября 2019

один способ достичь того, что вы хотите:

if(weapon=="wp1")
 //use wp1 object here.

Но лучшим способом было бы поместить ваши 3 wp в список или массив (так как вы буквально жестко закодировали список из 3 объектов). Тогда wp1 будет в

wpArray[0];

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...