Jypeli 10
The simple game programming library
AbstractTileMap.cs
Siirry tämän tiedoston dokumentaatioon.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5namespace Jypeli
6{
12 public abstract class AbstractTileMap<TileType>
13 {
14#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
15 public delegate void TileMethod(Vector position, double width, double height);
16 public delegate void TileMethod<T1>(Vector position, double width, double height, T1 p1);
17 public delegate void TileMethod<T1, T2>(Vector position, double width, double height, T1 p1, T2 p2);
18 public delegate void TileMethod<T1, T2, T3>(Vector position, double width, double height, T1 p1, T2 p2, T3 p3);
19 public delegate void TileMethod<T1, T2, T3, T4>(Vector position, double width, double height, T1 p1, T2 p2, T3 p3, T4 p4);
20 public delegate void TileMethod<T1, T2, T3, T4, T5>(Vector position, double width, double height, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5);
21 public delegate void TileMethod<T1, T2, T3, T4, T5, T6>(Vector position, double width, double height, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6);
22
23 public delegate void RouteMethod(List<Vector> route, double width, double height);
24
25#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
26
28 {
30 public int row;
31 public int col;
32
33 public TileMethodCall(TileMethod m, int row, int col)
34 {
35 this.method = m;
36 this.row = row;
37 this.col = col;
38 }
39
40 public void Invoke(double tileWidth, double tileHeight)
41 {
42 double realX = Game.Instance.Level.Left + (col * tileWidth) + (tileWidth / 2);
43 double realY = Game.Instance.Level.Top - (row * tileHeight) - (tileHeight / 2);
44 method(new Vector(realX, realY), tileWidth, tileHeight);
45 }
46 }
47
48 private List<TileMethodCall> optimized = new List<TileMethodCall>();
49
53 protected Dictionary<TileType, TileMethod> legend = new Dictionary<TileType, TileMethod>();
54
58 protected TileType[,] tiles;
59
63 protected abstract TileType Null { get; }
64
70 public AbstractTileMap(TileType[,] tiles)
71 {
72 if (tiles.GetLength(0) == 0 || tiles.GetLength(1) == 0)
73 throw new ArgumentException("All dimensions of tiles must be at least 1");
74
75 this.tiles = tiles;
76 }
77
81 public int RowCount
82 {
83 get { return tiles.GetLength(0); }
84 }
85
89 public int ColumnCount
90 {
91 get { return tiles.GetLength(1); }
92 }
93
101 public void SetTileMethod(TileType tileSymbol, TileMethod f)
102 {
103 legend[tileSymbol] = f;
104 }
105
115 public void SetTileMethod<T1>(TileType tileSymbol, TileMethod<T1> f, T1 p1)
116 {
117 legend[tileSymbol] = delegate (Vector p, double w, double h) { f(p, w, h, p1); };
118 }
119
131 public void SetTileMethod<T1, T2>(TileType tileSymbol, TileMethod<T1, T2> f, T1 p1, T2 p2)
132 {
133 legend[tileSymbol] = delegate (Vector p, double w, double h) { f(p, w, h, p1, p2); };
134 }
135
149 public void SetTileMethod<T1, T2, T3>(TileType tileSymbol, TileMethod<T1, T2, T3> f, T1 p1, T2 p2, T3 p3)
150 {
151 legend[tileSymbol] = delegate (Vector p, double w, double h) { f(p, w, h, p1, p2, p3); };
152 }
153
169 public void SetTileMethod<T1, T2, T3, T4>(TileType tileSymbol, TileMethod<T1, T2, T3, T4> f, T1 p1, T2 p2, T3 p3, T4 p4)
170 {
171 legend[tileSymbol] = delegate (Vector p, double w, double h) { f(p, w, h, p1, p2, p3, p4); };
172 }
173
191 public void SetTileMethod<T1, T2, T3, T4, T5>(TileType tileSymbol, TileMethod<T1, T2, T3, T4, T5> f, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
192 {
193 legend[tileSymbol] = delegate (Vector p, double w, double h) { f(p, w, h, p1, p2, p3, p4, p5); };
194 }
195
215 public void SetTileMethod<T1, T2, T3, T4, T5, T6>(TileType tileSymbol, TileMethod<T1, T2, T3, T4, T5, T6> f, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6)
216 {
217 legend[tileSymbol] = delegate (Vector p, double w, double h) { f(p, w, h, p1, p2, p3, p4, p5, p6); };
218 }
219
229 public void SetRouteMethod(RouteMethod f, params TileType[] tileSymbols)
230 {
231 if (tileSymbols == null || tileSymbols.Length < 1)
232 throw new ArgumentException("Pass at least one tile symbol!");
233
234 Vector[] vectorTable = new Vector[tileSymbols.Length];
235 int vectorsAdded = 0;
236
237 for (int i = 0; i < tileSymbols.Length; i++)
238 {
239 int index = i;
240 legend[tileSymbols[i]] = delegate (Vector p, double w, double h)
241 {
242 vectorTable[index] = p;
243 if (++vectorsAdded >= tileSymbols.Length)
244 f(vectorTable.ToList(), w, h);
245 };
246 }
247 }
248
256 public void Execute()
257 {
258 double h = Game.Instance.Level.Height / tiles.GetLength(0);
259 double w = Game.Instance.Level.Width / tiles.GetLength(1);
260 Execute(w, h);
261 }
262
272 public void Execute(double tileWidth, double tileHeight)
273 {
274 Game game = Game.Instance;
275 int width = tiles.GetLength(1);
276 int height = tiles.GetLength(0);
277
278 game.Level.Width = width * tileWidth;
279 game.Level.Height = height * tileHeight;
280
281 foreach (var m in optimized)
282 {
283 m.Invoke(tileWidth, tileHeight);
284 }
285
286 for (int y = height - 1; y >= 0; y--)
287 {
288 for (int x = 0; x < width; x++)
289 {
290 TileMethod method = GetMethodForSymbol(tiles[y, x]);
291
292 if (method != null)
293 {
294 double realX = game.Level.Left + (x * tileWidth) + (tileWidth / 2);
295 double realY = game.Level.Top - (y * tileHeight) - (tileHeight / 2);
296 method(new Vector(realX, realY), tileWidth, tileHeight);
297 }
298 }
299 }
300 }
301
307 protected TileMethod GetMethodForSymbol(TileType symbol)
308 {
309 if (symbol.Equals(Null)) return null;
310
311 foreach (var key in legend.Keys)
312 {
313 if (SymbolEquals(key, symbol))
314 return legend[key];
315 }
316
317 return null;
318 }
319
326 protected virtual bool SymbolEquals(TileType a, TileType b)
327 {
328 return a.Equals(b);
329 }
330
336 public void Optimize(params TileType[] symbols)
337 {
338 for (int i = 0; i < symbols.Length; i++)
339 Optimize(symbols[i]);
340 }
341
347 public void Optimize(TileType sym)
348 {
349 TileMethod method = GetMethodForSymbol(sym);
350
351 if (method == null)
352 throw new ArgumentException("Symbol " + sym + " not added, cannot optimize.");
353
354 for (int row = 0; row < RowCount; row++)
355 {
356 for (int col = 0; col < ColumnCount; col++)
357 {
358 int w, h;
359 GetGreatestMatchingRectangle(sym, row, col, out w, out h);
360
361 if (w > 0 && h > 0)
362 {
363 TileMethod newMethod = delegate (Vector oldPos, double oldWidth, double oldHeight)
364 {
365 Vector oldAdjust = new Vector(-oldWidth, oldHeight);
366 Vector newAdjust = new Vector(oldWidth * w, -oldHeight * h);
367 Vector newPos = oldPos + (oldAdjust + newAdjust) / 2;
368 method(newPos, oldWidth * w, oldHeight * h);
369 };
370 optimized.Add(new TileMethodCall(newMethod, row, col));
371 SetArea(row, col, w, h, Null);
372 col += w;
373 }
374 }
375 }
376 }
377
378 private void GetGreatestMatchingRectangle(TileType sym, int row, int col, out int width, out int height)
379 {
380 for (width = 0; width < ColumnCount - col; width++)
381 {
382 if (!SymbolEquals(tiles[row, col + width], sym))
383 break;
384 }
385
386 if (width == 0)
387 {
388 height = 0;
389 return;
390 }
391
392 for (height = 1; height < RowCount - row; height++)
393 {
394 if (!RowEquals(row + height, col, width, sym))
395 break;
396 }
397 }
398
399 private bool RowEquals(int row, int col, int length, TileType sym)
400 {
401 for (int i = col; i < col + length; i++)
402 {
403 if (!SymbolEquals(tiles[row, i], sym)) return false;
404 }
405
406 return true;
407 }
408
409 private void SetArea(int row, int col, int width, int height, TileType sym)
410 {
411 for (int j = row; j < row + height; j++)
412 {
413 for (int i = col; i < col + width; i++)
414 {
415 tiles[j, i] = sym;
416 }
417 }
418 }
419
425 public int GetLength(int dimension)
426 {
427 return tiles.GetLength(dimension);
428 }
429
436 public TileType GetTile(int row, int col)
437 {
438 return tiles[row, col];
439 }
440
448 public void SetTile(int row, int col, TileType c)
449 {
450 tiles[row, col] = c;
451 }
452
460 public static TileMethod ChangeSize(TileMethod m, double newWidth, double newHeight)
461 {
462 return new TileMethod(delegate (Vector p, double w, double h) { m(p, newWidth, newHeight); });
463 }
464
472 public static TileMethod ChangeSizeMultiplier(TileMethod m, double widthMultiplier, double heightMultiplier)
473 {
474 return new TileMethod(delegate (Vector p, double w, double h) { m(p, w * widthMultiplier, h * heightMultiplier); });
475 }
476 }
477}
Abstrakti ruutukartta. Tätä luokkaa et voi muodostaa. Katso ColorTileMap ja TileMap
void SetTileMethod< T1, T2, T3, T4, T5, T6 >(TileType tileSymbol, TileMethod< T1, T2, T3, T4, T5, T6 > f, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f....
void SetTileMethod< T1, T2, T3, T4, T5 >(TileType tileSymbol, TileMethod< T1, T2, T3, T4, T5 > f, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f....
delegate void TileMethod(Vector position, double width, double height)
delegate void TileMethod< T1, T2 >(Vector position, double width, double height, T1 p1, T2 p2)
void Execute()
Käy kentän kaikki merkit läpi ja kutsuu SetTileMethod-metodilla annettuja aliohjelmia kunkin merkin k...
delegate void TileMethod< T1, T2, T3, T4, T5, T6 >(Vector position, double width, double height, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6)
static TileMethod ChangeSizeMultiplier(TileMethod m, double widthMultiplier, double heightMultiplier)
Muuttaa luontialiohjelman tekemän olion kokoa tietyllä kertoimilla.
static TileMethod ChangeSize(TileMethod m, double newWidth, double newHeight)
Muuttaa luontialiohjelman tekemän olion kokoa.
TileType[,] tiles
Ruudut
TileType GetTile(int row, int col)
Palauttaa ruudussa olevan symbolin.
void SetTileMethod< T1 >(TileType tileSymbol, TileMethod< T1 > f, T1 p1)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f....
delegate void RouteMethod(List< Vector > route, double width, double height)
delegate void TileMethod< T1, T2, T3, T4, T5 >(Vector position, double width, double height, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
void SetTileMethod< T1, T2 >(TileType tileSymbol, TileMethod< T1, T2 > f, T1 p1, T2 p2)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f....
int GetLength(int dimension)
Palauttaa annetun dimension pituuden (merkkeinä, ei pikseleinä).
void GetGreatestMatchingRectangle(TileType sym, int row, int col, out int width, out int height)
List< TileMethodCall > optimized
delegate void TileMethod< T1, T2, T3, T4 >(Vector position, double width, double height, T1 p1, T2 p2, T3 p3, T4 p4)
void Optimize(params TileType[] symbols)
Optimoi annetut ruudut niin, että useammat vierekkäiset oliot yhdistetään isommiksi olioiksi....
TileMethod GetMethodForSymbol(TileType symbol)
Antaa ruutukartan symbolia vastaavan metodin
delegate void TileMethod< T1, T2, T3 >(Vector position, double width, double height, T1 p1, T2 p2, T3 p3)
void SetArea(int row, int col, int width, int height, TileType sym)
bool RowEquals(int row, int col, int length, TileType sym)
void Execute(double tileWidth, double tileHeight)
Käy kentän kaikki merkit läpi ja kutsuu SetTileMethod-metodilla annettuja aliohjelmia kunkin merkin k...
void SetTileMethod(TileType tileSymbol, TileMethod f)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f....
Dictionary< TileType, TileMethod > legend
Ruutuja vastaavat metodit
void SetRouteMethod(RouteMethod f, params TileType[] tileSymbols)
Kokoaa reitin useammasta ruutukentän symbolista.
abstract TileType Null
Tyhjä ruutumerkki
int ColumnCount
Sarakkeiden määrä kentässä (vaakasuoraan).
void Optimize(TileType sym)
Optimoi annetut ruudut niin, että useammat vierekkäiset oliot yhdistetään isommiksi olioiksi....
AbstractTileMap(TileType[,] tiles)
Ruutukartan oletusmuodostaja. Tätä luokkaa et voi muodostaa.
int RowCount
Rivien määrä kentässä (pystysuoraan).
delegate void TileMethod< T1 >(Vector position, double width, double height, T1 p1)
void SetTile(int row, int col, TileType c)
Asettaa ruudussa olevan symbolin.
virtual bool SymbolEquals(TileType a, TileType b)
Ovatko ruutukartan merkit samat
void SetTileMethod< T1, T2, T3 >(TileType tileSymbol, TileMethod< T1, T2, T3 > f, T1 p1, T2 p2, T3 p3)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f....
void SetTileMethod< T1, T2, T3, T4 >(TileType tileSymbol, TileMethod< T1, T2, T3, T4 > f, T1 p1, T2 p2, T3 p3, T4 p4)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f....
Level Level
Aktiivinen kenttä.
Definition: Game.cs:145
static Game Instance
Käynnissä olevan pelin pääolio.
Definition: Game.cs:96
double Top
Kentän yläreunan y-koordinaatti.
Definition: Level.cs:152
double Left
Kentän vasemman reunan x-koordinaatti.
Definition: Level.cs:136
double Width
Kentän leveys.
Definition: Level.cs:109
double Height
Kentän korkeus.
Definition: Level.cs:118
TileMethodCall(TileMethod m, int row, int col)
void Invoke(double tileWidth, double tileHeight)
2D-vektori.
Definition: Vector.cs:67