我目前正在制作一个简单的基于控制台的 RPG 地牢游戏,我对 C# 还是很陌生,我在学校上过一门视觉基础类(class),并且已经玩了大约一个月的 unity。
我的问题是,我正在对玩家将遇到的第一场战斗进行编程。我已经构建了一些武器,我希望能够用单独的字符串调用人的当前武器,例如,我当前的武器是 Dagger ,或者对象 wp1,我希望我的“武器”附加到 wp1以某种方式,这样我就可以做类似的事情,
Console.WriteLine("Damage: "+ weapon.dmg);
而不是硬编码 wp1.dmg,这样在游戏制作过程的后期,当玩家有机会购买更好的武器时,我可以用变量来做,例如,玩家现在有短剑(wp2)
私有(private)字符串 weapon = "wp2";
...
Console.WriteLine("伤害:"+ 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);
}
预期结果: 程序应该使用玩家当前武器的伤害值
实际结果,程序试图找到武器的伤害值,但这是不可能的,因为“武器”只是一个字符串,所以会抛出错误
最佳答案
正如我在上面的评论中所说,现在养成良好的习惯,作为初学者,您以后就不必改掉这些习惯了。让我们看看我们如何设计您的系统。从设计良好的类层次结构开始。假设我们有三种武器:剑、 Dagger 和棍棒。它们的共同点进入一个抽象基类:
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}";
没有引用对象的字符串!不要将字符串用于除文本 之外的任何内容。对对象的引用应该是对对象的引用,而不是字符串。
现在,仅限高级玩家,有时您确实需要通过字符串查找某些内容。在 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# 中引用某些内容的正常方式。
关于c# - 在 C# 中如何使用字符串调用对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58665000/