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
OrthogonalCoordinates.cs
1using System.Drawing;
3
5
10internal sealed class OrthogonalCoordinates : ISceneLayerCoordinates
11{
18 public Point GetAnchorPixelAtSceneLayerCoordinates(SceneLayer sceneLayer, PointF layerPoint)
19 {
20 int W = sceneLayer.TileWidth;
21 int H = sceneLayer.TileHeight;
22
23 var origin = sceneLayer.OriginPx;
24
25 int x = (int)(W * layerPoint.X) - origin.X;
26 int y = (int)(H * layerPoint.Y) - origin.Y;
27
28 return new Point(x, y);
29 }
30
37 public PointF GetSceneLayerCoordinatesAtPixel(SceneLayer sceneLayer, PointF pixelPt)
38 {
39 int W = sceneLayer.TileWidth;
40 int H = sceneLayer.TileHeight;
41
42 int originX = sceneLayer.OriginPx.X;
43 int originY = sceneLayer.OriginPx.Y;
44
45 float gx = (pixelPt.X + originX) / W;
46 float gy = (pixelPt.Y + originY) / H;
47
48 return new PointF(gx, gy);
49 }
50
59 public List<SceneLayerTile> GetSceneLayerTilesInPixelRange(SceneLayer sceneLayer, Rectangle worldPixelRange, bool includeOverhang)
60 {
61 var retVal = new List<SceneLayerTile>();
62 var candidateRange = TileBounds.GetTransformedTileCandidateRange(sceneLayer, worldPixelRange, includeOverhang);
63
64 // 1) Find coarse grid bounds via inverse transform (unchanged)
65 PointF ptUL = GetSceneLayerCoordinatesAtPixel(sceneLayer, new PointF(candidateRange.Left, candidateRange.Top));
66 PointF ptBR = GetSceneLayerCoordinatesAtPixel(sceneLayer, new PointF(candidateRange.Right - 1, candidateRange.Bottom - 1));
67
68 int minY = (int)Math.Floor(ptUL.Y) - 1;
69 int maxY = (int)Math.Ceiling(ptBR.Y) + 1;
70 int minX = (int)Math.Floor(ptUL.X) - 1;
71 int maxX = (int)Math.Ceiling(ptBR.X) + 1;
72
73 // 2) Scan candidate grid cells and include if their overhang-aware rect intersects
74 for (int y = minY; y <= maxY; y++)
75 {
76 for (int x = minX; x <= maxX; x++)
77 {
78 var gPt = sceneLayer[x, y];
79 if (gPt == null) continue;
80
81 // Overhang-aware pixel rect
82 var rect = GetPixelRangeForTile(gPt, includeOverhang);
83 if (rect.IntersectsWith(worldPixelRange))
84 retVal.Add(gPt);
85 }
86 }
87
88 return retVal;
89 }
90
97 public Rectangle GetPixelRangeForTile(Tile tile, bool includeOverhang)
98 {
99 var layer = tile.SceneLayer;
100 int W = layer.TileWidth;
101 int H = layer.TileHeight;
102
103 int originX = layer.OriginPx.X;
104 int originY = layer.OriginPx.Y;
105
106 var baseRect = new Rectangle
107 {
108 X = (int)(W * tile.SceneLayerCoordinates.X) - originX,
109 Y = (int)(H * tile.SceneLayerCoordinates.Y) - originY,
110 Width = W,
111 Height = H
112 };
113
114 // Apply full overhang (Left/Top/Right/Bottom)
115 return TileBounds.ApplyTileGeometry(baseRect, tile, includeOverhang);
116 }
117
124 public Rectangle GetPixelRangeForTileList(List<Tile> tileList, bool includeOverhang)
125 {
126 Rectangle retVal = Rectangle.Empty;
127
128 foreach (Tile tile in tileList)
129 {
130 var rect = GetPixelRangeForTile(tile, includeOverhang);
131 retVal = retVal.IsEmpty ? rect : Rectangle.Union(retVal, rect);
132 }
133
134 return retVal;
135 }
136
143 public SceneLayerTile GetAdjacentSceneLayerTile(SceneLayerTile layerPoint, CardinalDirections direction)
144 {
145 SceneLayer sceneLayer = layerPoint.SceneLayer;
146
147 switch (direction)
148 {
149 case CardinalDirections.N:
150 return sceneLayer.ResolveWrappedTile(layerPoint.GridCoordinatesAbs.X, layerPoint.GridCoordinatesAbs.Y - 1);
151
152 case CardinalDirections.NE:
153 return sceneLayer.ResolveWrappedTile(layerPoint.GridCoordinatesAbs.X + 1, layerPoint.GridCoordinatesAbs.Y - 1);
154
155 case CardinalDirections.E:
156 return sceneLayer.ResolveWrappedTile(layerPoint.GridCoordinatesAbs.X + 1, layerPoint.GridCoordinatesAbs.Y);
157
158 case CardinalDirections.SE:
159 return sceneLayer.ResolveWrappedTile(layerPoint.GridCoordinatesAbs.X + 1, layerPoint.GridCoordinatesAbs.Y + 1);
160
161 case CardinalDirections.S:
162 return sceneLayer.ResolveWrappedTile(layerPoint.GridCoordinatesAbs.X, layerPoint.GridCoordinatesAbs.Y + 1);
163
164 case CardinalDirections.SW:
165 return sceneLayer.ResolveWrappedTile(layerPoint.GridCoordinatesAbs.X - 1, layerPoint.GridCoordinatesAbs.Y + 1);
166
167 case CardinalDirections.W:
168 return sceneLayer.ResolveWrappedTile(layerPoint.GridCoordinatesAbs.X - 1, layerPoint.GridCoordinatesAbs.Y);
169
170 case CardinalDirections.NW:
171 return sceneLayer.ResolveWrappedTile(layerPoint.GridCoordinatesAbs.X - 1, layerPoint.GridCoordinatesAbs.Y - 1);
172
173 default:
174 return null;
175 }
176 }
177
184 public Point[] GetPolygonPts(Tile tile, bool includeOverhang)
185 {
186 // Square polygon using the overhang-aware rect
187 var r = GetPixelRangeForTile(tile, includeOverhang);
188 return new[]
189 {
190 new Point(r.Left, r.Top),
191 new Point(r.Right, r.Top),
192 new Point(r.Right, r.Bottom),
193 new Point(r.Left, r.Bottom)
194 };
195 }
196
204 public PointF FindEquivalentSceneLayerCoordinates(PointF valColRow, int xUpperBound, int yUpperBound)
205 {
206 float modX = valColRow.X % (xUpperBound + 1);
207 float modY = valColRow.Y % (yUpperBound + 1);
208
209 if (modX < 0)
210 modX += xUpperBound + 1;
211
212 if (modY < 0)
213 modY += yUpperBound + 1;
214
215 return new PointF(modX, modY);
216 }
217}
Point GridCoordinatesAbs
Gets the absolute grid coordinates of this tile within its parent scene layer as integer values.
override SceneLayer SceneLayer
Gets the parent scene layer that contains this tile.
Point OriginPx
Gets or sets the world-space pixel origin of this layer's (0,0) tile position.
int TileHeight
Gets or sets the height of each tile in this layer, measured in pixels.
SceneLayerTile? ResolveWrappedTile(int column, int row)
Resolves a virtual grid cell to its canonical tile. Only enabled axes wrap; an out-of-range disabled ...
int TileWidth
Gets or sets the width of each tile in this layer, measured in pixels.
CardinalDirections
Represents the eight cardinal and intercardinal directions of the compass.
@ Rectangle
Particles are spawned uniformly within a rectangular area. This is the default distribution.
@ SceneLayer
Performs direct drawing within a scene layer using world-space coordinates.