【问题标题】:How to use abstract methods in inherited classes?如何在继承类中使用抽象方法?
【发布时间】:2017-11-07 14:33:04
【问题描述】:

我目前正在做一个周五的学校项目,我有很多事情要做。 任务是使用 Monogame 使用 XNA 框架制作视频游戏。我目前正在处理碰撞问题。

游戏对象的结构有点像这样:

对于碰撞,我有一个简单的碰撞类

     class Collision{

public GameObject Other;

public GameObject Obj1;

public Collision(GameObject obj1, GameObject other)
{
    Other = other;
    Obj1 = obj1;
}}

在 GameObject 类中的静态方法中处理碰撞:

public static void UpdateCollisions()
{
    //Empty the list
    AllCollisions.Clear();

    for (int a = 0; a < AllGameObjectsWithCollision.Count; a++)
    {
        GameObject obja = AllGameObjectsWithCollision[a];
        for (int b = 0; b < AllGameObjectsWithCollision.Count; b++)
        {
            GameObject objb = AllGameObjectsWithCollision[b];

            if (obja.Mask != null & objb.Mask!= null && obja != objb)
            {
                if (obja.Mask.CollisionRectangle.Intersects(objb.Mask.CollisionRectangle))
                    AllCollisions.Add(new Collision(obja, objb));
            }
        }
    }

}

到目前为止,它正在工作,游戏正在寻找所有应有的碰撞。但是现在我需要让我的对象知道它们正在碰撞,并告诉它们该怎么做。 为此,我将实体类抽象为能够声明一个名为“OnCollision(Collision collision)”的抽象方法

abstract class Entity : GameObject
{
    public float Health;
    public float MaxHealth;
    public bool Alive;
    public float OriginalDmg;
    public float Dmg;

    public abstract void OnCollision(Collision collision);
}

然后我在继承Entity类的类中重写方法

例如。弹丸

class Projectile : Entity
{
    Entity Owner;
    ProjectileType pType;

    public Projectile(Texture2D image, float maxSpeed, Entity owner, float dmg, ProjectileType type)
    {
        Image = image;
        MaxSpeed = maxSpeed;
        AccelerationSpeed = MaxSpeed;
        Owner = owner;
        Dmg = dmg;
        pType = type;
    }

    public override void OnCollision(Collision collision)
    {
        #region If this projectile friendly
        if (pType == ProjectileType.Friendly)
        {
            //If colliding with an enemy
            if (collision.Other.GetType() == typeof(Enemy))
            {
                var enemy = (Enemy)collision.Other;
                enemy.Health -= Dmg;
                Destroy(this);
            }
        }
        #endregion

        #region If this projectile is hostile
        if (pType == ProjectileType.Hostile)
        {

        }
        #endregion
    }
}

然后我尝试从 GameObject 类中的 Update 调用 OnCollision 方法。 这就是我尝试通知我的对象是否正在碰撞以及它们正在与谁碰撞的方式:

        if (GetType().IsAssignableFrom(typeof(Entity)))
        {
            Entity entity = (Entity)this;

            if (GetType() == typeof(Player))
                entity = (Player)this;
            if (GetType() == typeof(Enemy))
                entity = (Enemy)this;
            if (GetType() == typeof(Projectile))
                entity = (Projectile)this;

            var entityCol = FindCollision(entity);

            if (entityCol != null)
                entity.OnCollision(entityCol);
        }

我是抽象类和重写的新手,所以我可能把整个想法弄错了。 但似乎没有达到 OnCollision 方法,因为我尝试了 Debug.WriteLine 的东西,但输出窗口中没有显示任何内容。

感谢您阅读并可能会帮助我:)

Mediafire link 下载项目以备查看所有代码。

【问题讨论】:

  • 会不会是entityCol为null,所以没有尝试调用OnCollision方法?
  • 我刚刚尝试调试该值,似乎它甚至没有通过“if (GetType().IsAssignableFrom(typeof(Entity)))”。 Player, Entity & Projectile 继承 Entity 类...不应该是正确的吗?
  • 嗨。只有 1 点:UpdateCollisions 中的嵌套循环不需要从 0 开始。它可以从 a+1 开始。关于不发生碰撞的问题,您需要在调用 UpdateCollisions 后确定 AllCollisions 中的内容。该容器中的数据是否应该是它应该是的数据? FindCollision 是否返回正确的值?您需要一点一点地拆开它,直到找到损坏的链接。不是答案,但我希望我已经在正确的方向上刺激了你。

标签: c# inheritance types xna monogame


【解决方案1】:

您应该阅读interfaces。接口提供派生类必须实现的契约(一堆方法和属性)。抽象类比接口更具体,因为它们还可以为派生类提供基本实现。您只能从一个抽象类派生,而您可以从多个接口派生。从您帖子中的代码看来,您正在使用像接口这样的抽象类。

您正在使用反射进行类型检查。 is 关键字用于测试类型兼容性。例如:

if(entity is Player)
{
    var player = (Player)entity;

    // player specific code
}

最后;根据我从您的帖子中收集到的信息,您似乎没有完全正确地使用继承。看起来您正确地使用继承来构建类型层次结构,然后将所有逻辑放在基类中。

继承旨在让您将专门的逻辑放在适当的类中。

public interface IGameObject
{
    void OnCollision(IGameObject target);
}

public class Player : IGameObject
{
    public void OnCollision(IGameObject target)
    {
         Console.WriteLine("Player collision");
    }
}

public class Projectile : IGameObject
{
    public void OnCollision(IGameObject target)
    {
         Console.WriteLine("Projectile collision");
    }
}

当我们引用IGameObject 并调用OnCollision 时,将自动调用相应的OnCollision 函数。例如:

IGameObject player = new Player();
IGameObject projectile = new Projectile();

player.OnCollision(projectile);
projectile.OnCollision(player);

输出:

Player collision
Projectile collision

【讨论】:

  • 哦,哇,谢谢,我会考虑的。我将继续完成目前的工作,因为本周五需要完成作业。
【解决方案2】:

呃,错误的 if 语句...

使用

if (GetType().IsSubclassOf(typeof(Entity)))

修复它。

愚蠢的错误,我的错。

【讨论】:

  • 我认为其中的“GetType()==typeof”if 语句也是多余的,因为您已经将其分配给实体。
猜你喜欢
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-01
  • 1970-01-01
相关资源
最近更新 更多