Jypeli  5
The simple game programming library
AbstractTileMap.cs
Siirry tämän tiedoston dokumentaatioon.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 
6 namespace Jypeli
7 {
8  public abstract class AbstractTileMap<TileType>
9  {
10  public delegate void TileMethod( Vector position, double width, double height );
11  public delegate void TileMethod<T1>( Vector position, double width, double height, T1 p1 );
12  public delegate void TileMethod<T1, T2>( Vector position, double width, double height, T1 p1, T2 p2 );
13  public delegate void TileMethod<T1, T2, T3>( Vector position, double width, double height, T1 p1, T2 p2, T3 p3 );
14  public delegate void TileMethod<T1, T2, T3, T4>( Vector position, double width, double height, T1 p1, T2 p2, T3 p3, T4 p4 );
15  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 );
16  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 );
17 
18  public delegate void TileMethodWithPos( Vector position, double width, double height, IntPoint positionInLevelArray);
19  public delegate void TileMethodWithPos<T1>(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1);
20  public delegate void TileMethodWithPos<T1, T2>(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2);
21  public delegate void TileMethodWithPos<T1, T2, T3>(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2, T3 p3);
22  public delegate void TileMethodWithPos<T1, T2, T3, T4>(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2, T3 p3, T4 p4);
23  public delegate void TileMethodWithPos<T1, T2, T3, T4, T5>(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5);
24  public delegate void TileMethodWithPos<T1, T2, T3, T4, T5, T6>(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6);
25 
26 
27 
28  struct TileMethodCall
29  {
30  public TileMethodWithPos method;
31  public int row;
32  public int col;
33 
34  public TileMethodCall( TileMethodWithPos m, int row, int col )
35  {
36  this.method = m;
37  this.row = row;
38  this.col = col;
39  }
40 
41  public void Invoke( double tileWidth, double tileHeight )
42  {
43  double realX = Game.Instance.Level.Left + ( col * tileWidth ) + ( tileWidth / 2 );
44  double realY = Game.Instance.Level.Top - ( row * tileHeight ) - ( tileHeight / 2 );
45  method( new Vector( realX, realY ), tileWidth, tileHeight, new IntPoint(row, col));
46  }
47  }
48 
49  private List<TileMethodCall> optimized = new List<TileMethodCall>();
50  protected Dictionary<TileType, TileMethodWithPos> legend = new Dictionary<TileType, TileMethodWithPos>();
51  protected TileType[,] tiles;
52 
53  protected abstract TileType Null { get; }
54 
55  public AbstractTileMap(TileType[,] tiles)
56  {
57  if ( tiles.GetLength( 0 ) == 0 || tiles.GetLength( 1 ) == 0 )
58  throw new ArgumentException( "All dimensions of tiles must be at least 1" );
59 
60  this.tiles = tiles;
61  }
62 
66  public int RowCount
67  {
68  get { return tiles.GetLength( 0 ); }
69  }
70 
74  public int ColumnCount
75  {
76  get { return tiles.GetLength( 1 ); }
77  }
78 
86  public void SetTileMethod( TileType tileSymbol, TileMethodWithPos f )
87  {
88  legend[tileSymbol] = f;
89  }
90 
100  public void SetTileMethod<T1>( TileType tileSymbol, TileMethodWithPos<T1> f, T1 p1 )
101  {
102  legend[tileSymbol] = delegate( Vector p, double w, double h, IntPoint posInLevel ) { f( p, w, h, posInLevel, p1 ); };
103  }
104 
116  public void SetTileMethod<T1, T2>( TileType tileSymbol, TileMethodWithPos<T1, T2> f, T1 p1, T2 p2 )
117  {
118  legend[tileSymbol] = delegate(Vector p, double w, double h, IntPoint posInLevel) { f(p, w, h, posInLevel, p1, p2); };
119  }
120 
132  public void SetTileMethod<T1, T2, T3>( TileType tileSymbol, TileMethodWithPos<T1, T2, T3> f, T1 p1, T2 p2, T3 p3 )
133  {
134  legend[tileSymbol] = delegate(Vector p, double w, double h, IntPoint posInLevel) { f(p, w, h, posInLevel, p1, p2, p3); };
135  }
136 
148  public void SetTileMethod<T1, T2, T3, T4>(TileType tileSymbol, TileMethodWithPos<T1, T2, T3, T4> f, T1 p1, T2 p2, T3 p3, T4 p4)
149  {
150  legend[tileSymbol] = delegate(Vector p, double w, double h, IntPoint posInLevel) { f(p, w, h, posInLevel, p1, p2, p3, p4); };
151  }
152 
164  public void SetTileMethod<T1, T2, T3, T4, T5>(TileType tileSymbol, TileMethodWithPos<T1, T2, T3, T4, T5> f, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
165  {
166  legend[tileSymbol] = delegate(Vector p, double w, double h, IntPoint posInLevel) { f(p, w, h, posInLevel, p1, p2, p3, p4, p5); };
167  }
168 
180  public void SetTileMethod<T1, T2, T3, T4, T5, T6>(TileType tileSymbol, TileMethodWithPos<T1, T2, T3, T4, T5, T6> f, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6)
181  {
182  legend[tileSymbol] = delegate(Vector p, double w, double h, IntPoint posInLevel) { f(p, w, h, posInLevel, p1, p2, p3, p4, p5, p6); };
183  }
184 
186 
194  public void SetTileMethod( TileType tileSymbol, TileMethod f )
195  {
196  legend[tileSymbol] = delegate( Vector p, double w, double h, IntPoint posInLevel ) { f( p, w, h ); };
197  }
198 
208  public void SetTileMethod<T1>( TileType tileSymbol, TileMethod<T1> f, T1 p1 )
209  {
210  legend[tileSymbol] = delegate( Vector p, double w, double h, IntPoint posInLevel ) { f( p, w, h, p1 ); };
211  }
212 
224  public void SetTileMethod<T1, T2>( TileType tileSymbol, TileMethod<T1, T2> f, T1 p1, T2 p2 )
225  {
226  legend[tileSymbol] = delegate( Vector p, double w, double h, IntPoint posInLevel ) { f( p, w, h, p1, p2 ); };
227  }
228 
240  public void SetTileMethod<T1, T2, T3>( TileType tileSymbol, TileMethod<T1, T2, T3> f, T1 p1, T2 p2, T3 p3 )
241  {
242  legend[tileSymbol] = delegate( Vector p, double w, double h, IntPoint posInLevel ) { f( p, w, h, p1, p2, p3 ); };
243  }
244 
256  public void SetTileMethod<T1, T2, T3, T4>( TileType tileSymbol, TileMethod<T1, T2, T3, T4> f, T1 p1, T2 p2, T3 p3, T4 p4 )
257  {
258  legend[tileSymbol] = delegate( Vector p, double w, double h, IntPoint posInLevel ) { f( p, w, h, p1, p2, p3, p4 ); };
259  }
260 
272  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 )
273  {
274  legend[tileSymbol] = delegate( Vector p, double w, double h, IntPoint posInLevel ) { f( p, w, h, p1, p2, p3, p4, p5 ); };
275  }
276 
288  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 )
289  {
290  legend[tileSymbol] = delegate( Vector p, double w, double h, IntPoint posInLevel ) { f( p, w, h, p1, p2, p3, p4, p5, p6 ); };
291  }
292 
293 
294 
302  public void Execute()
303  {
304  double h = Game.Instance.Level.Height / tiles.GetLength( 0 );
305  double w = Game.Instance.Level.Width / tiles.GetLength( 1 );
306  Execute( w, h );
307  }
308 
318  public void Execute( double tileWidth, double tileHeight )
319  {
320  Game game = Game.Instance;
321  int width = tiles.GetLength( 1 );
322  int height = tiles.GetLength( 0 );
323 
324  game.Level.Width = width * tileWidth;
325  game.Level.Height = height * tileHeight;
326 
327  foreach ( var m in optimized )
328  {
329  m.Invoke( tileWidth, tileHeight );
330  }
331 
332  for ( int y = height - 1; y >= 0; y-- )
333  {
334  for ( int x = 0; x < width; x++ )
335  {
336  TileMethodWithPos method = GetMethodForSymbol( tiles[y, x] );
337 
338  if ( method != null )
339  {
340  double realX = game.Level.Left + ( x * tileWidth ) + ( tileWidth / 2 );
341  double realY = game.Level.Top - ( y * tileHeight ) - ( tileHeight / 2 );
342  method( new Vector( realX, realY ), tileWidth, tileHeight, new IntPoint(x, y));
343  }
344  }
345  }
346  }
347 
348  protected TileMethodWithPos GetMethodForSymbol( TileType symbol )
349  {
350  if ( symbol.Equals(Null) ) return null;
351 
352  foreach ( var key in legend.Keys )
353  {
354  if ( SymbolEquals( key, symbol ) )
355  return legend[key];
356  }
357 
358  return null;
359  }
360 
361  protected virtual bool SymbolEquals( TileType a, TileType b )
362  {
363  return a.Equals( b );
364  }
365 
371  public void Optimize( params TileType[] symbols )
372  {
373  for ( int i = 0; i < symbols.Length; i++ )
374  Optimize( symbols[i] );
375  }
376 
382  public void Optimize( TileType sym )
383  {
384  TileMethodWithPos method = GetMethodForSymbol(sym);
385 
386  if (method == null)
387  throw new ArgumentException("Symbol " + sym + " not added, cannot optimize.");
388 
389  for ( int row = 0; row < RowCount; row++ )
390  {
391  for ( int col = 0; col < ColumnCount; col++ )
392  {
393  int w, h;
394  GetGreatestMatchingRectangle( sym, row, col, out w, out h );
395 
396  if ( w > 0 && h > 0 )
397  {
398  TileMethodWithPos newMethod = delegate (Vector oldPos, double oldWidth, double oldHeight, IntPoint oldPosInLevel)
399  {
400  Vector oldAdjust = new Vector(-oldWidth, oldHeight);
401  Vector newAdjust = new Vector(oldWidth * w, -oldHeight * h);
402  Vector newPos = oldPos + ( oldAdjust + newAdjust ) / 2;
403  method( newPos, oldWidth * w, oldHeight * h, new IntPoint(row, col));
404  };
405  optimized.Add( new TileMethodCall( newMethod, row, col ) );
406  SetArea( row, col, w, h, Null );
407  col += w;
408  }
409  }
410  }
411  }
412 
413  private void GetGreatestMatchingRectangle( TileType sym, int row, int col, out int width, out int height )
414  {
415  for ( width = 0; width < ColumnCount - col; width++ )
416  {
417  if ( !SymbolEquals( tiles[row, col + width], sym ) )
418  break;
419  }
420 
421  if ( width == 0 )
422  {
423  height = 0;
424  return;
425  }
426 
427  for ( height = 1; height < RowCount - row; height++ )
428  {
429  if ( !RowEquals( row + height, col, width, sym ) )
430  break;
431  }
432  }
433 
434  private bool RowEquals( int row, int col, int length, TileType sym )
435  {
436  for ( int i = col; i < col + length; i++ )
437  {
438  if ( !SymbolEquals( tiles[row, i], sym ) ) return false;
439  }
440 
441  return true;
442  }
443 
444  private void SetArea( int row, int col, int width, int height, TileType sym )
445  {
446  for ( int j = row; j < row + height; j++ )
447  {
448  for ( int i = col; i < col + width; i++ )
449  {
450  tiles[j, i] = sym;
451  }
452  }
453  }
454 
460  public int GetLength( int dimension )
461  {
462  return tiles.GetLength( dimension );
463  }
464 
471  public TileType GetTile( int row, int col )
472  {
473  return tiles[row,col];
474  }
475 
483  public void SetTile( int row, int col, TileType c )
484  {
485  tiles[row,col] = c;
486  }
487 
495  public static TileMethodWithPos ChangeSize( TileMethodWithPos m, double newWidth, double newHeight )
496  {
497  return new TileMethodWithPos( delegate( Vector p, double w, double h, IntPoint posInLevel ) { m( p, newWidth, newHeight, posInLevel); } );
498  }
499 
507  public static TileMethodWithPos ChangeSizeMultiplier( TileMethodWithPos m, double widthMultiplier, double heightMultiplier )
508  {
509  return new TileMethodWithPos( delegate( Vector p, double w, double h, IntPoint posInLevel) { m( p, w * widthMultiplier, h * heightMultiplier, posInLevel ); } );
510  }
511  }
512 }
void Optimize(TileType sym)
Optimoi annetut ruudut niin, että useammat vierekkäiset oliot yhdistetään isommiksi olioiksi...
delegate void TileMethodWithPos< T1, T2, T3, T4 >(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2, T3 p3, T4 p4)
int ColumnCount
Sarakkeiden määrä kentässä (vaakasuoraan).
static TileMethodWithPos ChangeSize(TileMethodWithPos m, double newWidth, double newHeight)
Muuttaa luontialiohjelman tekemän olion kokoa.
abstract TileType Null
double Top
Kentän yläreunan y-koordinaatti.
Definition: Level.cs:160
TileMethodWithPos GetMethodForSymbol(TileType symbol)
void SetTileMethod< T1 >(TileType tileSymbol, TileMethodWithPos< T1 > f, T1 p1)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f...
void SetTileMethod< T1, T2, T3 >(TileType tileSymbol, TileMethodWithPos< 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, T5 >(TileType tileSymbol, TileMethodWithPos< 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...
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 >(Vector position, double width, double height, T1 p1, T2 p2, T3 p3)
void SetTileMethod(TileType tileSymbol, TileMethod f)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f...
static Game Instance
Definition: Game.cs:149
delegate void TileMethodWithPos(Vector position, double width, double height, IntPoint positionInLevelArray)
Piste kokonaislukuruudukossa.
Definition: IntPoint.cs:11
void SetTileMethod< T1, T2 >(TileType tileSymbol, TileMethodWithPos< 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 SetTile(int row, int col, TileType c)
Asettaa ruudussa olevan symbolin.
delegate void TileMethod< T1 >(Vector position, double width, double height, T1 p1)
Peliluokka reaaliaikaisille peleille.
Definition: DebugScreen.cs:10
AbstractTileMap(TileType[,] tiles)
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)
delegate void TileMethodWithPos< T1, T2, T3 >(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2, T3 p3)
delegate void TileMethod(Vector position, double width, double height)
static TileMethodWithPos ChangeSizeMultiplier(TileMethodWithPos m, double widthMultiplier, double heightMultiplier)
Muuttaa luontialiohjelman tekemän olion kokoa tietyllä kertoimilla.
void SetTileMethod(TileType tileSymbol, TileMethodWithPos f)
Määrittää, että tietyn ruutukentän symbolin (tileSymbol) kohdalla kutsutaan aliohjelmaa f...
void SetTileMethod< T1, T2, T3, T4, T5, T6 >(TileType tileSymbol, TileMethodWithPos< 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...
double Height
Kentän korkeus.
Definition: Level.cs:126
Level Level
Aktiivinen kenttä.
Definition: Game.cs:299
delegate void TileMethod< T1, T2 >(Vector position, double width, double height, T1 p1, T2 p2)
int RowCount
Rivien määrä kentässä (pystysuoraan).
delegate void TileMethod< T1, T2, T3, T4, T5 >(Vector position, double width, double height, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
delegate void TileMethodWithPos< T1, T2 >(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2)
double Width
Kentän leveys.
Definition: Level.cs:117
delegate void TileMethodWithPos< T1 >(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1)
delegate void TileMethodWithPos< T1, T2, T3, T4, T5 >(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
delegate void TileMethodWithPos< T1, T2, T3, T4, T5, T6 >(Vector position, double width, double height, IntPoint positionInLevelArray, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6)
TileType GetTile(int row, int col)
Palauttaa ruudussa olevan symbolin.
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...
2D-vektori.
Definition: Vector.cs:56
virtual bool SymbolEquals(TileType a, TileType b)
void Execute(double tileWidth, double tileHeight)
Käy kentän kaikki merkit läpi ja kutsuu SetTileMethod-metodilla annettuja aliohjelmia kunkin merkin k...
Dictionary< TileType, TileMethodWithPos > legend
void SetTileMethod< T1, T2, T3, T4 >(TileType tileSymbol, TileMethodWithPos< 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...
double Left
Kentän vasemman reunan x-koordinaatti.
Definition: Level.cs:144