From 3b39073b1f250111f8ca1981d8f0dd43735d0c5d Mon Sep 17 00:00:00 2001 From: Nik Date: Thu, 12 Oct 2023 11:41:48 +0300 Subject: [PATCH] refactor: collision system split wit debugging --- .../MovementFeatureCompositionRoot.cs | 15 ++++++ src/Libs/Features/Features.csproj | 4 -- src/Libs/Features/MovementFeature.cs | 5 +- .../DrawRectangleCollisionComponentsSystem.cs | 41 +++----------- src/Libs/Systems/CollisionSystem.cs | 54 +++++++++++++++++++ 5 files changed, 80 insertions(+), 39 deletions(-) create mode 100644 src/Libs/Systems/CollisionSystem.cs diff --git a/src/Apps/GameDesktop/CompositionRoots/Features/MovementFeatureCompositionRoot.cs b/src/Apps/GameDesktop/CompositionRoots/Features/MovementFeatureCompositionRoot.cs index 77cc3f1..7efe4bf 100644 --- a/src/Apps/GameDesktop/CompositionRoots/Features/MovementFeatureCompositionRoot.cs +++ b/src/Apps/GameDesktop/CompositionRoots/Features/MovementFeatureCompositionRoot.cs @@ -12,6 +12,11 @@ namespace GameDesktop.CompositionRoots.Features; internal class MovementFeatureCompositionRoot : ICompositionRoot { + private static readonly IMatcher[] CollisionMatchers = + { + GameMatcher.RectangleCollision, GameMatcher.Transform + }; + private static readonly IMatcher[] MovableMatchers = { GameMatcher.Transform, GameMatcher.Movable }; private static readonly IMatcher[] AnimatedMovableMatchers = @@ -31,6 +36,16 @@ private static void RegisterImpl(IServiceRegistry serviceRegistry) => private static void RegisterSystems(IServiceRegistry serviceRegistry) { + serviceRegistry.RegisterSingleton(factory => + { + var getGroup = factory.GetInstance[], IGroup>>(Matcher.AllOf); + IGroup group = getGroup(CollisionMatchers); + + var logger = factory.GetInstance(); + + return new CollisionSystem(group, logger); + }); + serviceRegistry.RegisterSingleton(factory => { var movement = factory.GetInstance(); diff --git a/src/Libs/Features/Features.csproj b/src/Libs/Features/Features.csproj index 742fe1c..6298e7b 100644 --- a/src/Libs/Features/Features.csproj +++ b/src/Libs/Features/Features.csproj @@ -17,8 +17,4 @@ - - - - diff --git a/src/Libs/Features/MovementFeature.cs b/src/Libs/Features/MovementFeature.cs index 3b0c7c3..62bdfec 100644 --- a/src/Libs/Features/MovementFeature.cs +++ b/src/Libs/Features/MovementFeature.cs @@ -4,9 +4,12 @@ namespace Features; public sealed class MovementFeature : Entitas.Extended.Feature { - public MovementFeature(MovementSystem movementSystem, + public MovementFeature( + CollisionSystem collisionSystem, + MovementSystem movementSystem, AnimatedMovementSystem animatedMovementSystem) { + Add(collisionSystem); Add(movementSystem); Add(animatedMovementSystem); } diff --git a/src/Libs/Systems.Debugging/DrawRectangleCollisionComponentsSystem.cs b/src/Libs/Systems.Debugging/DrawRectangleCollisionComponentsSystem.cs index 8a5a92b..2b2bacb 100644 --- a/src/Libs/Systems.Debugging/DrawRectangleCollisionComponentsSystem.cs +++ b/src/Libs/Systems.Debugging/DrawRectangleCollisionComponentsSystem.cs @@ -20,58 +20,31 @@ public DrawRectangleCollisionComponentsSystem(Contexts contexts, IGroup x.transform.Position.Y).ToArray(); + GameEntity[] entities = _group.GetEntities(); spriteBatch.Begin(samplerState: SamplerState.PointClamp); - // temp start Color[] colors = { Color.Black, Color.White }; int k = 0; - // temp end - for (int i = 0; i < entities.Length; ++i) + foreach (GameEntity e in entities) { - GameEntity first = entities[i]; - - for (int j = i + 1; j < entities.Length; ++j) - { - GameEntity second = entities[j]; - if (AreIntersecting(first, second)) - { - first.transform.Velocity = Vector2.Zero; - second.transform.Velocity = Vector2.Zero; - } - } - - // temp start var texture = new Texture2D(spriteBatch.GraphicsDevice, 1, 1); texture.SetData(new[] { colors[k] }); + ++k; - if (k is 2) + if (k == colors.Length) k = 0; - // temp end - spriteBatch.Draw(texture, first.transform.Position, sourceRectangle: first.rectangleCollision.Size, + spriteBatch.Draw(texture, e.transform.Position, sourceRectangle: e.rectangleCollision.Size, Color.White); } spriteBatch.End(); } - private bool AreIntersecting(GameEntity first, GameEntity second) - { - Func buildRectangle = new(x => - new((int)(x.transform.Position.X + x.transform.Velocity.X), - (int)(x.transform.Position.Y + x.transform.Velocity.Y), - x.rectangleCollision.Size.Width, - x.rectangleCollision.Size.Height)); - - Rectangle firstRectangle = buildRectangle(first); - Rectangle secondRectangle = buildRectangle(second); - - return Rectangle.Intersect(firstRectangle, secondRectangle).IsEmpty is false; - } } diff --git a/src/Libs/Systems/CollisionSystem.cs b/src/Libs/Systems/CollisionSystem.cs new file mode 100644 index 0000000..01c3235 --- /dev/null +++ b/src/Libs/Systems/CollisionSystem.cs @@ -0,0 +1,54 @@ +using Entitas; +using Entitas.Extended; +using Microsoft.Xna.Framework; +using Serilog; + +namespace Systems; + +public class CollisionSystem : IFixedExecuteSystem +{ + private readonly IGroup _group; + private readonly ILogger _logger; + + public CollisionSystem(IGroup group, ILogger logger) + { + _group = group; + _logger = logger; + } + + // TODO: Optimize efficiency + public void FixedExecute(GameTime gameTime) + { + GameEntity[] entities = _group.GetEntities(); + + for (int i = 0; i < entities.Length; ++i) + { + GameEntity first = entities[i]; + + for (int j = i + 1; j < entities.Length; ++j) + { + GameEntity second = entities[j]; + + if (AreIntersecting(first, second)) + { + first.transform.Velocity = Vector2.Zero; + second.transform.Velocity = Vector2.Zero; + } + } + } + } + + private static bool AreIntersecting(GameEntity first, GameEntity second) + { + Rectangle firstRectangle = BuildRectangle(first); + Rectangle secondRectangle = BuildRectangle(second); + + Rectangle intersect = Rectangle.Intersect(firstRectangle, secondRectangle); + + return !intersect.IsEmpty; + + Rectangle BuildRectangle(GameEntity x) => new((int)(x.transform.Position.X + x.transform.Velocity.X), + (int)(x.transform.Position.Y + x.transform.Velocity.Y), x.rectangleCollision.Size.Width, + x.rectangleCollision.Size.Height); + } +}