diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/AddAsteroidCommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/AddAsteroidCommand.cs new file mode 100644 index 0000000..f1547ec --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/AddAsteroidCommand.cs @@ -0,0 +1,12 @@ +using Avans.FlatGalaxy.Simulation.Commands.Common; + +namespace Avans.FlatGalaxy.Simulation.Commands +{ + public class AddAsteroidCommand : ICommand + { + public void Execute(ISimulator simulator) + { + simulator.AddAsteroid(); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/CollisionSwitchCommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/CollisionSwitchCommand.cs new file mode 100644 index 0000000..35ebc32 --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/CollisionSwitchCommand.cs @@ -0,0 +1,12 @@ +using Avans.FlatGalaxy.Simulation.Commands.Common; + +namespace Avans.FlatGalaxy.Simulation.Commands +{ + public class CollisionSwitchCommand : ICommand + { + public void Execute(ISimulator simulator) + { + simulator.SwitchCollisionAlgo(); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/CollisionVisibilityCommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/CollisionVisibilityCommand.cs new file mode 100644 index 0000000..9695350 --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/CollisionVisibilityCommand.cs @@ -0,0 +1,12 @@ +using Avans.FlatGalaxy.Simulation.Commands.Common; + +namespace Avans.FlatGalaxy.Simulation.Commands +{ + public class CollisionVisibilityCommand : ICommand + { + public void Execute(ISimulator simulator) + { + simulator.ToggleCollisionVisibility(); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/Common/ICommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/Common/ICommand.cs new file mode 100644 index 0000000..d8d0a71 --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/Common/ICommand.cs @@ -0,0 +1,7 @@ +namespace Avans.FlatGalaxy.Simulation.Commands.Common +{ + public interface ICommand + { + void Execute(ISimulator simulator); + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/PauseCommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/PauseCommand.cs new file mode 100644 index 0000000..cf4481f --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/PauseCommand.cs @@ -0,0 +1,12 @@ +using Avans.FlatGalaxy.Simulation.Commands.Common; + +namespace Avans.FlatGalaxy.Simulation.Commands +{ + public class PauseCommand : ICommand + { + public void Execute(ISimulator simulator) + { + simulator.Pause(); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/RemoveAsteroidCommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/RemoveAsteroidCommand.cs new file mode 100644 index 0000000..cdb25e0 --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/RemoveAsteroidCommand.cs @@ -0,0 +1,12 @@ +using Avans.FlatGalaxy.Simulation.Commands.Common; + +namespace Avans.FlatGalaxy.Simulation.Commands +{ + public class RemoveAsteroidCommand : ICommand + { + public void Execute(ISimulator simulator) + { + simulator.RemoveAsteroid(); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/RestoreCommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/RestoreCommand.cs new file mode 100644 index 0000000..18ebc12 --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/RestoreCommand.cs @@ -0,0 +1,12 @@ +using Avans.FlatGalaxy.Simulation.Commands.Common; + +namespace Avans.FlatGalaxy.Simulation.Commands +{ + public class RestoreCommand : ICommand + { + public void Execute(ISimulator simulator) + { + simulator.Restore(); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/ResumeCommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/ResumeCommand.cs new file mode 100644 index 0000000..9c09e83 --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/ResumeCommand.cs @@ -0,0 +1,12 @@ +using Avans.FlatGalaxy.Simulation.Commands.Common; + +namespace Avans.FlatGalaxy.Simulation.Commands +{ + public class ResumeCommand : ICommand + { + public void Execute(ISimulator simulator) + { + simulator.Resume(); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/SpeedDownCommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/SpeedDownCommand.cs new file mode 100644 index 0000000..10d9746 --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/SpeedDownCommand.cs @@ -0,0 +1,19 @@ +using Avans.FlatGalaxy.Simulation.Commands.Common; + +namespace Avans.FlatGalaxy.Simulation.Commands +{ + public class SpeedDownCommand : ICommand + { + private readonly double _speedDiff; + + public SpeedDownCommand(double speedDiff = ISimulator.SpeedDiff) + { + _speedDiff = speedDiff; + } + + public void Execute(ISimulator simulator) + { + simulator.SpeedDown(_speedDiff); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Commands/SpeedUpCommand.cs b/src/Avans.FlatGalaxy.Simulation/Commands/SpeedUpCommand.cs new file mode 100644 index 0000000..1cdb1cd --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Commands/SpeedUpCommand.cs @@ -0,0 +1,19 @@ +using Avans.FlatGalaxy.Simulation.Commands.Common; + +namespace Avans.FlatGalaxy.Simulation.Commands +{ + public class SpeedUpCommand : ICommand + { + private readonly double _speedDiff; + + public SpeedUpCommand(double speedDiff = ISimulator.SpeedDiff) + { + _speedDiff = speedDiff; + } + + public void Execute(ISimulator simulator) + { + simulator.SpeedUp(_speedDiff); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/Extensions/ListExtensions.cs b/src/Avans.FlatGalaxy.Simulation/Extensions/ListExtensions.cs new file mode 100644 index 0000000..a68ddaa --- /dev/null +++ b/src/Avans.FlatGalaxy.Simulation/Extensions/ListExtensions.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Avans.FlatGalaxy.Simulation.Extensions +{ + public static class ListExtensions + { + public static T Random(this IEnumerable source) + { + return source.Random(1).Single(); + } + + public static IEnumerable Random(this IEnumerable source, int count) + { + return source.Shuffle().Take(count); + } + + public static IEnumerable Shuffle(this IEnumerable source) + { + return source.OrderBy(x => Guid.NewGuid()); + } + } +} diff --git a/src/Avans.FlatGalaxy.Simulation/ISimulator.cs b/src/Avans.FlatGalaxy.Simulation/ISimulator.cs index 42fc251..334a102 100644 --- a/src/Avans.FlatGalaxy.Simulation/ISimulator.cs +++ b/src/Avans.FlatGalaxy.Simulation/ISimulator.cs @@ -9,14 +9,32 @@ public interface ISimulator public const int Height = 600; + public const double SpeedDiff = 0.1; + + public const double BookmarkTime = 5000; + Galaxy Galaxy { get; set; } QuadTree QuadTree { get; set; } + bool CollisionVisible { get; set; } + void Resume(); void Pause(); void Restore(); + + void SpeedUp(double speed); + + void SpeedDown(double speed); + + void SwitchCollisionAlgo(); + + void AddAsteroid(); + + void RemoveAsteroid(); + + void ToggleCollisionVisibility(); } } diff --git a/src/Avans.FlatGalaxy.Simulation/Simulator.cs b/src/Avans.FlatGalaxy.Simulation/Simulator.cs index 2d19973..48c73e5 100644 --- a/src/Avans.FlatGalaxy.Simulation/Simulator.cs +++ b/src/Avans.FlatGalaxy.Simulation/Simulator.cs @@ -1,11 +1,16 @@ using System; +using System.Drawing; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Avans.FlatGalaxy.Models; +using Avans.FlatGalaxy.Models.CelestialBodies; +using Avans.FlatGalaxy.Models.CelestialBodies.States; using Avans.FlatGalaxy.Simulation.Bookmark; using Avans.FlatGalaxy.Simulation.Bookmark.Common; using Avans.FlatGalaxy.Simulation.Collision; using Avans.FlatGalaxy.Simulation.Data; +using Avans.FlatGalaxy.Simulation.Extensions; namespace Avans.FlatGalaxy.Simulation { @@ -17,7 +22,7 @@ public class Simulator : ISimulator private DateTime _lastTick = DateTime.UtcNow; - private int _speed = 50; + private double _speed = 25; private bool _running = false; private DateTime _lastBookmark; @@ -37,6 +42,8 @@ public Simulator(Galaxy galaxy) public QuadTree QuadTree { get; set; } + public bool CollisionVisible { get; set; } = false; + public void Resume() { if (_running) return; @@ -60,7 +67,45 @@ public void Restore() _caretaker.Undo(); } - public void Tick(CancellationToken token) + public void SpeedUp(double speed) + { + _speed += speed; + } + + public void SpeedDown(double speed) + { + _speed -= speed; + } + + public void SwitchCollisionAlgo() + { + _collisionHandler.Toggle(); + } + + public void ToggleCollisionVisibility() + { + CollisionVisible = !CollisionVisible; + } + + public void AddAsteroid() + { + var rnd = new Random(); + var x = rnd.NextDouble() * ISimulator.Width; + var y = rnd.NextDouble() * ISimulator.Height; + var vx = rnd.NextDouble() * 10 - 5; + var vy = rnd.NextDouble() * 10 - 5; + var radius = rnd.Next(2, 6); + + Galaxy.Add(new Asteroid(x, y, vx, vy, radius, Color.Black, new NullCollisionState())); + } + + public void RemoveAsteroid() + { + var asteroid = Galaxy.CelestialBodies.OfType().Random(); + Galaxy.Remove(asteroid); + } + + private void Tick(CancellationToken token) { if (_running) { @@ -74,7 +119,7 @@ public void Tick(CancellationToken token) _collisionHandler.Detect(this); _lastTick = DateTime.UtcNow; - if ((DateTime.UtcNow - _lastBookmark).TotalSeconds >= 1) + if ((DateTime.UtcNow - _lastBookmark).TotalSeconds >= ISimulator.BookmarkTime) { _caretaker.Save(); _lastBookmark = DateTime.UtcNow;