I'm writing a game in C# Monogame, and I've decided to make my project as modular as possible.
At first, I've had a single project with a folder that's separated inside to other folders which represent different systems in the game (Items, Abilities, Stats).
I've started by making a .dll project for everything that I've considered as a 'system', i.e - Items, Abilities, Stats, and others that I will soon add, like the player itself (that's just a class right now).
I'm designing the Abilities system based on the answer given on this post.
I'm asking for a code review about the Ability
system module, and if you care, about the rest of the game (the MainModule
is just remainder of what I've had before I refactored into modularizing everything, so for now there's not much need for whatever's there, unless you see something the could help).
I'd appreciate referencing stuff (or solutions to problems I have) to design patterns, as I'd rather use design patterns to solve problems.
The ability system code:
public interface IBehavior
{
void ApplyBehavior(IUnit unit);
}
// ---------------------------------------------------- //
public abstract class ActivatableBehavior : IBehavior
{
public abstract bool BehaviorImplentation(IUnit destinationPlayer);
public void ApplyBehavior(IUnit unit)
{
BehaviorImplentation(unit);
}
}
// ---------------------------------------------------- //
public abstract class LimitedTimeBehavior : IBehavior
{
public Stopwatch Timer { get; }
public abstract void ApplyBehavior(IUnit unit);
public long Duration { get; }
protected LimitedTimeBehavior(long durationOfBehavior)
{
Timer = new Stopwatch();
Duration = durationOfBehavior;
}
}
// ---------------------------------------------------- //
public abstract class TickBasedBehavior : LimitedTimeBehavior
{
public long TickTime { get; }
protected abstract void ApplyTick(IUnit unit);
protected TickBasedBehavior(long durationOfBehavior, long timeBetweenTicks)
: base(durationOfBehavior)
{
TickTime = timeBetweenTicks;
}
public override void ApplyBehavior(IUnit unit)
{
Thread trd = new Thread(() => ThreadMethod(unit));
trd.Start();
}
private void ThreadMethod(IUnit unit)
{
Timer.Start();
while (Timer.ElapsedMilliseconds < Duration)
{
if (Timer.Elapsed.TotalMilliseconds % TickTime == 0)
ApplyTick(unit);
}
Timer.Stop();
}
}
// ---------------------------------------------------- //
public abstract class DurationBehavior : LimitedTimeBehavior
{
protected abstract void Activate(IUnit unit);
protected abstract void Deactivate(IUnit unit);
private bool IsActivated { get; set; }
protected DurationBehavior(long durationOfBehavior)
: base(durationOfBehavior)
{
IsActivated = false;
}
public override void ApplyBehavior(IUnit unit)
{
if (IsActivated) return;
Thread trd = new Thread(() => ThreadMethod(unit));
trd.Start();
IsActivated = true;
}
private void ThreadMethod(IUnit unit)
{
Timer.Start();
Activate(unit);
while (Timer.Elapsed.TotalMilliseconds < Duration) { }
Timer.Reset();
Deactivate(unit);
IsActivated = false;
}
}