From f4dff2a6df51522e5c481dd3fbf094038851bc57 Mon Sep 17 00:00:00 2001 From: Mikkel Mouridsen Date: Sun, 13 Nov 2022 00:45:55 +0100 Subject: [PATCH 1/2] Added Simple Physics and a simple platformer example --- .../ECS/Components/Movement2DComponent.cs | 4 +- .../ECS/Components/Physics/AABBComponent.cs | 13 +++ .../Physics/PhysicsMoverComponent.cs | 15 +++ SignE.Core/ECS/GameSystem.cs | 1 + SignE.Core/ECS/Systems/Animator2DSystem.cs | 5 + SignE.Core/ECS/Systems/Camera2DSystem.cs | 5 + SignE.Core/ECS/Systems/Draw2DSystem.cs | 5 + SignE.Core/ECS/Systems/Movement2DSystem.cs | 33 ++++--- .../Systems/Physics/SimplePhysicsSystem.cs | 93 +++++++++++++++++++ SignE.Core/ECS/Systems/YSortSystem.cs | 5 + SignE.Core/ECS/World.cs | 10 ++ SignE.ExampleGame/ECS/Systems/PlayerSystem.cs | 12 ++- .../ECS/Systems/SmoothFollowSystem.cs | 5 + .../Resources/Levels/sandbox.level | 47 +++++++++- SignE.ExampleGame/imgui.ini | 12 +-- SignE.Platforms.Raylib/RaylibGame.cs | 3 + .../ECS/Systems/EditorControlSystem.cs | 5 + Signe.Editor/ECS/Systems/EditorDrawSystem.cs | 5 + 18 files changed, 249 insertions(+), 29 deletions(-) create mode 100644 SignE.Core/ECS/Components/Physics/AABBComponent.cs create mode 100644 SignE.Core/ECS/Components/Physics/PhysicsMoverComponent.cs create mode 100644 SignE.Core/ECS/Systems/Physics/SimplePhysicsSystem.cs diff --git a/SignE.Core/ECS/Components/Movement2DComponent.cs b/SignE.Core/ECS/Components/Movement2DComponent.cs index 2f29aa0..f2b1648 100644 --- a/SignE.Core/ECS/Components/Movement2DComponent.cs +++ b/SignE.Core/ECS/Components/Movement2DComponent.cs @@ -3,8 +3,8 @@ namespace SignE.Core.ECS.Components public class Movement2DComponent : IComponent { public float Speed { get; set; } = 50.0f; - public float VelX { get; set; } - public float VelY { get; set; } + public float JumpSpeed { get; set; } = 5.0f; + public void InitComponent() { diff --git a/SignE.Core/ECS/Components/Physics/AABBComponent.cs b/SignE.Core/ECS/Components/Physics/AABBComponent.cs new file mode 100644 index 0000000..e8d70d4 --- /dev/null +++ b/SignE.Core/ECS/Components/Physics/AABBComponent.cs @@ -0,0 +1,13 @@ +namespace SignE.Core.ECS.Components.Physics +{ + public class AABBComponent : IComponent + { + public int Width { get; set; } + public int Height { get; set; } + + public void InitComponent() + { + + } + } +} \ No newline at end of file diff --git a/SignE.Core/ECS/Components/Physics/PhysicsMoverComponent.cs b/SignE.Core/ECS/Components/Physics/PhysicsMoverComponent.cs new file mode 100644 index 0000000..1222e94 --- /dev/null +++ b/SignE.Core/ECS/Components/Physics/PhysicsMoverComponent.cs @@ -0,0 +1,15 @@ +namespace SignE.Core.ECS.Components.Physics +{ + public class PhysicsMoverComponent : IComponent + { + public float VelX { get; set; } + public float VelY { get; set; } + + public float Gravity { get; set; } = 200.0f; + + public void InitComponent() + { + + } + } +} \ No newline at end of file diff --git a/SignE.Core/ECS/GameSystem.cs b/SignE.Core/ECS/GameSystem.cs index fd8d504..0c1c838 100644 --- a/SignE.Core/ECS/GameSystem.cs +++ b/SignE.Core/ECS/GameSystem.cs @@ -9,6 +9,7 @@ public abstract class GameSystem protected List Entities; public abstract void UpdateSystem(); + public abstract void LateUpdateSystem(); public abstract void DrawSystem(); public abstract void GetEntities(World world); } diff --git a/SignE.Core/ECS/Systems/Animator2DSystem.cs b/SignE.Core/ECS/Systems/Animator2DSystem.cs index 5af44d9..45ba593 100644 --- a/SignE.Core/ECS/Systems/Animator2DSystem.cs +++ b/SignE.Core/ECS/Systems/Animator2DSystem.cs @@ -40,6 +40,11 @@ public override void UpdateSystem() } } + public override void LateUpdateSystem() + { + + } + public override void DrawSystem() { diff --git a/SignE.Core/ECS/Systems/Camera2DSystem.cs b/SignE.Core/ECS/Systems/Camera2DSystem.cs index 6a050e4..81c49da 100644 --- a/SignE.Core/ECS/Systems/Camera2DSystem.cs +++ b/SignE.Core/ECS/Systems/Camera2DSystem.cs @@ -16,6 +16,11 @@ public override void UpdateSystem() SignE.Graphics.Camera2D.Y = pos.Y; } + public override void LateUpdateSystem() + { + + } + public override void DrawSystem() { diff --git a/SignE.Core/ECS/Systems/Draw2DSystem.cs b/SignE.Core/ECS/Systems/Draw2DSystem.cs index 5f0a0d2..d716729 100644 --- a/SignE.Core/ECS/Systems/Draw2DSystem.cs +++ b/SignE.Core/ECS/Systems/Draw2DSystem.cs @@ -18,6 +18,11 @@ public override void UpdateSystem() } + public override void LateUpdateSystem() + { + + } + public override void DrawSystem() { DrawCircles(); diff --git a/SignE.Core/ECS/Systems/Movement2DSystem.cs b/SignE.Core/ECS/Systems/Movement2DSystem.cs index 388d337..b87297a 100644 --- a/SignE.Core/ECS/Systems/Movement2DSystem.cs +++ b/SignE.Core/ECS/Systems/Movement2DSystem.cs @@ -1,5 +1,6 @@ using System.Linq; using SignE.Core.ECS.Components; +using SignE.Core.ECS.Components.Physics; using SignE.Core.Extensions; using SignE.Core.Input; @@ -11,29 +12,27 @@ public override void UpdateSystem() { foreach (var entity in Entities) { - var pos = entity.GetComponent(); + var mover = entity.GetComponent(); var movement = entity.GetComponent(); - movement.VelX = 0; - movement.VelY = 0; - - if (SignE.Input.IsKeyDown(Key.W)) - movement.VelY = -(movement.Speed * SignE.Graphics.DeltaTime); - - if (SignE.Input.IsKeyDown(Key.S)) - movement.VelY = (movement.Speed * SignE.Graphics.DeltaTime); - + mover.VelX = 0; + if (SignE.Input.IsKeyDown(Key.D)) - movement.VelX = (movement.Speed * SignE.Graphics.DeltaTime); - - if (SignE.Input.IsKeyDown(Key.A)) - movement.VelX = -(movement.Speed * SignE.Graphics.DeltaTime); + mover.VelX = movement.Speed; - pos.X += movement.VelX; - pos.Y += movement.VelY; + if (SignE.Input.IsKeyDown(Key.A)) + mover.VelX = -movement.Speed; + + if (SignE.Input.IsKeyPressed(Key.SPACE)) + mover.VelY -= movement.JumpSpeed; } } + public override void LateUpdateSystem() + { + + } + public override void DrawSystem() { @@ -42,7 +41,7 @@ public override void DrawSystem() public override void GetEntities(World world) { Entities = world.Entities - .WithComponent() + .WithComponent() .WithComponent() .ToList(); } diff --git a/SignE.Core/ECS/Systems/Physics/SimplePhysicsSystem.cs b/SignE.Core/ECS/Systems/Physics/SimplePhysicsSystem.cs new file mode 100644 index 0000000..4410158 --- /dev/null +++ b/SignE.Core/ECS/Systems/Physics/SimplePhysicsSystem.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SignE.Core.ECS.Components; +using SignE.Core.ECS.Components.Physics; +using SignE.Core.Extensions; + +namespace SignE.Core.ECS.Systems.Physics +{ + public class SimplePhysicsSystem : GameSystem + { + + private List _simpleMovers; + + public override void UpdateSystem() + { + + } + + public override void LateUpdateSystem() + { + foreach (var entity in _simpleMovers) + { + var mover = entity.GetComponent(); + var entityPos = entity.GetComponent(); + var aabb = entity.GetComponent(); + + mover.VelY += mover.Gravity; + + var posX = new Position2DComponent + { + X = entityPos.X + mover.VelX * SignE.Graphics.DeltaTime, + Y = entityPos.Y + }; + + var posY = new Position2DComponent + { + X = entityPos.X, + Y = entityPos.Y + mover.VelY * SignE.Graphics.DeltaTime + }; + + foreach (var other in Entities) + { + if (entity == other) + continue; + + var otherPos = other.GetComponent(); + var otherAabb = other.GetComponent(); + + if (CheckCollision(posX, aabb, otherPos, otherAabb)) + mover.VelX = 0; + + if (CheckCollision(posY, aabb, otherPos, otherAabb)) + mover.VelY = 0; + } + + entityPos.X += mover.VelX * SignE.Graphics.DeltaTime; + entityPos.Y += mover.VelY * SignE.Graphics.DeltaTime; + } + } + + private static bool CheckCollision(Position2DComponent aPos, AABBComponent aAabb, Position2DComponent bPos, AABBComponent bAabb) + { + var aIsToTheRightOfB = aPos.X - aAabb.Width / 2 > bPos.X + bAabb.Width / 2; + var aIsToTheLeftOfB = aPos.X + aAabb.Width / 2 < bPos.X - bAabb.Width / 2; + var aIsAboveB = aPos.Y + aAabb.Height / 2 < bPos.Y - bAabb.Height / 2; + var aIsBelowB = aPos.Y - aAabb.Height / 2 > bPos.Y + bAabb.Height / 2; + + return !(aIsToTheRightOfB + || aIsToTheLeftOfB + || aIsAboveB + || aIsBelowB); + } + + public override void DrawSystem() + { + foreach (var entity in Entities) + { + var pos = entity.GetComponent(); + var aabb = entity.GetComponent(); + + SignE.Graphics.DrawRectangle(pos.X, pos.Y, aabb.Width, aabb.Height, false); + } + } + + public override void GetEntities(World world) + { + _simpleMovers = world.Entities.WithComponent().WithComponent() + .WithComponent().ToList(); + Entities = world.Entities.WithComponent().WithComponent().ToList(); + } + } +} \ No newline at end of file diff --git a/SignE.Core/ECS/Systems/YSortSystem.cs b/SignE.Core/ECS/Systems/YSortSystem.cs index 68b3f71..9ce28bb 100644 --- a/SignE.Core/ECS/Systems/YSortSystem.cs +++ b/SignE.Core/ECS/Systems/YSortSystem.cs @@ -17,6 +17,11 @@ public override void UpdateSystem() } } + public override void LateUpdateSystem() + { + + } + public override void DrawSystem() { diff --git a/SignE.Core/ECS/World.cs b/SignE.Core/ECS/World.cs index 04eec70..fe05c32 100644 --- a/SignE.Core/ECS/World.cs +++ b/SignE.Core/ECS/World.cs @@ -58,6 +58,14 @@ public void UpdateSystems() } } + public void LateUpdateSystems() + { + foreach (var gameSystem in _systems) + { + gameSystem.LateUpdateSystem(); + } + } + public void DrawSystems() { foreach (var gameSystem in _systems) @@ -70,5 +78,7 @@ public List GetAllSystems() { return _systems; } + + } } \ No newline at end of file diff --git a/SignE.ExampleGame/ECS/Systems/PlayerSystem.cs b/SignE.ExampleGame/ECS/Systems/PlayerSystem.cs index a22ec24..86c345f 100644 --- a/SignE.ExampleGame/ECS/Systems/PlayerSystem.cs +++ b/SignE.ExampleGame/ECS/Systems/PlayerSystem.cs @@ -2,6 +2,7 @@ using System.Linq; using SignE.Core.ECS; using SignE.Core.ECS.Components; +using SignE.Core.ECS.Components.Physics; using SignE.Core.ECS.Systems; using SignE.Core.Extensions; using SignE.Core.Input; @@ -16,7 +17,7 @@ public override void UpdateSystem() foreach (var entity in Entities) { var player = entity.GetComponent(); - var movement = entity.GetComponent(); + var movement = entity.GetComponent(); var sprite = entity.GetComponent(); var animator = entity.GetComponent(); @@ -47,7 +48,12 @@ public override void UpdateSystem() } } - private void UpdateIdleRunning(Movement2DComponent movement, PlayerComponent player) + public override void LateUpdateSystem() + { + + } + + private void UpdateIdleRunning(PhysicsMoverComponent movement, PlayerComponent player) { if (movement.VelX != 0 || movement.VelY != 0) player.PlayerState = PlayerState.Running; @@ -86,7 +92,7 @@ public override void GetEntities(World world) { Entities = world.Entities .WithComponent() - .WithComponent() + .WithComponent() .WithComponent() .WithComponent().ToList(); } diff --git a/SignE.ExampleGame/ECS/Systems/SmoothFollowSystem.cs b/SignE.ExampleGame/ECS/Systems/SmoothFollowSystem.cs index 04ac231..da6870a 100644 --- a/SignE.ExampleGame/ECS/Systems/SmoothFollowSystem.cs +++ b/SignE.ExampleGame/ECS/Systems/SmoothFollowSystem.cs @@ -27,6 +27,11 @@ public override void UpdateSystem() } } + public override void LateUpdateSystem() + { + + } + public override void DrawSystem() { diff --git a/SignE.ExampleGame/Resources/Levels/sandbox.level b/SignE.ExampleGame/Resources/Levels/sandbox.level index 99b8d96..e950b6d 100644 --- a/SignE.ExampleGame/Resources/Levels/sandbox.level +++ b/SignE.ExampleGame/Resources/Levels/sandbox.level @@ -202,8 +202,18 @@ { "$type": "SignE.Core.ECS.Components.Movement2DComponent, SignE.Core", "Speed": 100.0, + "JumpSpeed": 300.0 + }, + { + "$type": "SignE.Core.ECS.Components.Physics.AABBComponent, SignE.Core", + "Width": 30, + "Height": 60 + }, + { + "$type": "SignE.Core.ECS.Components.Physics.PhysicsMoverComponent, SignE.Core", "VelX": 0.0, - "VelY": 0.0 + "VelY": 0.0, + "Gravity": 0.5 }, { "$type": "SignE.ExampleGame.ECS.Components.PlayerComponent, SignE.ExampleGame", @@ -297,6 +307,32 @@ "FlipX": false, "FlipY": false, "IsSpritesheet": false + }, + { + "$type": "SignE.Core.ECS.Components.Physics.AABBComponent, SignE.Core", + "Width": 500, + "Height": 360 + } + ] + }, + { + "Id": "3982be64-3340-42db-97c1-f631e417adbc", + "Components": [ + { + "$type": "SignE.Core.ECS.Components.Position2DComponent, SignE.Core", + "Y": 0.0, + "X": 0.0 + }, + { + "$type": "SignE.Core.ECS.Components.Camera2DComponent, SignE.Core" + }, + { + "$type": "SignE.ExampleGame.ECS.Components.SmoothFollowComponent, SignE.ExampleGame", + "Target": { + "Id": "1c870102-4b69-426b-9377-e9e0dd6281c1" + }, + "Smooth": 0.001, + "NewPropertyHihi": 0.0 } ] } @@ -313,6 +349,15 @@ }, { "$type": "SignE.ExampleGame.ECS.Systems.PlayerSystem, SignE.ExampleGame" + }, + { + "$type": "SignE.ExampleGame.ECS.Systems.SmoothFollowSystem, SignE.ExampleGame" + }, + { + "$type": "SignE.Core.ECS.Systems.Physics.SimplePhysicsSystem, SignE.Core" + }, + { + "$type": "SignE.Core.ECS.Systems.Camera2DSystem, SignE.Core" } ] } \ No newline at end of file diff --git a/SignE.ExampleGame/imgui.ini b/SignE.ExampleGame/imgui.ini index 885bb45..1b37b90 100644 --- a/SignE.ExampleGame/imgui.ini +++ b/SignE.ExampleGame/imgui.ini @@ -42,7 +42,7 @@ Collapsed=0 [Window][Levels] Pos=372,27 -Size=1540,745 +Size=1540,809 Collapsed=0 DockId=0x00000005,0 @@ -65,8 +65,8 @@ Collapsed=0 DockId=0x00000008,1 [Window][Asset Browser] -Pos=372,774 -Size=1540,298 +Pos=372,838 +Size=1540,234 Collapsed=0 DockId=0x00000006,0 @@ -86,7 +86,7 @@ Size=416,475 Collapsed=0 [Window][No Project Open] -Pos=45,60 +Pos=45,59 Size=465,71 Collapsed=0 @@ -101,6 +101,6 @@ DockSpace ID=0xB14CFBAD Window=0x1D5E63D6 Pos=8,27 Size=1904,1045 Split=X Se DockNode ID=0x00000003 Parent=0x00000001 SizeRef=325,525 Selected=0x30D91616 DockNode ID=0x00000008 Parent=0x00000001 SizeRef=325,518 Selected=0xE7039252 DockNode ID=0x00000002 Parent=0xB14CFBAD SizeRef=1540,1045 Split=Y - DockNode ID=0x00000005 Parent=0x00000002 SizeRef=1904,745 CentralNode=1 Selected=0xAB8F3D9C - DockNode ID=0x00000006 Parent=0x00000002 SizeRef=1904,298 Selected=0x6F7CD859 + DockNode ID=0x00000005 Parent=0x00000002 SizeRef=1904,809 CentralNode=1 Selected=0xAB8F3D9C + DockNode ID=0x00000006 Parent=0x00000002 SizeRef=1904,234 Selected=0x6F7CD859 diff --git a/SignE.Platforms.Raylib/RaylibGame.cs b/SignE.Platforms.Raylib/RaylibGame.cs index 995bcc6..96f63fb 100644 --- a/SignE.Platforms.Raylib/RaylibGame.cs +++ b/SignE.Platforms.Raylib/RaylibGame.cs @@ -40,6 +40,9 @@ protected override void Loop() if (Core.SignE.LevelManager.CurrentLevel != null && !Core.SignE.LevelManager.CurrentLevel.Paused) Core.SignE.LevelManager.CurrentLevel.World.UpdateSystems(); + + if (Core.SignE.LevelManager.CurrentLevel != null && !Core.SignE.LevelManager.CurrentLevel.Paused) + Core.SignE.LevelManager.CurrentLevel.World.LateUpdateSystems(); if (RenderGameToTexture) { diff --git a/Signe.Editor/ECS/Systems/EditorControlSystem.cs b/Signe.Editor/ECS/Systems/EditorControlSystem.cs index 0a5c386..fc7d060 100644 --- a/Signe.Editor/ECS/Systems/EditorControlSystem.cs +++ b/Signe.Editor/ECS/Systems/EditorControlSystem.cs @@ -22,6 +22,11 @@ public override void UpdateSystem() camera.Y -= dy / camera.Zoom; } + public override void LateUpdateSystem() + { + + } + public override void DrawSystem() { diff --git a/Signe.Editor/ECS/Systems/EditorDrawSystem.cs b/Signe.Editor/ECS/Systems/EditorDrawSystem.cs index 4855229..cf78b07 100644 --- a/Signe.Editor/ECS/Systems/EditorDrawSystem.cs +++ b/Signe.Editor/ECS/Systems/EditorDrawSystem.cs @@ -13,6 +13,11 @@ public override void UpdateSystem() } + public override void LateUpdateSystem() + { + + } + public override void DrawSystem() { SignE.Core.SignE.Graphics.Draw2DGrid(); From 40a51c11773bf3020f59ed65a92a0753c119346f Mon Sep 17 00:00:00 2001 From: Mikkel Mouridsen Date: Sun, 13 Nov 2022 01:34:27 +0100 Subject: [PATCH 2/2] fix(editor): editor spritesheet selection drawing now draws tile rectangle instead of whole sprite --- Signe.Editor/ECS/Systems/EditorDrawSystem.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Signe.Editor/ECS/Systems/EditorDrawSystem.cs b/Signe.Editor/ECS/Systems/EditorDrawSystem.cs index cf78b07..2bac4b6 100644 --- a/Signe.Editor/ECS/Systems/EditorDrawSystem.cs +++ b/Signe.Editor/ECS/Systems/EditorDrawSystem.cs @@ -33,7 +33,10 @@ private void DrawSelectedEntity() if (selectedEntity.HasComponent()) { var sprite = _editor.SelectedEntity.GetComponent(); - SignE.Core.SignE.Graphics.DrawRectangle(pos.X, pos.Y, (int)sprite.Sprite.Width + 2, (int)sprite.Sprite.Height + 2, false); + if (sprite.IsSpritesheet) + SignE.Core.SignE.Graphics.DrawRectangle(pos.X, pos.Y, (int)sprite.TileW + 2, (int)sprite.TileH + 2, false); + else + SignE.Core.SignE.Graphics.DrawRectangle(pos.X, pos.Y, (int)sprite.Sprite.Width + 2, (int)sprite.Sprite.Height + 2, false); } else if (selectedEntity.HasComponent()) {