Jypeli 10
The simple game programming library
Animation.cs
Siirry tämän tiedoston dokumentaatioon.
1#region MIT License
2/*
3 * Copyright (c) 2009 University of Jyväskylä, Department of Mathematical
4 * Information Technology.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#endregion
25
26/*
27 * Authors: Tero Jäntti, Tomi Karppinen, Janne Nikkanen.
28 */
29
30using System;
31using System.Collections.Generic;
32
33#if WINDOWS_STOREAPP
35#else
37#endif
38
39namespace Jypeli
40{
61 public class Animation : IEnumerable<Image>
62 {
63 private double secondsPerFrame;
64 private TimeSpan startTime;
65 private int currentIndex;
66 private int repeatCount = -1; // When -1, animation repeats forever.
67
68 // NOTES:
69 //
70 // Animation frames should be immutable, because that is what
71 // the Layer class assumes. So, let's not provide
72 // any methods to modify the images of an existing animation.
73 //
74 // This is not a big deal, as there rarely is any need
75 // to modify animations at runtime and constructing new
76 // animation objects is quite easy anyway.
77
78 internal Image[] frames = null;
79
83 public bool IsPlaying { get; set; }
84
88 public int FrameCount
89 {
90 get { return frames.Length; }
91 }
92
93 int lastRepeat = 0;
94
99 {
100 get
101 {
102 if ( !IsPlaying ) return currentIndex;
103
104 double secondsNow = Game.Time.SinceStartOfGame.TotalSeconds;
105 double secondsAdvanced = secondsNow - startTime.TotalSeconds;
106 int currentRepeat = (int)( secondsAdvanced / ( FrameCount * secondsPerFrame ) );
107
108 if ( currentRepeat > lastRepeat )
109 {
110 OnPlayed();
111 lastRepeat = currentRepeat;
112 }
113
114 if ( repeatCount >= 0 && currentRepeat >= repeatCount )
115 Stop();
116
117 return ( (int)( secondsAdvanced * FPS ) ) % FrameCount;
118 }
119 }
120
124 public double FPS
125 {
126 get { return 1 / secondsPerFrame; }
127 set
128 {
129 if ( value == 0 )
130 throw new ArgumentException( "FPS can not be zero" );
131 secondsPerFrame = 1 / value;
132 }
133 }
134
139 {
140 get { return frames[CurrentFrameIndex]; }
141 }
142
147 public bool StopOnLastFrame { get; set; }
148
152 public double Width
153 {
154 get { return FrameCount > 0 ? frames[0].Width : 0; }
155 }
156
160 public double Height
161 {
162 get { return FrameCount > 0 ? frames[0].Height : 0; }
163 }
164
169 {
170 get { return new Vector( Width, Height ); }
171 }
172
176 public event Action Played;
177
178 private void OnPlayed()
179 {
180 if ( Played != null ) Played();
181 }
182
187 public Animation( params Image[] frames )
188 {
189 if ( frames.Length == 0 )
190 throw new ArgumentException( "Animation must have at least one frame." );
191 FPS = 25;
192 currentIndex = 0;
194 this.frames = frames;
195 }
196
201 public static implicit operator Animation(Image image)
202 {
203 if ( image == null ) return null;
204 return new Animation( image );
205 }
206
211 public Animation( Animation src )
212 {
213 FPS = src.FPS;
214 IsPlaying = src.IsPlaying;
215 startTime = src.startTime;
218 frames = new Image[src.FrameCount];
219
220 // Copy only the references to images.
221 for ( int i = 0; i < src.FrameCount; i++ )
222 frames[i] = src.frames[i];
223 }
224
231 public static Animation Apply( Animation anim, ImageConverter method )
232 {
233 Animation applied = new Animation( anim );
234
235 for ( int i = 0; i < anim.frames.Length; i++ )
236 {
237 applied.frames[i] = method(anim.frames[i]);
238 }
239
240 return applied;
241 }
242
248 public static Animation Mirror( Animation anim )
249 {
250 return Apply( anim, Image.Mirror );
251 }
252
258 public static Animation Flip( Animation anim )
259 {
260 return Apply( anim, Image.Flip );
261 }
262
268 public static Animation Reverse( Animation anim )
269 {
270 Animation reversed = new Animation( anim );
271
272 for ( int i = 0; i < anim.frames.Length / 2; i++ )
273 {
274 reversed.frames[i] = anim.frames[anim.frames.Length - 1 - i];
275 reversed.frames[anim.frames.Length - 1 - i] = anim.frames[i];
276 }
277
278 return reversed;
279 }
280
284 public void Start()
285 {
286 Start( -1 );
287 }
288
293 public void Start( int repeatCount )
294 {
295 this.repeatCount = repeatCount;
297 IsPlaying = true;
298 lastRepeat = 0;
299 }
300
304 public void Pause()
305 {
306 IsPlaying = false;
307 }
308
312 public void Resume()
313 {
314 IsPlaying = true;
315 }
316
320 public void Stop()
321 {
322 IsPlaying = false;
323 currentIndex = 0;
324 if ( StopOnLastFrame )
326 repeatCount = -1;
327 }
328
334 public void Step( int numberOfFrames )
335 {
336 IsPlaying = false;
337 currentIndex = currentIndex + numberOfFrames;
338
339 if ( currentIndex >= FrameCount )
340 {
341 // Animation has reached its final frame
342 if ( repeatCount > 0 ) repeatCount--;
343
344 if ( repeatCount == 0 )
345 Stop();
346 else
347 {
348 // Play it again, Sam
350 }
351
352 OnPlayed();
353 }
354 }
355
359 public void Step()
360 {
361 Step( 1 );
362 }
363
364 #region IEnumerable<Image> Members
365
370 public IEnumerator<Image> GetEnumerator()
371 {
372 foreach ( Image frame in frames )
373 yield return frame;
374 }
375
376 #endregion
377
378 #region IEnumerable Members
379
380 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
381 {
382 return frames.GetEnumerator();
383 }
384
385 #endregion
386 }
387}
System.Converter< Jypeli.Image, Jypeli.Image > ImageConverter
Definition: Animation.cs:36
Sarja kuvia, jotka vaihtuvat halutulla nopeudella. Yksi animaatio koostuu yhdestä tai useammasta kuva...
Definition: Animation.cs:62
double? Height
Animaation korkeus. Nolla, jos animaatiossa ei ole yhtään ruutua.
Definition: Animation.cs:161
Animation(params Image[] frames)
Luo uuden animaation.
Definition: Animation.cs:187
static Animation Mirror(Animation anim)
Peilaa animaation X-suunnasssa.
Definition: Animation.cs:248
void Step()
Etenee animaatiossa yhden ruudun eteenpäin.
Definition: Animation.cs:359
double FPS
Animaation päivitysnopeus ruutuina sekunnissa (frames per second).
Definition: Animation.cs:125
Action Played
Tapahtuma, joka tapahtuu kun animaatio on suoritettu.
Definition: Animation.cs:176
static Animation Apply(Animation anim, ImageConverter method)
Käyttää haluttua metodia kaikkiin animaation ruutuihin.
Definition: Animation.cs:231
int FrameCount
Ruutujen määrä.
Definition: Animation.cs:89
void Pause()
Keskeyttää animaation toiston.
Definition: Animation.cs:304
static Animation Flip(Animation anim)
Peilaa animaation Y-suunnasssa.
Definition: Animation.cs:258
IEnumerator< Image > GetEnumerator()
Animaation kuvien iteraattori
Definition: Animation.cs:370
void Step(int numberOfFrames)
Etenee animaatiossa halutun määrän ruutuja. Käytä negatiivisia arvoja, jos haluat kulkea taaksepäin.
Definition: Animation.cs:334
bool StopOnLastFrame
Jos true, animaatio ei pysähtyessä palaa ensimmäiseen ruutuun.
Definition: Animation.cs:147
double? Width
Animaation leveys. Nolla, jos animaatiossa ei ole yhtään ruutua.
Definition: Animation.cs:153
double secondsPerFrame
Definition: Animation.cs:63
int CurrentFrameIndex
Aktiivisen animaatioruudun indeksi (alkaa nollasta).
Definition: Animation.cs:99
bool IsPlaying
Onko animaatio käynnissä.
Definition: Animation.cs:83
TimeSpan startTime
Definition: Animation.cs:64
Animation(Animation src)
Luo kopion jo tunnetusta animaatiosta.
Definition: Animation.cs:211
static Animation Reverse(Animation anim)
Palauttaa animaation, joka toistuu lopusta alkuun.
Definition: Animation.cs:268
Image[] frames
Definition: Animation.cs:78
void Resume()
Jatkaa animaatiota siitä, mihin viimeksi jäätiin.
Definition: Animation.cs:312
void Stop()
Pysäyttää animaation asettaen sen ensimmäiseen ruutuun.
Definition: Animation.cs:320
void Start(int repeatCount)
Käynnistää animaation alusta.
Definition: Animation.cs:293
Image CurrentFrame
Tällä hetkellä näkyvä ruutu animaatiosta.
Definition: Animation.cs:139
void Start()
Käynnistää animaation alusta.
Definition: Animation.cs:284
Vector Size
Animaation koko. Vector.Zero, jos animaatiossa ei ole yhtään ruutua.
Definition: Animation.cs:169
static Time Time
Peliaika. Sisältää tiedon siitä, kuinka kauan peliä on pelattu (Time.SinceStartOfGame) ja kuinka kaua...
Definition: Time.cs:25
Kuva.
Definition: Image.cs:30
static Image Mirror(Image image)
Peilaa kuvan X-suunnassa.
Definition: Image.cs:921
int Width
Leveys pikseleinä.
Definition: Image.cs:374
static Image Flip(Image image)
Peilaa kuvan Y-suunnassa.
Definition: Image.cs:955
int Height
Korkeus pikseleinä.
Definition: Image.cs:382
Apufunktioita listojen ja muiden tietorakenteiden käyttöön.
Definition: ListHelpers.cs:11
TimeSpan SinceStartOfGame
Aika joka on kulunut pelin alusta.
Definition: Time.cs:35
2D-vektori.
Definition: Vector.cs:67