Jypeli 10
The simple game programming library
Surface.cs
Siirry tämän tiedoston dokumentaatioon.
1using System;
2
3namespace Jypeli
4{
8 public class Surface : PhysicsObject
9 {
10 double[] heights = null;
11 double scale = 1.0;
12
13 #region Constructors
14
28 public Surface( double width, double[] heights, double scale )
29 : base( width, CalculateHeight( heights, scale ), CreateRuggedShape( width, heights, scale ) )
30 {
32 }
33
39 public Surface( double width, double height )
40 : base( width, height, Shape.Rectangle )
41 {
42 InitializeFlat( height );
43 }
44
45 private void InitializeFlat( double height )
46 {
47 this.heights = new double[1] { height };
48 this.scale = 1.0;
49
50 this.Color = Color.ForestGreen;
51 this.TextureFillsShape = true;
52 MakeStatic();
53 }
54
55 private void InitializeRugged( double[] heights, double scale )
56 {
57 this.heights = heights;
58 this.scale = scale;
59 this.Color = Color.ForestGreen;
60 this.TextureFillsShape = true;
61 MakeStatic();
62 }
63
72 public Surface( double width, double min, double max, int points )
73 : this( width, RandomGen.NextDoubleArray( Math.Max( min, 1.0f ), max, points ), 1.0 )
74 {
75 }
76
86 public Surface( double width, double min, double max, int points, int maxchange )
87 : this( width, RandomGen.NextDoubleArray( Math.Max( min, 1.0f ), max, points, maxchange ), 1.0 )
88 {
89 }
90
91 #endregion
92
93 #region Static private methods for constructors
94
95 private static double CalculateHeight( double[] heights, double scale )
96 {
97 if ( heights.Length < 2 )
98 throw new Exception( "At least two Y-points needed in order to create ground" );
99 if ( heights.Min() < 1 )
100 throw new Exception( "The heights must be positive and at least 1" ); // JN: doesn't work well with 0 values (slow and memory usage problems)
101
102 return heights.Max() * scale;
103 }
104
105 private static Vector[] CalculateVertexes( double width, double[] heights, double scale )
106 {
107 int n = heights.Length;
108 double step = width / ( n - 1 );
109 double maxHeight = heights.Max() * scale;
110
111 // Each point should be adjusted by this amount in order to get the center of the shape at (0, 0)
112 // This way, drawing a single texture on top of it covers the whole shape.
113 double halfHeight = maxHeight / 2;
114
115 Vector[] vertexes = new Vector[n * 2];
116
117 // Let's start from the bottom right corner and head clockwise from there.
118 Vector bottomRight = new Vector( width / 2, -halfHeight );
119
120 // Bottom vertexes, right to left
121 for ( int i = 0; i < n; i++ )
122 {
123 vertexes[i] = new Vector( bottomRight.X - ( i * step ), bottomRight.Y );
124 }
125
126 double left = -width / 2;
127
128 // Top vertexes, left to right
129 for ( int i = 0; i < n; i++ )
130 {
131 vertexes[n + i] = new Vector( left + ( i * step ), heights[i] * scale - halfHeight );
132 }
133
134 return vertexes;
135 }
136
137 private static Polygon CreateRuggedShape( double width, double[] heights, double scale )
138 {
139 Vector[] vertexes = CalculateVertexes( width, heights, scale );
140 return CreateShape( width, heights, vertexes );
141 }
142
143 private static Polygon CreateShape( double width, double[] heights, Vector[] vertexes )
144 {
145 int n = heights.Length;
146 double step = width / ( n - 1 );
147 IndexTriangle[] triangles = new IndexTriangle[( n - 1 ) * 2];
148 Int16[] outlineIndices = new Int16[n * 2];
149
150 for ( int i = 0; i < n * 2; i++ )
151 outlineIndices[i] = (Int16)i;
152 for ( int i = 0; i < n - 1; i++ )
153 {
154 triangles[2 * i] = new IndexTriangle( i, 2 * n - i - 2, 2 * n - i - 1 );
155 triangles[2 * i + 1] = new IndexTriangle( i, i + 1, 2 * n - i - 2 );
156 }
157
158 Vector[] outlineVertices = new Vector[outlineIndices.Length];
159 for ( int i = 0; i < outlineIndices.Length; i++ )
160 outlineVertices[i] = vertexes[outlineIndices[i]];
161
162 return new Polygon( new ShapeCache( vertexes, triangles, outlineIndices ), false );
163 }
164
165 private static double GetMinHeightDifference( double[] heights )
166 {
167 int n = heights.Length;
168 double minHeightDifference = double.PositiveInfinity;
169
170 for ( int i = 0; i < n - 1; i++ )
171 {
172 double diff = Math.Abs( heights[i + 1] - heights[i] );
173 if ( diff > double.Epsilon && diff < minHeightDifference ) minHeightDifference = diff;
174 }
175
176 return minHeightDifference;
177 }
178
179 #endregion
180
181 #region Factory methods
182
190 public static Surface Create( Level level, Direction direction )
191 {
192 if ( direction == Direction.Left ) return CreateLeft( level );
193 if ( direction == Direction.Right ) return CreateRight( level );
194 if ( direction == Direction.Up ) return CreateTop( level );
195 if ( direction == Direction.Down ) return CreateBottom( level );
196
197 return null;
198 }
199
210 public static Surface Create( Level level, Direction direction, double min, double max, int points )
211 {
212 if ( direction == Direction.Left ) return CreateLeft( level, min, max, points );
213 if ( direction == Direction.Right ) return CreateRight( level, min, max, points );
214 if ( direction == Direction.Up ) return CreateTop( level, min, max, points );
215 if ( direction == Direction.Down ) return CreateBottom( level, min, max, points );
216
217 return null;
218 }
219
231 public static Surface Create( Level level, Direction direction, double min, double max, int points, int maxchange )
232 {
233 if ( direction == Direction.Left ) return CreateLeft( level, min, max, points, maxchange );
234 if ( direction == Direction.Right ) return CreateRight( level, min, max, points, maxchange );
235 if ( direction == Direction.Up ) return CreateTop( level, min, max, points, maxchange );
236 if ( direction == Direction.Down ) return CreateBottom( level, min, max, points, maxchange );
237
238 return null;
239 }
240
247 public static Surface CreateLeft( Level level )
248 {
249 double thickness = level.GetBorderThickness();
250 Surface ground = new Surface( level.Height, thickness );
251 ground.Angle = -Angle.RightAngle;
252 ground.Position = new Vector( level.Left - ( thickness / 2 ), level.Center.Y );
253 return ground;
254 }
255
265 public static Surface CreateLeft( Level level, double min, double max, int points )
266 {
267 Surface ground = new Surface( level.Height + 2 * max, min, max, points );
268 ground.Angle = -Angle.RightAngle;
269 ground.Position = new Vector( level.Left - ( max / 2 ), level.Center.Y );
270 return ground;
271 }
272
283 public static Surface CreateLeft( Level level, double min, double max, int points, int maxchange )
284 {
285 Surface ground = new Surface( level.Height + 2 * max, min, max, points, maxchange );
286 ground.Angle = -Angle.RightAngle;
287 ground.Position = new Vector( level.Left - ( max / 2 ), level.Center.Y );
288 return ground;
289 }
290
297 public static Surface CreateRight( Level level )
298 {
299 double thickness = level.GetBorderThickness();
300 Surface ground = new Surface( level.Height, thickness );
301 ground.Angle = Angle.RightAngle;
302 ground.Position = new Vector( level.Right + ( thickness / 2 ), level.Center.Y );
303 return ground;
304 }
305
315 public static Surface CreateRight( Level level, double min, double max, int points )
316 {
317 Surface ground = new Surface( level.Height + 2 * max, min, max, points );
318 ground.Angle = Angle.RightAngle;
319 ground.Position = new Vector( level.Right + ( max / 2 ), level.Center.Y );
320 return ground;
321 }
322
333 public static Surface CreateRight( Level level, double min, double max, int points, int maxchange )
334 {
335 Surface ground = new Surface( level.Height + 2 * max, min, max, points, maxchange );
336 ground.Angle = Angle.RightAngle;
337 ground.Position = new Vector( level.Right + ( max / 2 ), level.Center.Y );
338 return ground;
339 }
340
347 public static Surface CreateTop( Level level )
348 {
349 double thickness = level.GetBorderThickness();
350 Surface ground = new Surface( level.Width + ( 2 * thickness ), thickness );
351 ground.Angle = Angle.StraightAngle;
352 ground.Position = new Vector( level.Center.X, level.Top + ( thickness / 2 ) );
353 return ground;
354 }
355
365 public static Surface CreateTop( Level level, double min, double max, int points )
366 {
367 Surface ground = new Surface( level.Width + 2 * max, min, max, points );
368 ground.Angle = Angle.StraightAngle;
369 ground.Position = new Vector( level.Center.X, level.Top + ( max / 2 ) );
370 return ground;
371 }
372
383 public static Surface CreateTop( Level level, double min, double max, int points, int maxchange )
384 {
385 Surface ground = new Surface( level.Width + 2 * max, min, max, points, maxchange );
386 ground.Angle = Angle.StraightAngle;
387 ground.Position = new Vector( level.Center.X, level.Top + ( max / 2 ) );
388 return ground;
389 }
390
397 public static Surface CreateBottom( Level level )
398 {
399 double thickness = level.GetBorderThickness();
400 Surface ground = new Surface( level.Width + ( 2 * thickness ), thickness );
401 ground.Position = new Vector( level.Center.X, level.Bottom - ( thickness / 2 ) );
402 return ground;
403 }
404
414 public static Surface CreateBottom( Level level, double min, double max, int points )
415 {
416 Surface ground = new Surface( level.Width + 2 * max, min, max, points );
417 ground.Position = new Vector( level.Center.X, level.Bottom - ( max / 2 ) );
418 return ground;
419 }
420
431 public static Surface CreateBottom( Level level, double min, double max, int points, int maxchange )
432 {
433 Surface ground = new Surface( level.Width + 2 * max, min, max, points, maxchange );
434 ground.Position = new Vector( level.Center.X, level.Bottom - ( max / 2 ) );
435 return ground;
436 }
437
438 #endregion
439
440 #region Public methods
441
447 public double GetGroundHeight( double x )
448 {
449 if ( heights == null || x < Left || x > Right ) return Top;
450
451 int n = heights.Length;
452 double step = Width / ( n - 1 );
453 double maxHeight = heights.Max() * scale;
454
455 double indexX = ( Width / 2 + x ) / step;
456 int lowerIndex = (int)Math.Floor( indexX );
457 int upperIndex = (int)Math.Ceiling( indexX );
458
459 if ( upperIndex >= n ) return Top; // DEBUG
460 if ( lowerIndex == upperIndex ) return Bottom + scale * heights[lowerIndex];
461
462 double k = ( heights[upperIndex] - heights[lowerIndex] ) / step;
463 double relX = ( Width / 2 + x ) % step;
464
465 return Bottom + heights[lowerIndex] + relX * k;
466 }
467
473 public Vector GetGroundNormal( double x )
474 {
475 if ( heights == null || x < Left || x > Right ) return Vector.UnitY;
476
477 int n = heights.Length;
478 double step = Width / ( n - 1 );
479 double maxHeight = heights.Max() * scale;
480
481 double indexX = ( Width / 2 + x ) / step;
482 int lowerIndex = (int)Math.Floor( indexX );
483 int upperIndex = (int)Math.Ceiling( indexX );
484
485 if ( upperIndex >= n ) return Vector.UnitY; // DEBUG
486 if ( lowerIndex == upperIndex )
487 {
488 return ( GetGroundNormal( x - step / 2 ) + GetGroundNormal( x + step / 2 ) ) / 2;
489 }
490
491 double k = ( heights[upperIndex] - heights[lowerIndex] ) / step;
493 }
494
495 #endregion
496 }
497}
bool TextureFillsShape
Jos true, kuva piirretään niin, ettei se mene olion muodon ääriviivojen yli. Toisin sanoen kuva p...
Definition: Appearance.cs:81
double Top
Olion yläreunan y-koordinaatti.
double Bottom
Olion alareunan y-koordinaatti.
double Width
Olion leveys (X-suunnassa, leveimmässä kohdassa).
double Right
Olion oikean reunan x-koordinaatti.
Pelikenttä, johon voi lisätä olioita. Kentällä voi myös olla reunat ja taustaväri tai taustakuva.
Definition: Borders.cs:6
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 Right
Kentän oikean reunan x-koordinaatti.
Definition: Level.cs:144
double Width
Kentän leveys.
Definition: Level.cs:109
double Bottom
Kentän alareunan y-koordinaatti.
Definition: Level.cs:160
readonly Vector Center
Kentän keskipiste.
Definition: Level.cs:89
double Height
Kentän korkeus.
Definition: Level.cs:118
double GetBorderThickness()
Definition: Borders.cs:515
Kappale joka noudattaa fysiikan lakeja, johon voi törmätä. Vaatii että käytössä on fysiikkapeli.
Definition: Collisions.cs:7
override Angle?? Angle
Definition: Dimensions.cs:55
override Vector?? Position
Definition: Dimensions.cs:30
void MakeStatic()
Tekee oliosta staattisen eli liikkumattoman.
Monikulmio.
Definition: Shapes.cs:535
Satunnaisgeneraattori. Luo satunnaisia arvoja, mm. lukuja, vektoreita sekä kulmia.
Definition: RandomGen.cs:39
Suorakulmio.
Definition: Shapes.cs:322
Sisältää valmiiksi lasketut kolmiot, joiden avulla piirtäminen on suoraviivaista.
Definition: Shapes.cs:628
Kuvio.
Definition: Shapes.cs:47
Tasainen tai epätasainen pinta.
Definition: Surface.cs:9
static Surface CreateBottom(Level level, double min, double max, int points)
Luo kentälle epätasaisen alareunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:414
double GetGroundHeight(double x)
Maanpinnan korkeus annetussa x-koordinaatissa
Definition: Surface.cs:447
static Surface CreateTop(Level level, double min, double max, int points)
Luo kentälle epätasaisen yläreunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:365
static Polygon CreateRuggedShape(double width, double[] heights, double scale)
Definition: Surface.cs:137
static Surface Create(Level level, Direction direction)
Luo kentälle tasaisen reunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:190
double scale
Definition: Surface.cs:11
Surface(double width, double min, double max, int points)
Luo satunnaisen pinnan.
Definition: Surface.cs:72
Vector GetGroundNormal(double x)
Maanpinnan normaalivektori annetulla x-koordinaatilla
Definition: Surface.cs:473
static double GetMinHeightDifference(double[] heights)
Definition: Surface.cs:165
double[] heights
Definition: Surface.cs:10
static Surface CreateRight(Level level)
Luo kentälle tasaisen oikean reunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:297
static Surface Create(Level level, Direction direction, double min, double max, int points, int maxchange)
Luo kentälle epätasaisen reunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:231
static Vector[] CalculateVertexes(double width, double[] heights, double scale)
Definition: Surface.cs:105
static double CalculateHeight(double[] heights, double scale)
Definition: Surface.cs:95
static Surface Create(Level level, Direction direction, double min, double max, int points)
Luo kentälle epätasaisen reunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:210
Surface(double width, double min, double max, int points, int maxchange)
Luo satunnaisen pinnan.
Definition: Surface.cs:86
static Surface CreateLeft(Level level, double min, double max, int points, int maxchange)
Luo kentälle epätasaisen vasemman reunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:283
void InitializeFlat(double height)
Definition: Surface.cs:45
static Surface CreateTop(Level level)
Luo kentälle tasaisen yläreunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:347
static Surface CreateRight(Level level, double min, double max, int points, int maxchange)
Luo kentälle epätasaisen oikean reunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:333
static Surface CreateRight(Level level, double min, double max, int points)
Luo kentälle epätasaisen oikean reunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:315
static Surface CreateTop(Level level, double min, double max, int points, int maxchange)
Luo kentälle epätasaisen yläreunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:383
void InitializeRugged(double[] heights, double scale)
Definition: Surface.cs:55
static Surface CreateBottom(Level level, double min, double max, int points, int maxchange)
Luo kentälle epätasaisen alareunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:431
static Surface CreateLeft(Level level, double min, double max, int points)
Luo kentälle epätasaisen vasemman reunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:265
static Surface CreateBottom(Level level)
Luo kentälle tasaisen alareunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:397
static Surface CreateLeft(Level level)
Luo kentälle tasaisen vasemman reunan. Ei lisää reunaa automaattisesti kenttään.
Definition: Surface.cs:247
static Polygon CreateShape(double width, double[] heights, Vector[] vertexes)
Definition: Surface.cs:143
Surface(double width, double[] heights, double scale)
Helppo tapa lisätä kenttään epätasainen pinta. Pinta kuvataan luettelemalla Y-koordinaatteja vasemmal...
Definition: Surface.cs:28
Surface(double width, double height)
Luo tasaisen pinnan.
Definition: Surface.cs:39
Suuntakulma (rajoitettu -180 ja 180 asteen välille) asteina ja radiaaneina. Tietoja kulmasta: http://...
Definition: Angle.cs:40
static readonly Angle RightAngle
Suora kulma (90 astetta).
Definition: Angle.cs:49
static readonly Angle StraightAngle
Oikokulma (180 astetta).
Definition: Angle.cs:54
static Angle ArcTan(double d)
Palauttaa kulman joka vastaa d:n arcus-tangentti.
Definition: Angle.cs:502
Väri.
Definition: Color.cs:13
static readonly Color ForestGreen
Metsänvihreä.
Definition: Color.cs:681
Perussuunta tasossa.
Definition: Direction.cs:47
static Direction Up
Suunta ylös.
Definition: Direction.cs:56
static Direction Right
Suunta oikealle.
Definition: Direction.cs:71
static Direction Down
Suunta alas.
Definition: Direction.cs:61
static Direction Left
Suunta vasemmalle.
Definition: Direction.cs:66
Muotojen määrityksessä käytettävä kolmio.
Definition: Shapes.cs:598
2D-vektori.
Definition: Vector.cs:67
double Y
Vektorin Y-komponentti
Definition: Vector.cs:339
double X
Vektorin X-komponentti.
Definition: Vector.cs:334
static readonly Vector UnitY
Pystysuuntainen yksikkövektori (pituus 1, suunta ylös).
Definition: Vector.cs:86
static Vector FromLengthAndAngle(double length, double angle)
Luo vektorin pituuden ja kulman perusteella.
Definition: Vector.cs:114