我有点困惑,我正确地接近这个。假设我有一个滚动游戏,玩家可以击败怪物并收集物品,这里是我的玩家类的一些 :( c#)
public string Name { get; set; }
public double life { get; set; }
public double power { get; set; }
public Swords weapon { get; set; } // their Held weapon
private List<Items> items; //Represents their backpack
private Monster monster; //The monster they are currently facing.
public Player(string name)
{
this.Name = name;
life = 1000;
power = 10;
weapon = new Swords("Fists", 100, 1); //The power of the weapon. Can only punch at the start
items = new List<Items>();
}
public void addItem(Items i)
{
items.Add(i);
}
然后看看我在播放器类中使用的这种方法:
public void equiptSword() //
{
Swords tempSword;
foreach (Items i in items)
{
if (i is Swords)
{
tempSword = i as Swords;
tempSword.equiptItem(this);
}
}
}
正如你所看到的,我有一个名为items的超级/基类,所有内容都来源于此。当玩家击败怪物时,他们获得了一把剑,我将其添加到物品清单(他们的背包)中。基类没有equiptItem()
的虚方法,只有剑有这种方法。因此,我不能只键入类型items[5].equiptItem()
。这意味着我必须使用if语句检查我是否是一把剑,如果是,则将其作为一把剑施放,然后装备它。但是有一些关于这一点的事情让我觉得我正在接近它,当然,我可以在基类Items中添加一个虚拟方法,但是我再次不希望所有项目都可以选择装备。
对不起,如果我在散步。
您怎么看?我正确接近这个吗?
答案 0 :(得分:1)
我认为你走在正确的轨道上。
我同意你不想在Item
添加一大堆不相关的内容。
我认为你可以提出一些可以简化代码的广泛接口。
例如,您可以拥有IEquippable
接口,该接口具有Equip()
方法。然后任何可装备的物品都会实施IEquippable
。
您可以使用其他界面以类似的方式表示其他内容,例如IConsumable
和IPortable
。
然后在您的代码中,您可以执行以下操作:
IEquippable equippable = item as IEquippable;
if (equippable != null)
equippable.Equip(); /// Etc
使用Linq,您可以编写如下内容:
foreach (var equippableItem in inventoryItems.OfType<IEquippable>())
{
equippableItem.Equip();
}
但是,您应尽可能保留强类型集合 - 但当然,库存本质上是异构集合。
另请注意,使用接口来表示这些概念可让您拥有实现多个概念的项目,例如IConsumable
和IPortable
的药水。
将执行此操作的逻辑放入可以隐藏它的单独类中可能是个好主意;例如,一个处理装备的Equipper
类。
但有一件事 - 我不明白为什么你必须通过在袋子里循环装备剑。我原本以为你会有一套物品(让我们称之为Loot
)掉落在怪物身上,你会更喜欢这样:
void handleLoot(Loot loot)
{
// Get first sword dropped, or null if none.
var sword = Loot.Items.OfType<Sword>().FirstOrDefault();
if (sword != null) // Sword implements IEquippable so we can:
sword.Equip(); // just equip it.
}