From 6333d80fd489b391635da87bc67571e9923b49d0 Mon Sep 17 00:00:00 2001 From: HiveBeats Date: Thu, 18 Apr 2024 00:51:12 +0700 Subject: [PATCH] initial commit --- .gitignore | 43 +++++++++++ BakeryGame.csproj | 15 ++++ BakeryGame.sln | 25 +++++++ Components/BlockComponent.cs | 8 ++ Components/CameraComponent.cs | 7 ++ Components/CanCollideComponent.cs | 6 ++ Components/ColorComponent.cs | 7 ++ Components/HealthComponent.cs | 6 ++ Components/MovementComponent.cs | 8 ++ Components/PlayerComponent.cs | 8 ++ Components/PositionComponent.cs | 7 ++ Models/Direction.cs | 9 +++ Models/EnvItem.cs | 15 ++++ Program.cs | 119 ++++++++++++++++++++++++++++++ Systems/BallRenderSystem.cs | 26 +++++++ Systems/BlockRenderSystem.cs | 36 +++++++++ Systems/CameraSystem.cs | 59 +++++++++++++++ Systems/CollisionSystem.cs | 80 ++++++++++++++++++++ Systems/HPRenderSystem.cs | 26 +++++++ Systems/HealthSystem.cs | 28 +++++++ Systems/MovementSystem.cs | 50 +++++++++++++ 21 files changed, 588 insertions(+) create mode 100644 .gitignore create mode 100644 BakeryGame.csproj create mode 100644 BakeryGame.sln create mode 100644 Components/BlockComponent.cs create mode 100644 Components/CameraComponent.cs create mode 100644 Components/CanCollideComponent.cs create mode 100644 Components/ColorComponent.cs create mode 100644 Components/HealthComponent.cs create mode 100644 Components/MovementComponent.cs create mode 100644 Components/PlayerComponent.cs create mode 100644 Components/PositionComponent.cs create mode 100644 Models/Direction.cs create mode 100644 Models/EnvItem.cs create mode 100644 Program.cs create mode 100644 Systems/BallRenderSystem.cs create mode 100644 Systems/BlockRenderSystem.cs create mode 100644 Systems/CameraSystem.cs create mode 100644 Systems/CollisionSystem.cs create mode 100644 Systems/HPRenderSystem.cs create mode 100644 Systems/HealthSystem.cs create mode 100644 Systems/MovementSystem.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f8771ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +*.swp +*.*~ +project.lock.json +.DS_Store +*.pyc +nupkg/ + +# Visual Studio Code +.vscode/ + +# Rider +.idea/ + +# Visual Studio +.vs/ + +# Fleet +.fleet/ + +# Code Rush +.cr/ + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +msbuild.log +msbuild.err +msbuild.wrn \ No newline at end of file diff --git a/BakeryGame.csproj b/BakeryGame.csproj new file mode 100644 index 0000000..fcfa10b --- /dev/null +++ b/BakeryGame.csproj @@ -0,0 +1,15 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + + diff --git a/BakeryGame.sln b/BakeryGame.sln new file mode 100644 index 0000000..9ea0f9c --- /dev/null +++ b/BakeryGame.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BakeryGame", "BakeryGame.csproj", "{037DFA54-0D95-4966-BF63-3010DF217502}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {037DFA54-0D95-4966-BF63-3010DF217502}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {037DFA54-0D95-4966-BF63-3010DF217502}.Debug|Any CPU.Build.0 = Debug|Any CPU + {037DFA54-0D95-4966-BF63-3010DF217502}.Release|Any CPU.ActiveCfg = Release|Any CPU + {037DFA54-0D95-4966-BF63-3010DF217502}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {84E39CDA-0964-48A8-A605-FE09581BEEF1} + EndGlobalSection +EndGlobal diff --git a/Components/BlockComponent.cs b/Components/BlockComponent.cs new file mode 100644 index 0000000..c1b7729 --- /dev/null +++ b/Components/BlockComponent.cs @@ -0,0 +1,8 @@ +using System.Numerics; +using Raylib_cs; +using Scellecs.Morpeh; + +public struct BlockComponent : IComponent +{ + public Vector3 Size; +} \ No newline at end of file diff --git a/Components/CameraComponent.cs b/Components/CameraComponent.cs new file mode 100644 index 0000000..a97984b --- /dev/null +++ b/Components/CameraComponent.cs @@ -0,0 +1,7 @@ +using Raylib_cs; +using Scellecs.Morpeh; + +public struct CameraComponent : IComponent +{ + public Camera2D Camera; +} \ No newline at end of file diff --git a/Components/CanCollideComponent.cs b/Components/CanCollideComponent.cs new file mode 100644 index 0000000..6eb4ed2 --- /dev/null +++ b/Components/CanCollideComponent.cs @@ -0,0 +1,6 @@ +using Scellecs.Morpeh; + +public struct CanCollideComponent : IComponent +{ + public bool CanCollide; +} \ No newline at end of file diff --git a/Components/ColorComponent.cs b/Components/ColorComponent.cs new file mode 100644 index 0000000..af01a7f --- /dev/null +++ b/Components/ColorComponent.cs @@ -0,0 +1,7 @@ +using Raylib_cs; +using Scellecs.Morpeh; + +public struct ColorComponent : IComponent +{ + public Color Color { get; set; } +} \ No newline at end of file diff --git a/Components/HealthComponent.cs b/Components/HealthComponent.cs new file mode 100644 index 0000000..1f963a6 --- /dev/null +++ b/Components/HealthComponent.cs @@ -0,0 +1,6 @@ +using Scellecs.Morpeh; + +public struct HealthComponent : IComponent +{ + public int HealthPoints; +} \ No newline at end of file diff --git a/Components/MovementComponent.cs b/Components/MovementComponent.cs new file mode 100644 index 0000000..646da8b --- /dev/null +++ b/Components/MovementComponent.cs @@ -0,0 +1,8 @@ +using BakeryGame.Models; +using Scellecs.Morpeh; + +public struct MovementComponent : IComponent +{ + public Direction Direction; + public float Speed; +} \ No newline at end of file diff --git a/Components/PlayerComponent.cs b/Components/PlayerComponent.cs new file mode 100644 index 0000000..516bbaa --- /dev/null +++ b/Components/PlayerComponent.cs @@ -0,0 +1,8 @@ +using System.Numerics; +using Raylib_cs; +using Scellecs.Morpeh; + +public struct PlayerComponent : IComponent +{ + public Vector3 Size; +} \ No newline at end of file diff --git a/Components/PositionComponent.cs b/Components/PositionComponent.cs new file mode 100644 index 0000000..221fde5 --- /dev/null +++ b/Components/PositionComponent.cs @@ -0,0 +1,7 @@ +using System.Numerics; +using Scellecs.Morpeh; + +public struct PositionComponent : IComponent +{ + public Vector3 Position; +} \ No newline at end of file diff --git a/Models/Direction.cs b/Models/Direction.cs new file mode 100644 index 0000000..acacd40 --- /dev/null +++ b/Models/Direction.cs @@ -0,0 +1,9 @@ +namespace BakeryGame.Models; + +public enum Direction +{ + Left, + Right, + Up, + Down +} \ No newline at end of file diff --git a/Models/EnvItem.cs b/Models/EnvItem.cs new file mode 100644 index 0000000..b4430d6 --- /dev/null +++ b/Models/EnvItem.cs @@ -0,0 +1,15 @@ +using Raylib_cs; + +public struct EnvItem +{ + public EnvItem(Rectangle rect, Color color, bool canCollide) + { + Rect = rect; + Color = color; + CanCollide = canCollide; + } + + public Rectangle Rect; + public Color Color; + public bool CanCollide; +} \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..14c2552 --- /dev/null +++ b/Program.cs @@ -0,0 +1,119 @@ +// See https://aka.ms/new-console-template for more information + +using System.Numerics; +using BakeryGame.Systems; +using Raylib_cs; +using Scellecs.Morpeh; + +internal class Program +{ + private static World _world; + + private static readonly EnvItem[] _envItems = + { + new EnvItem(new Rectangle(0, 0, 1000, 400), Color.LightGray, false), + new EnvItem(new Rectangle(0, 400, 1000, 200), Color.Gray, true), + new EnvItem(new Rectangle(300, 200, 400, 100), Color.Gray, true), + new EnvItem(new Rectangle(250, 300, 100, 10), Color.Gray, true), + new EnvItem(new Rectangle(650, 300, 100, 10), Color.Gray, true) + }; + + private static Entity CreateBlock() + { + var position = new Vector3( -4.0f, 1.0f, 2.0f ); + var size = new Vector3( 2.0f, 2.0f, 2.0f ); + + var block = _world.CreateEntity(); + block.SetComponent(new BlockComponent { Size = size }); + block.SetComponent(new ColorComponent { Color = Color.Gray }); + block.SetComponent(new PositionComponent(){ Position = position }); + + return block; + } + + private static Entity CreatePlayer() + { + var player = _world.CreateEntity(); + player.SetComponent(new HealthComponent { HealthPoints = 100 }); + player.SetComponent(new PositionComponent { Position = new Vector3(0.0f, 1.0f, 2.0f) }); + player.SetComponent(new MovementComponent() { Speed = 0.1f }); + // ball.SetComponent(new CameraComponent + // { + // Camera = new Cam2qera2D + // { + // Target = new Vector2(800 / 2 + 10.0f, 480 / 2 + 10.0f), + // Offset = new Vector2(800 / 2, 480 / 2), + // Rotation = 0.0f, + // Zoom = 1.0f + // } + // }); + player.SetComponent(new PlayerComponent + { + Size = new Vector3(1.0f, 2.0f, 1.0f ), + }); + + return player; + } + + private static void Main(string[] args) + { + _world = World.Create(); + + Raylib.InitWindow(800, 480, "Hello World"); + + var player = CreatePlayer(); + var block = CreateBlock(); + var camera = new Camera3D(new ( 0.0f, 10.0f, 10.0f ), new( 0.0f, 0.0f, 0.0f ), new ( 0.0f, 1.0f, 0.0f ), 45.0f, 0); + + var healthSystem = new HealthSystem { World = _world }; + var movementSystem = new MovementSystem { World = _world }; + var collisionSystem = new CollisionSystem(_world); + var systemsGroup = _world.CreateSystemsGroup(); + systemsGroup.AddSystem(healthSystem); + systemsGroup.AddSystem(movementSystem); + systemsGroup.AddSystem(collisionSystem); + + systemsGroup.EnableSystem(movementSystem); + systemsGroup.EnableSystem(healthSystem); + systemsGroup.EnableSystem(collisionSystem); + _world.AddSystemsGroup(0, systemsGroup); + + var renderSystemsGroup = _world.CreateSystemsGroup(); + var hpRenreSystem = new HPRenderSystem { World = _world }; + var ballRenderSystem = new BallRenderSystem { World = _world }; + //var cameraSystem = new CameraSystem(_world); + var blockRenderSystem = new BlockRenderSystem(_world); + + renderSystemsGroup.AddSystem(blockRenderSystem); + renderSystemsGroup.AddSystem(ballRenderSystem); + renderSystemsGroup.AddSystem(hpRenreSystem); + //renderSystemsGroup.AddSystem(cameraSystem); + + renderSystemsGroup.EnableSystem(blockRenderSystem); + renderSystemsGroup.EnableSystem(ballRenderSystem); + renderSystemsGroup.EnableSystem(hpRenreSystem); + //renderSystemsGroup.EnableSystem(cameraSystem); + + _world.AddSystemsGroup(1, renderSystemsGroup); + + Raylib.SetTargetFPS(60); + while (!Raylib.WindowShouldClose()) + { + var deltaTime = Raylib.GetFrameTime(); + + Raylib.BeginDrawing(); + Raylib.ClearBackground(Color.White); + Raylib.BeginMode3D(camera); + _world.Update(deltaTime); + Raylib.DrawGrid(10, 1.0f); + _world.CleanupUpdate(deltaTime); + Raylib.EndMode3D(); + Raylib.DrawFPS(100, 10); + _world.LateUpdate(deltaTime); + _world.Commit(); + Raylib.EndDrawing(); + } + + Raylib.CloseWindow(); + } +} \ No newline at end of file diff --git a/Systems/BallRenderSystem.cs b/Systems/BallRenderSystem.cs new file mode 100644 index 0000000..a0f75d4 --- /dev/null +++ b/Systems/BallRenderSystem.cs @@ -0,0 +1,26 @@ +using System.Numerics; +using Raylib_cs; +using Scellecs.Morpeh; + +public class BallRenderSystem : ISystem +{ + private Filter _filter; + public World World { get; set; } + + public void Dispose() + { + } + + public void OnAwake() + { + _filter = World.Filter.With().Build(); + } + + public void OnUpdate(float deltaTime) + { + foreach (var entity in _filter) + { + Raylib.DrawCubeV(entity.GetComponent().Position, entity.GetComponent().Size, Color.Green); + } + } +} \ No newline at end of file diff --git a/Systems/BlockRenderSystem.cs b/Systems/BlockRenderSystem.cs new file mode 100644 index 0000000..eca55e3 --- /dev/null +++ b/Systems/BlockRenderSystem.cs @@ -0,0 +1,36 @@ +using Raylib_cs; +using Scellecs.Morpeh; + +public class BlockRenderSystem : ISystem +{ + private Filter _filter; + + public BlockRenderSystem(World world) + { + World = world; + } + + public World World { get; set; } + + public void Dispose() + { + } + + public void OnAwake() + { + _filter = World.Filter.With().Build(); + } + + public void OnUpdate(float deltaTime) + { + foreach (var item in _filter) + { + var size = item.GetComponent().Size; + var positionComponent = item.GetComponent(); + var itemColorComponent = item.GetComponent(); + + // Draw enemy-box + Raylib.DrawCube(positionComponent.Position, size.X, size.Y, size.Z, itemColorComponent.Color); + } + } +} \ No newline at end of file diff --git a/Systems/CameraSystem.cs b/Systems/CameraSystem.cs new file mode 100644 index 0000000..0f12fef --- /dev/null +++ b/Systems/CameraSystem.cs @@ -0,0 +1,59 @@ +using System.Numerics; +using Raylib_cs; +using Scellecs.Morpeh; + +public class CameraSystem : ISystem +{ + private Filter _filter; + + public CameraSystem(World world) + { + World = world; + } + + public World World { get; set; } + + + public void OnAwake() + { + _filter = World.Filter.With().Build(); + } + + public void OnUpdate(float deltaTime) + { + foreach (var entity in _filter) + { + var position = entity.GetComponent().Position; + ref var cameraComponent = ref entity.GetComponent(); + + ref var camera = ref cameraComponent.Camera; + // Camera target follows player + camera.Target = new Vector2(position.X + 20, position.Y + 20); + + // // Camera rotation controls + // if (IsKeyDown(KEY_A)) camera.rotation--; + // else if (IsKeyDown(KEY_S)) camera.rotation++; + + // Limit camera rotation to 80 degrees (-40 to 40) + if (camera.Rotation > 40) camera.Rotation = 40; + else if (camera.Rotation < -40) camera.Rotation = -40; + + // Camera zoom controls + camera.Zoom += Raylib.GetMouseWheelMove() * 0.05f; + + if (camera.Zoom > 3.0f) camera.Zoom = 3.0f; + else if (camera.Zoom < 0.1f) camera.Zoom = 0.1f; + + // // Camera reset (zoom and rotation) + // if (IsKeyPressed(KEY_R)) + // { + // camera.zoom = 1.0f; + // camera.rotation = 0.0f; + // } + } + } + + public void Dispose() + { + } +} \ No newline at end of file diff --git a/Systems/CollisionSystem.cs b/Systems/CollisionSystem.cs new file mode 100644 index 0000000..40e5118 --- /dev/null +++ b/Systems/CollisionSystem.cs @@ -0,0 +1,80 @@ +using System.Numerics; +using BakeryGame.Models; +using Raylib_cs; +using Scellecs.Morpeh; + +namespace BakeryGame.Systems; + +public class CollisionSystem: ISystem +{ + private Filter _playerFilter; + private Filter _blockFilter; + public World World { get; set; } + + public CollisionSystem(World world) + { + World = world; + } + + public void Dispose() + { + + } + + public void OnAwake() + { + _playerFilter = World.Filter.With().Build(); + _blockFilter = World.Filter.With().Build(); + } + + + public void OnUpdate(float deltaTime) + { + var player = _playerFilter.First(); + ref var playerPosition = ref player.GetComponent(); + var playerSize = player.GetComponent().Size; + var playerMovement = player.GetComponent(); + foreach (var block in _blockFilter) + { + var blockPosition = block.GetComponent().Position; + var blockSize = block.GetComponent().Size; + var blockBounds = new BoundingBox( + new Vector3(blockPosition.X - blockSize.X / 2, blockPosition.Y - blockSize.Y / 2, + blockPosition.Z - blockSize.Z / 2), + new Vector3(blockPosition.X + blockSize.X / 2, blockPosition.Y + blockSize.Y / 2, + blockPosition.Z + blockSize.Z / 2)); + + + var collided = false; + do + { + var playerBounds = new BoundingBox( + new Vector3(playerPosition.Position.X - playerSize.X / 2, playerPosition.Position.Y - playerSize.Y / 2, + playerPosition.Position.Z - playerSize.Z / 2), + new Vector3(playerPosition.Position.X + playerSize.X / 2, playerPosition.Position.Y + playerSize.Y / 2, + playerPosition.Position.Z + playerSize.Z / 2)); + + collided = Raylib.CheckCollisionBoxes(playerBounds, blockBounds); + if (collided) + { + var delta = playerMovement.Speed / 2; + switch (playerMovement.Direction) + { + case Direction.Left: + playerPosition.Position.X += delta; + break; + case Direction.Right: + playerPosition.Position.X -= delta; + break; + case Direction.Up: + playerPosition.Position.Z += delta; + break; + case Direction.Down: + playerPosition.Position.Z -= delta; + break; + } + } + } while (collided); + } + } +} \ No newline at end of file diff --git a/Systems/HPRenderSystem.cs b/Systems/HPRenderSystem.cs new file mode 100644 index 0000000..ef5935a --- /dev/null +++ b/Systems/HPRenderSystem.cs @@ -0,0 +1,26 @@ +using Raylib_cs; +using Scellecs.Morpeh; + +public class HPRenderSystem : ILateSystem +{ + private Filter _filter; + public World World { get; set; } + + public void Dispose() + { + } + + public void OnAwake() + { + _filter = World.Filter.With().Build(); + } + + public void OnUpdate(float deltaTime) + { + foreach (var entity in _filter) + { + var healthComponent = entity.GetComponent(); + Raylib.DrawText($"HP: {healthComponent.HealthPoints}", 12, 12, 20, Color.Black); + } + } +} \ No newline at end of file diff --git a/Systems/HealthSystem.cs b/Systems/HealthSystem.cs new file mode 100644 index 0000000..fd96d4b --- /dev/null +++ b/Systems/HealthSystem.cs @@ -0,0 +1,28 @@ +using Raylib_cs; +using Scellecs.Morpeh; + +public sealed class HealthSystem : ISystem +{ + private Filter filter; + + public World World { get; set; } + + public void Dispose() + { + } + + public void OnAwake() + { + filter = World.Filter.With().Build(); + } + + public void OnUpdate(float deltaTime) + { + foreach (var entity in filter) + { + ref var healthComponent = ref entity.GetComponent(); + if (Raylib.IsKeyDown(KeyboardKey.Enter)) + healthComponent.HealthPoints++; + } + } +} \ No newline at end of file diff --git a/Systems/MovementSystem.cs b/Systems/MovementSystem.cs new file mode 100644 index 0000000..30f49ff --- /dev/null +++ b/Systems/MovementSystem.cs @@ -0,0 +1,50 @@ +using BakeryGame.Models; +using Raylib_cs; +using Scellecs.Morpeh; + +public sealed class MovementSystem : ISystem +{ + private Filter _filter; + public World World { get; set; } + + public void Dispose() + { + } + + public void OnAwake() + { + _filter = World.Filter.With().Build(); + } + + public void OnUpdate(float deltaTime) + { + foreach (var entity in _filter) + { + ref var positionComponent = ref entity.GetComponent(); + ref var directionComponent = ref entity.GetComponent(); + if (Raylib.IsKeyDown(KeyboardKey.Right)) + { + positionComponent.Position.X += directionComponent.Speed; + directionComponent.Direction = Direction.Right; + } + + if (Raylib.IsKeyDown(KeyboardKey.Left)) + { + positionComponent.Position.X -= directionComponent.Speed; + directionComponent.Direction = Direction.Left; + } + + if (Raylib.IsKeyDown(KeyboardKey.Up)) + { + positionComponent.Position.Z -= directionComponent.Speed; + directionComponent.Direction = Direction.Up; + } + + if (Raylib.IsKeyDown(KeyboardKey.Down)) + { + positionComponent.Position.Z += directionComponent.Speed; + directionComponent.Direction = Direction.Down; + } + } + } +} \ No newline at end of file