Skip to content

Commit

Permalink
feat: CollisionSystem
Browse files Browse the repository at this point in the history
- Code clean-up
  • Loading branch information
cherrynik committed Feb 28, 2024
1 parent efdde5e commit aa2a23d
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,15 @@ private static void RegisterTransformComponent(IServiceRegistry serviceRegistry)

private static void RegisterRectangleColliderComponent(IServiceRegistry serviceRegistry)
{
serviceRegistry.RegisterTransient(_ =>
new RectangleColliderComponent { Size = new(0, 0, 8, 8) });
serviceRegistry.RegisterSingleton(_ =>
new RectangleColliderComponent
{
Size = new(0, 0, 8, 8),
// IsTrigger = true
}, "DummyEntity");

serviceRegistry.RegisterSingleton(_ =>
new RectangleColliderComponent { Size = new(0, 0, 8, 8) }, "PlayerEntity");
}

private static void RegisterInventoryComponent(IServiceRegistry serviceRegistry)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Components.Data;
using Components.Render.Animation;
using Components.Tags;
using Entities;
using Entities.Factories;
using Entities.Factories.Characters;
using LightInject;

Expand All @@ -22,7 +20,7 @@ private static void RegisterEntity(IServiceRegistry serviceRegistry) =>
factory.GetInstance<MovableComponent>(),
factory.GetInstance<TransformComponent>("PlayerEntity"),
factory.GetInstance<CameraComponent>(),
factory.GetInstance<RectangleColliderComponent>(),
factory.GetInstance<RectangleColliderComponent>("PlayerEntity"),
factory.GetInstance<MovementAnimationsComponent>(),
factory.GetInstance<CharacterAnimatorComponent>("PlayerEntity"),
factory.GetInstance<InventoryComponent>()));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Components.Data;
using Components.Render.Static;
using Entities;
using Entities.Factories;
using Entities.Factories.Characters;
using LightInject;

Expand All @@ -20,5 +18,5 @@ private static void RegisterEntity(IServiceRegistry serviceRegistry) =>
new NameComponent("Dummy"), // factory.GetInstance<NameComponent>("Dummy")
factory.GetInstance<TransformComponent>("DummyEntity"),
factory.GetInstance<SpriteComponent>(),
factory.GetInstance<RectangleColliderComponent>()));
factory.GetInstance<RectangleColliderComponent>("DummyEntity")));
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private static void RegisterEntryPoint(IServiceRegistry serviceRegistry)
var panel = new Panel();
var rightBottomText = new Label()
{
Text = "Pre-Alpha v0.1.0",
Text = "Pre-Alpha v0.1.1",
HorizontalAlignment = HorizontalAlignment.Right,
VerticalAlignment = VerticalAlignment.Bottom,
Left = -30,
Expand Down Expand Up @@ -122,7 +122,9 @@ private static void RegisterEntryPoint(IServiceRegistry serviceRegistry)
// ⚠ Order-sensitive zone ⚠
var movement = new Feature(factory.GetInstance<World>(), factory.GetInstance<SystemsEngine>(),
new InputSystem(factory.GetInstance<World>(), new KeyboardInput()),
new MovementSystem(factory.GetInstance<World>(), new SimpleMovement()));
new CollisionSystem(factory.GetInstance<World>()),
new MovementSystem(factory.GetInstance<World>(), new SimpleMovement())
);

var preRender = new Feature(factory.GetInstance<World>(),
factory.GetInstance<SystemsEngine>(),
Expand Down
35 changes: 21 additions & 14 deletions src/Libs/External/Scellecs.Morpeh.Extended/Feature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,56 @@

public class Feature(World world, SystemsEngine systemsEngine)
{
public readonly SystemsEngine SystemsEngine = systemsEngine;
public World World { get; set; } = world;

public Feature(World world, SystemsEngine systemsEngine, params IInitializer[] systems) : this(world, systemsEngine)
{
foreach (var system in systems) Add(system);
}

public void OnAwake() => SystemsEngine.Initializers.Initialize();
public void OnAwake()
{
systemsEngine.Initializers.Initialize();
systemsEngine.Systems.Initialize();
systemsEngine.FixedSystems.Initialize();
systemsEngine.CleanupSystems.Initialize();
systemsEngine.LateSystems.Initialize();
systemsEngine.RenderSystems.Initialize();
}

public virtual void OnUpdate(float deltaTime) => SystemsEngine.Systems.Update(deltaTime);
public void OnUpdate(float deltaTime) => systemsEngine.Systems.Update(deltaTime);

public virtual void OnFixedUpdate(float deltaTime) => SystemsEngine.FixedSystems.FixedUpdate(deltaTime);
public void OnFixedUpdate(float deltaTime) => systemsEngine.FixedSystems.FixedUpdate(deltaTime);

public virtual void OnLateUpdate(float deltaTime)
public void OnLateUpdate(float deltaTime)
{
SystemsEngine.LateSystems.LateUpdate(deltaTime);
SystemsEngine.CleanupSystems.CleanupUpdate(deltaTime);
systemsEngine.LateSystems.LateUpdate(deltaTime);
systemsEngine.CleanupSystems.CleanupUpdate(deltaTime);
}

public virtual void OnRender(float deltaTime) => SystemsEngine.RenderSystems.Update(deltaTime);
public void OnRender(float deltaTime) => systemsEngine.RenderSystems.Update(deltaTime);

protected void Add(IInitializer initializer)
{
switch (initializer)
{
case IRenderSystem renderSystem:
SystemsEngine.RenderSystems.AddSystem(renderSystem);
systemsEngine.RenderSystems.AddSystem(renderSystem);
break;
case ICleanupSystem cleanupSystem:
SystemsEngine.CleanupSystems.AddSystem(cleanupSystem);
systemsEngine.CleanupSystems.AddSystem(cleanupSystem);
break;
case ILateSystem lateSystem:
SystemsEngine.LateSystems.AddSystem(lateSystem);
systemsEngine.LateSystems.AddSystem(lateSystem);
break;
case IFixedSystem fixedSystem:
SystemsEngine.FixedSystems.AddSystem(fixedSystem);
systemsEngine.FixedSystems.AddSystem(fixedSystem);
break;
case ISystem system:
SystemsEngine.Systems.AddSystem(system);
systemsEngine.Systems.AddSystem(system);
break;
default:
SystemsEngine.Initializers.AddInitializer(initializer);
systemsEngine.Initializers.AddInitializer(initializer);
break;
}
}
Expand Down
137 changes: 81 additions & 56 deletions src/Libs/Systems/CollisionSystem.cs
Original file line number Diff line number Diff line change
@@ -1,56 +1,81 @@
// using Entitas;
// using Entitas.Extended;
// using Microsoft.Xna.Framework;
// using Serilog;
//
// namespace Systems;
//
// // Input & Collision systems both have to be fixed execute systems,
// // otherwise it'll lead to the desynchronized behaviour.
// public class CollisionSystem : IFixedExecuteSystem
// {
// private readonly IGroup<GameEntity> _group;
// private readonly ILogger _logger;
//
// public CollisionSystem(IGroup<GameEntity> 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);
// }
// }
using Components.Data;
using Microsoft.Xna.Framework;
using Scellecs.Morpeh;
using Vector2 = System.Numerics.Vector2;

namespace Systems;

// Input & Collision systems both have to be fixed execute systems,
// otherwise it'll lead to the desynchronized behaviour.
public class CollisionSystem(World world) : IFixedSystem
{
public World World { get; set; } = world;

public void OnAwake()
{
}

public void OnUpdate(float deltaTime)
{
Filter filter = World.Filter
.With<RectangleColliderComponent>()
.With<TransformComponent>()
.Build();

foreach (Entity e in filter)
{
ref var leftTransform = ref e.GetComponent<TransformComponent>();
ref var leftCollider = ref e.GetComponent<RectangleColliderComponent>();

foreach (Entity other in filter)
{
if (e.Equals(other)) continue;

ref var rightTransform = ref other.GetComponent<TransformComponent>();
ref var rightCollider = ref other.GetComponent<RectangleColliderComponent>();

if (!AreColliding(new(leftTransform, leftCollider),
new(rightTransform, rightCollider))) continue;

if (leftCollider.IsTrigger || rightCollider.IsTrigger) HandleTrigger();
else HandleCollision(ref leftTransform, ref rightTransform);
}
}
}

private static void HandleTrigger()
{
// raise event of triggered
}

private static void HandleCollision(ref TransformComponent left, ref TransformComponent right)
{
left.Velocity = Vector2.Zero;
right.Velocity = Vector2.Zero;
}

private static bool AreColliding(Tuple<TransformComponent, RectangleColliderComponent> first,
Tuple<TransformComponent, RectangleColliderComponent> second)
{
var left = BuildRectangle(first);
var right = BuildRectangle(second);

var intersect = Rectangle.Intersect(left, right);

return !intersect.IsEmpty;

Rectangle BuildRectangle(Tuple<TransformComponent, RectangleColliderComponent> target)
{
(TransformComponent transform, RectangleColliderComponent rectCollider) = target;

return new Rectangle((int)(transform.Position.X + transform.Velocity.X),
(int)(transform.Position.Y + transform.Velocity.Y),
rectCollider.Size.Width,
rectCollider.Size.Height);
}
}

public void Dispose()
{
}
}
2 changes: 1 addition & 1 deletion src/Libs/Systems/InputSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Systems;

public class InputSystem(World world, IInputScanner inputScanner) : ISystem
public class InputSystem(World world, IInputScanner inputScanner) : IFixedSystem
{
public World World { get; set; } = world;

Expand Down

0 comments on commit aa2a23d

Please sign in to comment.