From 567c422f8cd42eba2437f9a8c2522716a1649be7 Mon Sep 17 00:00:00 2001 From: hazel Date: Mon, 26 Jan 2026 22:04:39 +0100 Subject: celesteia archive, last updated april 9th 2024 Signed-off-by: hazel --- .../systems/physics/PhysicsWorldCollisionSystem.cs | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 source/game/systems/physics/PhysicsWorldCollisionSystem.cs (limited to 'source/game/systems/physics/PhysicsWorldCollisionSystem.cs') diff --git a/source/game/systems/physics/PhysicsWorldCollisionSystem.cs b/source/game/systems/physics/PhysicsWorldCollisionSystem.cs new file mode 100644 index 0000000..ba8da22 --- /dev/null +++ b/source/game/systems/physics/PhysicsWorldCollisionSystem.cs @@ -0,0 +1,83 @@ +using System; +using Celesteia.Game.Components; +using Celesteia.Game.Components.Physics; +using Celesteia.Game.Planets; +using Microsoft.Xna.Framework; +using MonoGame.Extended; +using MonoGame.Extended.Entities; +using MonoGame.Extended.Entities.Systems; + +namespace Celesteia.Game.Systems.Physics { + public class PhysicsWorldCollisionSystem : EntityUpdateSystem { + private ChunkMap _chunkMap; + + public PhysicsWorldCollisionSystem(ChunkMap chunkMap) : base(Aspect.All(typeof(TargetPosition), typeof(PhysicsEntity), typeof(CollisionBox))) { + _chunkMap = chunkMap; + } + + private ComponentMapper transformMapper; + private ComponentMapper targetPositionMapper; + private ComponentMapper physicsEntityMapper; + private ComponentMapper collisionBoxMapper; + + public override void Initialize(IComponentMapperService mapperService) + { + transformMapper = mapperService.GetMapper(); + targetPositionMapper = mapperService.GetMapper(); + physicsEntityMapper = mapperService.GetMapper(); + collisionBoxMapper = mapperService.GetMapper(); + } + + public override void Update(GameTime gameTime) + { + foreach (int entityId in ActiveEntities) { + Transform2 transform = transformMapper.Get(entityId); + TargetPosition targetPosition = targetPositionMapper.Get(entityId); + PhysicsEntity physicsEntity = physicsEntityMapper.Get(entityId); + CollisionBox collisionBox = collisionBoxMapper.Get(entityId); + + collisionBox.Update(targetPosition.Target); + + int minX = (int)MathF.Floor(collisionBox.Bounds.Center.X - (collisionBox.Bounds.Width / 2f)); + int maxX = (int)MathF.Ceiling(collisionBox.Bounds.Center.X + (collisionBox.Bounds.Width / 2f)); + + int minY = (int)MathF.Floor(collisionBox.Bounds.Center.Y - (collisionBox.Bounds.Height / 2f)); + int maxY = (int)MathF.Ceiling(collisionBox.Bounds.Center.Y + (collisionBox.Bounds.Height / 2f)); + + bool collLeft = false; + bool collRight = false; + bool collUp = false; + bool collDown = false; + + for (int i = minX; i < maxX; i++) + for (int j = minY; j < maxY; j++) { + RectangleF? blockBox = _chunkMap.TestBoundingBox(i, j); + if (blockBox.HasValue) { + RectangleF inter = RectangleF.Intersection(collisionBox.Bounds, blockBox.Value); + + if (inter.IsEmpty) continue; + + if (inter.Width < inter.Height) { + collLeft = blockBox.Value.Center.X < collisionBox.Bounds.Center.X; + collRight = blockBox.Value.Center.X > collisionBox.Bounds.Center.X; + + targetPosition.Target += new Vector2(blockBox.Value.Center.X < collisionBox.Bounds.Center.X ? inter.Width : -inter.Width, 0f); + } else { + collUp = blockBox.Value.Center.Y < collisionBox.Bounds.Center.Y; + collDown = blockBox.Value.Center.Y > collisionBox.Bounds.Center.Y; + + targetPosition.Target += new Vector2(0f, blockBox.Value.Center.Y < collisionBox.Bounds.Center.Y ? inter.Height : -inter.Height); + } + + collisionBox.Update(targetPosition.Target); + } + } + + physicsEntity.CollidingDown = collDown; + physicsEntity.CollidingUp = collUp; + physicsEntity.CollidingLeft = collLeft; + physicsEntity.CollidingRight = collRight; + } + } + } +} \ No newline at end of file -- cgit v1.2.3