Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
Loading...
Searching...
No Matches
CollisionResolver.cs
1using System.Drawing;
2
4
10internal sealed class CollisionResolver
11{
12 private readonly List<ColliderInstance> _queryResults = new();
13 private readonly ColliderRegistry _world;
14
18 internal event Action<ICollider, ICollider, Rectangle>? TriggerOverlap;
19
23 internal event Action<ICollider, ICollider, Rectangle>? SolidOverlap;
24
30 internal CollisionResolver(ColliderRegistry world)
31 {
32 _world = world ?? throw new ArgumentNullException(nameof(world));
33 }
34
38 internal void Resolve()
39 {
40 foreach (var mover in _world.DynamicColliders)
41 {
42 if (mover.Owner is not ICollisionMovableEntity movableOwner)
43 continue; // Dynamic list should only contain movable owners
44
45 ResolveForMover(mover, movableOwner);
46 }
47 }
48
49 private void ResolveForMover(ICollider mover, ICollisionMovableEntity movableOwner)
50 {
51 Rectangle rect = mover.Owner.CollisionArea;
52
53 var aabb = Aabb.FromRectangle(rect);
54
55 _world.QueryInstances(
56 aabb,
57 mover.CollisionGroup,
58 mover.CollidesWith,
59 _queryResults,
60 ignore: mover);
61
62 int totalDx = 0;
63 int totalDy = 0;
64 bool hitX = false;
65 bool hitY = false;
66
67 foreach (var instance in _queryResults)
68 {
69 var otherCollider = instance.Collider;
70 var otherRect = instance.BoundsWorldPx.ToRectangle();
71
72 if (!rect.IntersectsWith(otherRect))
73 continue;
74
75 Rectangle overlap = Rectangle.Intersect(rect, otherRect);
76
77 if (overlap.IsEmpty)
78 continue;
79
80 if (mover.ResponseType == CollisionResponseType.Trigger ||
81 otherCollider.ResponseType == CollisionResponseType.Trigger)
82 {
83 TriggerOverlap?.Invoke(mover, otherCollider, overlap);
84 continue;
85 }
86
87 SolidOverlap?.Invoke(mover, otherCollider, overlap);
88
89 float centerX = rect.Left + rect.Width * 0.5f;
90 float centerY = rect.Top + rect.Height * 0.5f;
91 float otherCenterX = otherRect.Left + otherRect.Width * 0.5f;
92 float otherCenterY = otherRect.Top + otherRect.Height * 0.5f;
93
94 int dx = 0;
95 int dy = 0;
96
97 if (overlap.Width < overlap.Height)
98 {
99 dx = centerX < otherCenterX
100 ? -overlap.Width
101 : overlap.Width;
102
103 hitX = true;
104 }
105 else
106 {
107 dy = centerY < otherCenterY
108 ? -overlap.Height
109 : overlap.Height;
110
111 hitY = true;
112 }
113
114 rect.Offset(dx, dy);
115
116 totalDx += dx;
117 totalDy += dy;
118 }
119
120 if (totalDx != 0 || totalDy != 0)
121 {
122 movableOwner.TranslateWorldPx(totalDx, totalDy);
123 }
124
125 if (hitX || hitY)
126 {
127 movableOwner.CancelVelocityComponent(hitX, hitY);
128 }
129 }
130}
@ Rectangle
Particles are spawned uniformly within a rectangular area. This is the default distribution.
CollisionResponseType
Defines how a collider responds to collisions with other colliders.