我正在开发游戏的玩家库存系统。
我有一个struct Slot ,它有一个List< Loot>表示允许哪些项目的集合。抽象类 Loot 由所有可掠夺的项子类化 - 即:将是 Slot 结构的有效内容值。
我想表示 Slot 可以限制它可以包含的 Loot 的子类。例如,如果 Slot 代表一个弹药容器,我希望它只能容纳 Loot 子类,它们是弹药容器,如“Quivers”和“Shot Pouches”(这将是子类容器沿线的某个地方。)
Loot class
public abstract class Loot : GameEntity, ILootable
{
public int MaxUnitsPerStack { get; set; }
public int MaxUnitsCarriable { get; set; }
public int MaxUnitsOwnable { get; set; }
public void Stack() { }
public void Split() { }
public void Scrap() { }
}
容器类
public abstract class Container : Loot
{
public List<Slot> Slots { get; set; }
public Container(int slots)
{
this.Slots = new List<Slot>(slots);
}
}
广告位结构
public struct Slot
{
public Loot Content;
public int Count;
public List<Loot> ExclusiveLootTypes;
public Slot(Loot[] exclusiveLootTypes)
{
this.Content = null;
this.Count = 0;
List<Loot> newList;
if (exclusiveLootTypes.Count() > 0)
{
newList = new List<Loot>(exclusiveLootTypes.Count());
foreach (Loot l in exclusiveLootTypes)
{
newList.Add(l);
}
}
else { newList = new List<Loot>(); }
this.ExclusiveLootTypes = newList;
}
}
PlayerInventory
public struct PlayerInventory
{
static Dictionary<Slot, string> Slots;
static void Main()
{
Slots = new Dictionary<Slot, string>();
/* Add a bunch of slots */
Slots.Add(new Slot(/* I don't know the
syntax for this:
Quiver, Backpack */), "Backpack"); // Container
}
}
我不知道如何在 PlayerInventory 类的Main方法中的 Slot 构造函数调用中为Loot子类提供参数。
我希望这很清楚。提前谢谢。
修改
我能够使用David Sieler的方法和一些反射来解决这个问题(并且我的意思是让它编译)。
广告位结构
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
public struct Slot
{
private Loot _content;
private int _count;
public List ExclusiveLootTypes;
public Loot Content
{
get { return _content; }
private set
{
if ((ExclusiveLootTypes.Contains(value.GetType())) && (value.GetType().IsSubclassOf(Type.GetType("Loot"))))
{
_content = value;
}
}
}
public int Count
{
get { return _count; }
set { _count = value; }
}
public Slot(params Type[] exclusiveLootTypes)
{
this._content = null;
this._count = 0;
List newList;
if (exclusiveLootTypes.Count() > 0)
{
newList = new List(exclusiveLootTypes.Count());
foreach (Type l in exclusiveLootTypes)
{
newList.Add(l);
}
}
else { newList = new List(); }
this.ExclusiveLootTypes = newList;
}
}
PlayerInventory调用Slot构造函数
Slots.Add(new Slot(typeof(Backpack)));
再次感谢大家的讨论。
答案 0 :(得分:2)
您可能会发现在Slot构造函数的定义中使用params
更容易:
Slot(params Loot[] exclusiveLootTypes)
这可以让你称之为:
new Slot(lootItem1, lootItem2, lootItem2 /*...etc*/);
否则,您需要创建一个数组并将其传入。
答案 1 :(得分:2)
听起来你的对象设计需要稍微调整一下。
如果战利品的类型也是接口,那么例如,所有弹药战斗物品都继承自IAmmoContainer。
然后你可以传入IAmmoContainer类型来限制插槽。
public class Quiver : Container, IAmmoContainer
public class ShotPouch : Container, IAmmoContainer
// ...
new Slot(typeof(IAmmoContainer))
修改强>
根据评论中的讨论,以下是我如何设计这个系统。
Loot
课很好。它代表了战利品等级的基础。
然后为项目可以占用的“插槽”定义接口。例如:
public class LongSword : Loot, IRightHandItem
public class ShortSword : Loot, IRightHandItem, ILeftHandItem
然后,PlayerInventory类将“slots”作为属性,限制为适当的类型。
public class PlayerInventory
{
public List<IRightHandItem> RightHandSlot { get; private set; }
public List<ILeftHandItem> LeftHandSlot { get; private set; }
// etc...
}
答案 2 :(得分:1)
一种方法是将一个Type
对象数组传递给Slot构造函数:
public Slot(Type[] exclusiveLootTypes) {
// be sure and check that each Type is a subtype of Loot!
}
// Construction looks like:
new Slot(new[] {GetType(AmmoContainer), GetType(GemContainer) /* or whatever */});
然后为Content
编写一个属性setter来检查指定对象的类型,如果该类型不包含在ExclusiveLootTypes中,则发出某种错误信号。
答案 3 :(得分:1)
并结合之前的建议使用params,您可以使用LINQ扩展将params转换为List一步:
public Slot(params Type[] exclusiveLootTypes)
{
this.Content = null;
this.Count = 0;
this.ExclusiveLootTypes = exclusiveLootTypes.ToList();
}