C# Overriding Method won't run

98 views Asked by At

For a college project I'm making in monogame, I have a dictionary with references to all the different entities in my game. The hierachy I'm using is: Component <---- Entity <---- Enemy <---- Sawblade. I am defining the references like so:

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

In the main gameplay update method I am looping through all the current entities with:

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

So far this has worked very well, it updates the enemies with the update method in the enemy class and updates other entities with their own update class. However I need the sawblade class to run this update method and not the update method in the general enemy class:

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

The sawblade update method (What should run)^

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

The enemy update method (What is running)^

I don't understand why for every other entity the program runs the highest level override but for this class specifically it acts as if the sawblade override isn't even there. Does anybody have any ideas on what could be causing this?

I have tried:

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

to see if the error is that i doesn't understand the entity is of the sawblade type however it still refuses to acknowledge the override.

Classes:
Component:

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

Entity:

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)
        {

        }
    }

Enemy:

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

Sawblade:

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

There are 1 answers

0
ProGrammar On

Found the solution, it was due to when adding the entity to the entities list I called the clone() method which wasn't overriden in sawblade, so it was only returning the sawblade as type enemy.

Added the method to the sawblade and it fixed the problem

public override Entity Clone()
        {
            Sawblade copy = new Sawblade(animations, LinearSpeed, Health, Damage);
            return base.Clone(copy);
        }