How to add cooldown time to a character shooting?

I am developing a top down shooter. The character is already shooting fireballs but in my opionion the game is to easy so I want to add a cooldown time .
How can I do that?
Below I leave my projectile class

 public class Projectile : Basic2D 
    {
        protected bool done;
        protected float speed;
        protected Vector2 direction;
        protected Unit owner;
        protected _Timer timer;
        public float distanceTravelled = 250.0f;

        public Projectile(string _path, Vector2 _position, Vector2 _dimensions, Unit _owner, Vector2 _target) : base(_path, _position, _dimensions)
        {
            done = false;
            owner = _owner;
            direction = _target - owner.GetPosition();
            direction.Normalize(); //makes lenght 1
            SetRotation(Globals.RotateTowards(GetPosition(), new Vector2(_target.X, _target.Y)));
            timer = new _Timer(1200);
        }

        public bool IsDone()
        {
            return done;
        }
        public virtual void Update(Vector2 _offset, List<Unit> _units)
        {
            SetPosition(GetPosition() + (direction * speed));

            timer.UpdateTimer();
            if(timer.Test())
            {
                done = true;
            }

            if(CheckCollision(_units) || OutOfRange())
            {
                done = true;
                //owner.SetProjectilesOnScreen(owner.GetProjectilesOnScreen() - 1);
            }
            

        }


        public virtual bool CheckCollision(List<Unit> _units)
        {
            for(int i = 0; i < _units.Count; i++)
            {
                if (Vector2.Distance(GetPosition(), _units[i].GetPosition())< owner.GetAttackArea())
                {
                    _units[i].GetHit(owner.GetDamage());
                    return true;
                }
            }
            return false;
        }

        public virtual bool OutOfRange()
        {
            if(Vector2.Distance(GetPosition(), owner.GetPosition()) > owner.GetRange())
            {
                return true;
            }

            return false;

        }
    }

public class _Timer
    {
        public bool goodToGo;
        protected int mSec;
        protected TimeSpan timer = new TimeSpan();
        
        public _Timer(int m)
        {
            goodToGo = false;
            mSec = m;
        }

        public void UpdateTimer()
        {
            timer += Globals.gameTime.ElapsedGameTime;
        }

        public bool Test()
        {
            if(timer.TotalMilliseconds >= mSec || goodToGo)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void ResetToZero()
        {
            timer = TimeSpan.Zero;
            goodToGo = false;
        }

        public virtual void AddToTimer(int MSEC)
        {
            timer += TimeSpan.FromMilliseconds((long)(MSEC));
        }


    }

Looks like you tryed something with a _Time class.

If you look at the Update funktion in your game extended class you will see gameTime. You can use gameTime as it contains things like time sens last frame.

Here is an exampel of how to make a it in code.

I use a float variable with something like

EDIT: This logic should be on the object that is doing the shooting, not the projectile itself.

Doing this from Memory, so likely will have errors…

float timeLastShot;

private void Shoot()
{
   if (timeLastShot > 0) 
   {
       timeLastShot -= gameTime.Elaspsed; // Mono Games game time passed to Update()
       return;
   }
   // fire the shot
  timeLastShot = <your delay>; // Higher value = longer time between shots
}

That should give you frame independent adjustable fire rate.

Yes, I indeed have a _Timer class. Should I add a method to this class to do the cooldown?

If this is a OOP question i am proudly unqualified. Take a look at this https://gameprogrammingpatterns.com/ for exempels on structuring your project.

I have countdown functionality i can reuse every time i need something like a cooldown. so i say yes but i might not be the one ta ask.

Google is your friend look how others solved your problem.

I am looking for a opinion about another subject. I have the spawn points,characters,etc being loaded by code. Would it be better doing it using XML?

I would recommend JSON over XML. It will be a lot easier to read and edit by hand if you need to.

I create classes that match what I want in the “level file” and then I can serialize/deserialize the objects directly.

1 Like

But is there any advantage using this approach instead just storing my spawn points locations,monsters spawn rate ,etc in my code?

In code they are less hackable. In a file they are easier for you to manipulate when testing and balancing the game.

Also possible to use both methods in parallel. I mean load a level with code and also load additional levels by serialization. I would also recommend JSON. (Although I also used XML in a game but it was a long time ago and I did not know JSON at this time).

Another option is to develop using json files and then when you go to release use the json files as embedded resources in your app.

A scalable approach is to use events. Create an event queue, allow that event queue to sort and dispatch events scheduled for the future, process that queue each frame, and use events to fire and lock/unlock firing. Each part should be its own class. You should separate the projectile from the weapon, and those should be separate from the ship. Put the cooldown on the weapon and use a future event to unlock the weapon after whatever cooldown you want for that. You can extend this approach to update a GUI too. That’s scalable compared to polling updates and coupling everything to timing infrastructure since the temporality is decoupled.