C# 重写方法不会运行

问题描述 投票:0回答:1

对于我在单一游戏中制作的大学项目,我有一本字典,其中引用了我的游戏中的所有不同实体。我使用的层次结构是:组件<---- Entity <---- Enemy <---- Sawblade. I am defining the references like so:

{
    "Sawblade",
     new Sawblade(new Dictionary<string, Animation>
     {
           {"Moving", AllAnimations["SawBladeMoving"] },
     }, 100f, -1, 2)
},

在主要游戏更新方法中,我使用以下方法循环遍历所有当前实体:

foreach (Component entity in entities[game.currentDungeon.currentFloor])
{
     entity.Update(_gametime);
}

到目前为止,这效果非常好,它使用敌人类中的更新方法更新敌人,并使用其自己的更新类更新其他实体。但是我需要锯片类来运行这个更新方法,而不是一般敌人类中的更新方法:

public override void Update(GameTime gameTime)
{
      if (GameManager.CheckTileCollisions(new Rectangle(Edge.X + (int)Velocity.X, Edge.Y, Edge.Width, Edge.Height))) Velocity = new Vector2(-Velocity.X, Velocity.Y);
      if (GameManager.CheckTileCollisions(new Rectangle(Edge.X, Edge.Y + (int)Velocity.Y, Edge.Width, Edge.Height))) Velocity = new Vector2(Velocity.X, -Velocity.Y);
      animationManager.LateUpdate(gameTime);
}

锯片更新方法(应该运行什么)^

public override void Update(GameTime gameTime)
{
      if(Health <= 0) GameManager.RemoveEntity(this);
      if(Target is not null)
      {
            // TEMP PATHFINDING
            if(Target.Position.X == Position.X) Velocity = new Vector2(0, 0);
            else if (Target.Position.X > Position.X) Velocity =  new Vector2(1, 0);
            else Velocity = new Vector2(-1, 0);
            if (Target.Position.Y == Position.Y) Velocity = new Vector2(Velocity.X, 0);
            else if (Target.Position.Y > Position.Y) Velocity = new Vector2(Velocity.X, 1);
            else Velocity = new Vector2(Velocity.X, -1);
      }
}

敌人更新方法(正在运行什么)^

我不明白为什么对于每个其他实体,程序都会运行最高级别的覆盖,但对于此类,它的行为就好像锯片覆盖甚至不存在一样。有人对可能导致这种情况的原因有任何想法吗?

我已经尝试过:

foreach (Component entity in entities[game.currentDungeon.currentFloor])
{
      if (entity is Sawblade) ((Sawblade)entity).Update(_gametime);
      else entity.Update(_gametime);
}

看看错误是否是我不明白该实体是锯片类型,但它仍然拒绝确认覆盖。

课程:
成分:

public abstract class Component
    {
        public virtual Vector2 Position { get; set; }
        public Vector2 Size { get; set; }
        public Rectangle Edge => new Rectangle(Position.ToPoint(), Size.ToPoint());
        public Component Parent { get; set; }

        public bool IsSelected { get; set; }

        public abstract void Update(GameTime gameTime);
        public abstract void LateUpdate(GameTime gameTime);
        public abstract void Draw(SpriteBatch spriteBatch);
    }

实体:

public class Entity : Component
    {

        protected Vector2 Velocity { get; set; }

        public Direction direction;

        protected AnimationManager animationManager;
        protected Dictionary<string, Animation> animations;

        public Item itemContents;

        public override Vector2 Position { get => base.Position; set { base.Position = value; if (animationManager != null) animationManager.Position = value; } }

        public float LinearSpeed { get; set; }
        public Texture2D Texture { get; protected set; }

        public Entity(Texture2D texture, float speed)
        {
            Position = Vector2.Zero;
            Texture = texture;
            Size = new Vector2(texture.Width, texture.Height);
            Velocity = Vector2.Zero;
            LinearSpeed = speed;
            direction = Direction.Down;
        }

        public Entity(Dictionary<string, Animation> animations, float speed)
        {
            Position = Vector2.Zero;
            this.animations = animations;
            LinearSpeed = speed;
            Velocity = Vector2.Zero;
            Size = new Vector2(animations[animations.First().Key].frameWidth, animations[animations.First().Key].frameHeight);
            animationManager = new AnimationManager(animations.First().Value);
            direction = Direction.Down;
        }

        public Entity(Animation animation, float speed) : this(new Dictionary<string, Animation> { { "Idle", animation } }, speed)
        {
        }

        public override void Update(GameTime gameTime)
        {
        }

        public override void LateUpdate(GameTime gameTime)
        {
            // Physics
            Position += Velocity * LinearSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
            if (animationManager != null)
            {
                animationManager.LateUpdate(gameTime);
                if (animations.ContainsKey("WalkDown")) SetAnimations();
            }
        }
        public void DrawEditor(SpriteBatch spriteBatch)
        {
            if (animationManager is not null)
            {
                animationManager.Stop();
                animationManager.Draw(spriteBatch, Color.Gray);
            }
            else spriteBatch.Draw(Texture, Edge, Color.Gray);
        }
        public override void Draw(SpriteBatch spriteBatch)
        {
            if(animationManager is not null) animationManager.Draw(spriteBatch, Color.White);
            else spriteBatch.Draw(Texture, Edge, Color.White);
        }

        protected virtual void SetAnimations()
        {
            if (Velocity.Y > 0 && Velocity.X == 0)
            {
                animationManager.Play(animations["WalkDown"]);
                direction = Direction.Down;
            }
            else if (Velocity.Y < 0 && Velocity.X == 0)
            {
                animationManager.Play(animations["WalkUp"]);
                direction = Direction.Up;
            }
            if (Velocity.X < 0)
            {
                animationManager.Play(animations["WalkLeft"]);
                direction = Direction.Left;
            }
            else if (Velocity.X > 0)
            {
                animationManager.Play(animations["WalkRight"]);
                direction = Direction.Right;
            }
            else if (Velocity.Y == 0) animationManager.Stop();
        }

        public virtual void Activate(Player activator)
        {
        }
        public virtual void Activate(Dungeon dungeon)
        {
        }

        public virtual Entity Clone(Entity copy)
        {
            copy.Position = this.Position;
            copy.direction = this.direction;
            if (animationManager is not null) copy.animationManager = this.animationManager.Clone();
            copy.animations = this.animations;
            if(itemContents is not null) copy.itemContents = this.itemContents.Clone();
            copy.Size = this.Size;
            copy.Parent = this.Parent;
            copy.Velocity = this.Velocity;
            copy.Texture = this.Texture;
            copy.IsSelected = this.IsSelected;
            copy.LinearSpeed = this.LinearSpeed;
            return copy;
        }
        public virtual Entity Clone()
        {
            Entity copy;
            if (animationManager is not null) copy = new Entity(animations, LinearSpeed);
            else copy = new Entity(Texture, LinearSpeed);
            return Clone(copy);
        }

        public void Serialize(BinaryWriter writer)
        {

        }
        public void Deserialize(BinaryReader reader)
        {

        }
    }

敌人:

public class Enemy : Entity
    {
        public int Health { get; set; }
        public int Damage { get; set; }
        public bool IsAlive { get; set; }

        Component Target;

        public Enemy(Texture2D texture, float speed, int hp, int dmg) : base(texture, speed)
        {
            Health = hp;
            Damage = dmg;
        }

        public Enemy(Dictionary<string, Animation> _animations, float speed, int hp, int dmg) : base(_animations, speed)
        {
            Health = hp; Damage = dmg;
        }

        public void SetTarget(Component target)
        {
            Target = target;
        }

        public override void Update(GameTime gameTime)
        {
            if(Health <= 0) GameManager.RemoveEntity(this);
            if(Target is not null)
            {
                // TEMP PATHFINDING
                if(Target.Position.X == Position.X) Velocity = new Vector2(0, 0);
                else if (Target.Position.X > Position.X) Velocity =  new Vector2(1, 0);
                else Velocity = new Vector2(-1, 0);
                if (Target.Position.Y == Position.Y) Velocity = new Vector2(Velocity.X, 0);
                else if (Target.Position.Y > Position.Y) Velocity = new Vector2(Velocity.X, 1);
                else Velocity = new Vector2(Velocity.X, -1);
            }
        }

        public override void Activate(Player activator)
        {
            IsAlive = false;
        }

        public override Entity Clone()
        {
            Enemy copy;
            if (animationManager is not null) copy = new Enemy(animations, LinearSpeed, Health, Damage);
            else copy = new Enemy(Texture, LinearSpeed, Health, Damage);
            copy.Health = Health;
            copy.Damage = Damage;
            copy.IsAlive = IsAlive;
            return Clone(copy);
        }
    }

锯片:

public class Sawblade : Enemy
    {
        public Sawblade(Dictionary<string, Animation> _animations, float speed, int hp, int dmg) : base(_animations, speed, hp, dmg)
        {
            Random rng = new Random();
            Velocity = new Vector2((float)rng.NextDouble(), (float)rng.NextDouble());
            animationManager.Play(_animations["Moving"]);
        }

        public override void Update(GameTime gameTime)
        {
            if (GameManager.CheckTileCollisions(new Rectangle(Edge.X + (int)Velocity.X, Edge.Y, Edge.Width, Edge.Height))) Velocity = new Vector2(-Velocity.X, Velocity.Y);
            if (GameManager.CheckTileCollisions(new Rectangle(Edge.X, Edge.Y + (int)Velocity.Y, Edge.Width, Edge.Height))) Velocity = new Vector2(Velocity.X, -Velocity.Y);
            animationManager.LateUpdate(gameTime);
        }
    }
c# .net game-development monogame
1个回答
0
投票

找到了解决方案,这是因为在将实体添加到实体列表时,我调用了clone()方法,该方法在sawblade中没有被重写,所以它只是将sawblade返回为敌人类型。

将该方法添加到锯片中并解决了问题

public override Entity Clone()
        {
            Sawblade copy = new Sawblade(animations, LinearSpeed, Health, Damage);
            return base.Clone(copy);
        }
© www.soinside.com 2019 - 2024. All rights reserved.