C#多态性与克隆

C#多态性与克隆,c#,xna,polymorphism,clone,C#,Xna,Polymorphism,Clone,让我先解释一下我想要实现的目标 我正在制作一个玩家可以拾取电源的游戏(出于某种原因,我在游戏中称之为“战利品”)。这是我的战利品课程的基本形式: public class Loot : Sprite { //Properties and fields... public Loot(/*parameters...*/) { } public virtual OnPickUp(Player player) { } } 玩家和精灵是我的职业

让我先解释一下我想要实现的目标

我正在制作一个玩家可以拾取电源的游戏(出于某种原因,我在游戏中称之为“战利品”)。这是我的战利品课程的基本形式:

public class Loot : Sprite
{
    //Properties and fields...

    public Loot(/*parameters...*/)
    {
    }

    public virtual OnPickUp(Player player)
    {
    }
}
玩家和精灵是我的职业。这是我的问题:我的sprite类有一个位置(Vector2,XNA中表示向量的结构),根据我对C#如何工作的理解,复制两个sprite会相互复制引用,因此,每当我改变一个位置时,它也会改变另一个的位置

每当一个战利品产生时,我有一个类持有可能产生的战利品,它返回一个随机的战利品,战利品被复制并显示在屏幕上,但一旦我得到多个相同类型的战利品,它就会因为引用复制问题而混乱(两者共享相同的位置,只有一个可见)

因此,每当我需要生成新的战利品时,我就尝试创建一个新的战利品对象,因此我必须提供一个具有多个参数的构造函数,以便以这种方式轻松复制战利品: (让我们假设toSpawn可以是从Loot类派生的任何类型,如HealthPack或其他类型)

在我决定实施“OnPick”之前,它看起来是正确的。由于我创建了一个新的Loot对象,而不是正确的子类,因此toSpawn的OnPickUp函数的功能将消失,拾取一个Loot将不会起任何作用(它只会调用基类Loot的空函数)

显然,我在这里做错了什么。我没有太多编程经验,更不用说C语言了,所以我真的不知道如何解决这个问题。我尝试使用表示OnPickUp功能的Action对象,它可以工作,但仍然会限制我很多(因为我必须将静态函数作为Action传递,因此限制我使用Player参数的信息,并阻止我使用子类特定的信息)

因此,最后,我的问题是:如果允许具有重载函数的子类,但仍然能够克隆基类及其属性,那么什么样的设计会更好?

谢谢你宝贵的时间


如果有什么不清楚的地方(我知道不清楚),请在评论中询问我,我将尝试更详细地描述我的问题。

让你的战利品类实现


让你的战利品等级实现


Vector2
是一个
struct
而不是
,因此您最初的问题听起来像是因为持有对同一个战利品对象的两个引用,而不是两个不同的战利品对象引用到同一位置

负责创建Loot对象的类应该创建相关Loot子类的新实例,而不是创建基类。在您的设计中,Loot可能是一个抽象类,甚至是一个接口,您应该使用创建所需类型的Loot对象

例如:

class LootFactory
{
    const int numLootTypes = 3;

    public Loot CreateLoot(Vector2 position)
    {
        Random rand = new Random();
        int lootIndex = rand.Next(numLootTypes);
        if (lootIndex == 0)
        {
            return new HealthPack(position);
        }
        if (lootIndex == 1)
        {
            ...
        }
        ...
    }
}

Vector2
是一个
struct
而不是
,因此您最初的问题听起来像是因为持有对同一个战利品对象的两个引用,而不是两个不同的战利品对象引用到同一位置

负责创建Loot对象的类应该创建相关Loot子类的新实例,而不是创建基类。在您的设计中,Loot可能是一个抽象类,甚至是一个接口,您应该使用创建所需类型的Loot对象

例如:

class LootFactory
{
    const int numLootTypes = 3;

    public Loot CreateLoot(Vector2 position)
    {
        Random rand = new Random();
        int lootIndex = rand.Next(numLootTypes);
        if (lootIndex == 0)
        {
            return new HealthPack(position);
        }
        if (lootIndex == 1)
        {
            ...
        }
        ...
    }
}

我想我在这个问题上肯定遗漏了什么,因为
Vector2
是一个结构而不是一个类。将一个
Vector2
直接分配给另一个会自动创建副本

var v2a = new Vector2(10.0f, 20.0f);
var v2b = v2a; //`v2b` is a new instance of `Vector2` distinct from `v2a`.
您的问题听起来像是
possibleLoot
类并没有随机化创建的每个
Loot
实例的位置

我假设你的游戏逻辑是这样的:“每个关卡最多可以产生10个战利品”,所以你的
PossibleLoots
类会在启动时创建所有可能的
Loot
对象,但除非被要求“产生战利品”,否则不会显示一个

那么,如果是这样的话,这不是你需要的东西吗

public class PossibleLoots
{
    private IList<Loot> _loots = new List<Loot>();

    public PossibleLoots(int maxLoots)
    {
        for (var i = 0; i < maxLoots; i++)
        {
            _loots.Add(new Loot(this.GetRandomPosition()));
        }
    }

    private Vector2 GetRandomPosition()
    {
        // Your logic here to create suitable locations for loot to appear
    }

    // Rest of your `PossibleLoots` code
    // to spawn each `Loot` and to deplete the `_loots`
    // collection when the player picks up each `Loot`
}
公共类可能的远程
{
私有IList_loots=新列表();
公共可能的LOOT(int maxLoots)
{
对于(变量i=0;i

如果我错过了这个问题的要点,请告诉我。

我想这个问题肯定遗漏了什么,因为
Vector2
是一个结构,而不是一个类。将一个
Vector2
直接分配给另一个会自动创建副本

var v2a = new Vector2(10.0f, 20.0f);
var v2b = v2a; //`v2b` is a new instance of `Vector2` distinct from `v2a`.
您的问题听起来像是
possibleLoot
类并没有随机化创建的每个
Loot
实例的位置

我假设你的游戏逻辑是这样的:“每个关卡最多可以产生10个战利品”,所以你的
PossibleLoots
类会在启动时创建所有可能的
Loot
对象,但除非被要求“产生战利品”,否则不会显示一个

那么,如果是这样的话,这不是你需要的东西吗

public class PossibleLoots
{
    private IList<Loot> _loots = new List<Loot>();

    public PossibleLoots(int maxLoots)
    {
        for (var i = 0; i < maxLoots; i++)
        {
            _loots.Add(new Loot(this.GetRandomPosition()));
        }
    }

    private Vector2 GetRandomPosition()
    {
        // Your logic here to create suitable locations for loot to appear
    }

    // Rest of your `PossibleLoots` code
    // to spawn each `Loot` and to deplete the `_loots`
    // collection when the player picks up each `Loot`
}
公共类可能的远程
{
私有IList_loots=新列表();
公共可能的LOOT(int maxLoots)
{
对于(变量i=0;i