简体   繁体   English

如何在继承的类中使用抽象方法?

[英]How to use abstract methods in inherited classes?

I'm currently working on a school project that's due to friday & I've got a whole lot to do. 由于星期五,我目前正在做一个学校项目,还有很多工作要做。 The assignment is to make a video game with XNA framework using Monogame. 任务是使用Monogame使用XNA框架制作视频游戏。 I'm currently working with collisions. 我目前正在处理碰撞。

The structure for gameobjects looks somewhat like this: 游戏对象的结构如下所示: 在此处输入图片说明

For collisions, I have a simple collision class 对于碰撞,我有一个简单的碰撞课程

     class Collision{

public GameObject Other;

public GameObject Obj1;

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

The collisions are handled in a static method in the GameObject class: 冲突是通过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));
            }
        }
    }

}

This far it's working, the game is finding all collisions like it should. 到目前为止,游戏正在寻找所有应有的碰撞。 However now I need to let my objects know that they're colliding, and tell them what to do. 但是,现在我需要让我的对象知道它们正在碰撞,并告诉他们该怎么做。 For this, I made the entity class abstract to be able to declare an abstract method called "OnCollision(Collision collision)" 为此,我使实体类成为抽象类,以便能够声明一个名为“ OnCollision(Collisionflict)”的抽象方法。

 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); } 

Then I'm overriding the method in the classes that inherit the Entity class 然后我在继承Entity类的类中重写方法

Ex. 防爆。 Projectile 弹丸

 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 } } 

Then I'm trying to call the OnCollision method from my Update in the GameObject class. 然后,我尝试从GameObject类中的Update调用OnCollision方法。 This is how I try to inform my objects if they are collding and who they're colliding with: 这是我尝试通知对象是否碰撞以及与谁碰撞的方法:

  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); } 

I'm new to abstract classes & overriding, so I might have gotten the whole idea wrong. 我是抽象类和重写的新手,所以我可能把整个想法弄错了。 But it seems the OnCollision method isn't reached as I've tried to Debug.WriteLine stuff but nothing shows up in the output window. 但是似乎在我尝试Debug.WriteLine时未达到OnCollision方法,但是在输出窗口中没有任何显示。

Thanks for reading & perhaps trying to help me out :) 感谢您的阅读,并尝试帮助我:)

Mediafire link to download the project in case you want to see all the code. 如果您想查看所有代码,请使用Mediafire链接下载项目。

You should read up on interfaces . 您应该阅读接口 An interface provides a contract (a bunch of methods and properties) that deriving classes must implement. 接口提供了派生类必须实现的协定(一堆方法和属性)。 Abstract classes are more concrete than interfaces in that they can also provide a base implementation for deriving classes. 抽象类比接口更具体,因为它们还可以提供派生类的基本实现。 You can only derive from one abstract class whereas you can derive from multiple interfaces. 您只能从一个抽象类派生,而您可以从多个接口派生。 From the code in your post it looks like you are using an abstract class like an interface. 从帖子中的代码看来,您正在使用抽象类(如接口)。

You are using reflection to do type checking. 您正在使用反射进行类型检查。 There's the is keyword for testing type compatibility. is关键字用于测试类型兼容性。 For example: 例如:

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

    // player specific code
}

Finally; 最后; from what I can gather from your post it looks like you aren't quite using inheritance correctly. 从我可以从您的帖子中收集到的信息来看,您似乎不太正确地使用继承。 It looks like you are correctly using inheritance to build a type hierarchy but then putting all the logic in a base class. 看起来您正在正确地使用继承来构建类型层次结构,然后将所有逻辑都放在基类中。

Inheritance is meant to let you put the specialized logic in the appropriate class. 继承的目的是让您将专用逻辑放入适当的类中。

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");
    }
}

When we then have a reference to a IGameObject and call OnCollision the appropriate OnCollision function will automatically be called. 然后,当我们有对IGameObject的引用并调用OnCollision ,将自动调用相应的OnCollision函数。 For example: 例如:

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

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

Output: 输出:

Player collision
Projectile collision

Eh, wrong if statement... 嗯,如果声明错了...

Using 使用

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

fixed it. 修复。

Silly mistake, my bad. 愚蠢的错误,我不好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM