Jypeli 10
The simple game programming library
Explosion.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;
31
32namespace Jypeli.Assets
33{
37 public class Explosion : GameObject
38 {
40 private static Image commonImage = null;
41 private static SoundEffect commonSound = null;
42
44 private bool initialized;
45
49 public bool UseShockWave { get; set; }
50
54 public double MaxRadius { get; set; }
55
59 public SoundEffect Sound { get; set; }
60
64 public double CurrentRadius
65 {
66 get { return Size.X; }
67 private set
68 {
69 Size = new Vector( value, value );
70 }
71 }
72
80 {
81 get { return shockWave.Color; }
82 set { shockWave.Color = value; }
83 }
84
88 public double Speed { get; set; }
89
94 public double Force { get; set; }
95
100 public double Volume { get; set; }
101
105 public event Action<IPhysicsObject, Vector> ShockwaveReachesObject;
106
111 public Explosion( Explosion src )
112 : this( src.MaxRadius )
113 {
114 this.UseShockWave = src.UseShockWave;
116 this.Speed = src.Speed;
117 this.Force = src.Force;
118 }
119
124 public Explosion( double radius )
125 : base( 0.1, 0.1, Shape.Circle )
126 {
127 UseShockWave = true;
128 MaxRadius = radius;
129 Speed = 250.0;
130 Force = 1000.0;
131 Volume = 0.2;
132 shockWave = new GameObject( 1, 1, Shape.Circle );
133 shockWave.Color = new Color( 240, 248, 255, 60 );
134 Add( shockWave );
135
137
138 initialized = false;
139 IsUpdated = true;
140 }
141
142 private void PreloadContent()
143 {
144 if ( commonImage == null ) commonImage = Game.LoadImageFromResources( "Explosion.png" );
145 if ( commonSound == null ) commonSound = Game.LoadSoundEffectFromResources( "ExplosionSound.wav" );
146
149 }
150
151 private void OnShockwaveReachesObject( IPhysicsObject obj, Vector swForce )
152 {
153 if ( ShockwaveReachesObject != null )
154 ShockwaveReachesObject( obj, swForce );
155 }
156
162 public void AddShockwaveHandler( IPhysicsObject o, Action<IPhysicsObject, Vector> handler )
163 {
164 if ( o == null ) throw new NullReferenceException( "Object must not be null" );
165 if ( handler == null ) throw new NullReferenceException( "Handler must not be null" );
166
167 this.ShockwaveReachesObject += delegate( IPhysicsObject target, Vector shockForce )
168 {
169 if ( target == o )
170 handler( target, shockForce );
171 };
172 }
173
179 public void AddShockwaveHandler(string tag, Action<IPhysicsObject, Vector> handler)
180 {
181 if (tag == null) throw new NullReferenceException("Tag must not be null");
182 if (handler == null) throw new NullReferenceException("Handler must not be null");
183
184 this.ShockwaveReachesObject += delegate(IPhysicsObject target, Vector shockForce)
185 {
186 string targetTagAsString = target.Tag as string;
187
188 if (targetTagAsString != null && targetTagAsString == tag)
189 handler(target, shockForce);
190 };
191 }
192
193 private void applyShockwave( PhysicsObject target, Vector distance )
194 {
195 double distanceFromEdge = distance.Magnitude - CurrentRadius;
196 if ( distanceFromEdge >= 0 )
197 return;
198
199 double relDistance = ( CurrentRadius + distanceFromEdge ) / CurrentRadius;
200 double shockQuotient = 1 / Math.Pow( relDistance, 2 );
201 double shockForce = Force * shockQuotient;
202
203 if ( Math.Abs( shockForce ) > float.Epsilon )
204 {
205 Vector shockVector = Vector.FromLengthAndAngle( shockForce, distance.Angle );
206 target.Hit( shockVector );
207
208 if ( !shockwaveHitObjects.Contains( target ) )
209 {
210 OnShockwaveReachesObject( target, shockVector );
211 shockwaveHitObjects.Add( target );
212 }
213 }
214 }
215
220 public override void Update( Time time )
221 {
222 // this is done only once, after being added to the game.
223 if ( !initialized )
224 {
225 PlaySound();
226 shockwaveHitObjects.Clear();
227 initialized = true;
228 }
229
230 if ( CurrentRadius > MaxRadius )
231 {
232 this.Destroy();
233 return;
234 }
235
236 double dt = time.SinceLastUpdate.TotalSeconds;
237 CurrentRadius += dt * Speed;
238 shockwaveHitObjects.Update( time );
239
240 if ( UseShockWave )
241 {
242 if ( Force > 0 )
243 {
245 }
246
247 foreach ( var layer in Jypeli.Game.Instance.Layers )
248 {
249 foreach ( var o in layer.Objects )
250 {
251 if ( o is PhysicsObject )
252 {
254
255 if ( po.IgnoresExplosions )
256 {
257 // No shockwave
258 continue;
259 }
260
261 // Shockwave
262 Vector distance = o.Position - this.Position;
263 applyShockwave( po, distance );
264 }
265 }
266 }
267 }
268
269 base.Update( time );
270 }
271
272 private void PlaySound()
273 {
274 if ( Sound == null )
275 return;
276
277 // play the sound
278 double pitch = RandomGen.NextDouble( -0.1, 0.1 ); // add some variation to explosion sound
279 double pan = this.Position.X / ( Game.Screen.Width / 2 ); // sound comes from left or right speaker
280 pan = AdvanceMath.MathHelper.Clamp( (float)pan, (float)-1.0, (float)1.0 );
281 if ( !double.IsNaN( pan ) ) // sometimes pan can be Nan, that is why this check is here
282 {
283 Sound.Play(Volume, pitch, pan );
284 }
285 }
286 }
287}
static Scalar Clamp(Scalar value, Scalar min, Scalar max)
Definition: MathHelper.cs:111
Color ShockwaveColor
Paineaallon väri. Shockwave.Color = Color.White
Definition: Explosion.cs:80
Explosion(double radius)
Luo uuden räjähdyksen.
Definition: Explosion.cs:124
double Force
Voima, jolla räjähdyksen paineaallon uloin reuna heittää olioita räjähdyksestä poispäin....
Definition: Explosion.cs:94
GameObject shockWave
Definition: Explosion.cs:43
double MaxRadius
Suurin säde, johon räjähdys voi kasvaa.
Definition: Explosion.cs:54
SynchronousList< PhysicsObject > shockwaveHitObjects
Definition: Explosion.cs:39
Explosion(Explosion src)
Luo uuden räjähdyksen entisen pohjalta.
Definition: Explosion.cs:111
void applyShockwave(PhysicsObject target, Vector distance)
Definition: Explosion.cs:193
void AddShockwaveHandler(IPhysicsObject o, Action< IPhysicsObject, Vector > handler)
Laukaisee aliohjelman handler, kun tämän räjähdyksen paineaalto osuu olioon o.
Definition: Explosion.cs:162
Action< IPhysicsObject, Vector > ShockwaveReachesObject
Tapahtuu, kun paineaalto osuu peliolioon.
Definition: Explosion.cs:105
double Speed
Räjähdyksen leviämisnopeus (pikseliä sekunnissa)
Definition: Explosion.cs:88
bool UseShockWave
Onko paineaalto käytössä.
Definition: Explosion.cs:49
double Volume
Kuinka voimakas räjähdyksestä tuleva ääni on, väliltä 0-1.0. Oletusarvona 0.2.
Definition: Explosion.cs:100
static Image commonImage
Definition: Explosion.cs:40
override void Update(Time time)
Ajetaan kun pelitilannetta päivitetään. Päivityksen voi toteuttaa omassa luokassa toteuttamalla tämän...
Definition: Explosion.cs:220
double CurrentRadius
Räjähdyksen nykyinen säde.
Definition: Explosion.cs:65
static SoundEffect commonSound
Definition: Explosion.cs:41
void AddShockwaveHandler(string tag, Action< IPhysicsObject, Vector > handler)
Laukaisee aliohjelman handler, kun tämän räjähdyksen paineaalto osuu olioon o.
Definition: Explosion.cs:179
void OnShockwaveReachesObject(IPhysicsObject obj, Vector swForce)
Definition: Explosion.cs:151
static Image LoadImageFromResources(string name)
Lataa kuvan Jypelin sisäisistä resursseista.
Definition: Content.cs:91
static SoundEffect LoadSoundEffectFromResources(string name)
Lataa ääniefektin Jypelin sisäisistä resursseista.
Definition: Content.cs:167
SynchronousList< Layer > Layers
Kerrokset, joilla pelioliot viihtyvät.
Definition: Layers.cs:14
static Game Instance
Käynnissä olevan pelin pääolio.
Definition: Game.cs:96
static void AssertInitialized(Action actionMethod)
Suorittaa aliohjelman kun peli on varmasti alustettu.
static ScreenView Screen
Näytön dimensiot, eli koko ja reunat.
Definition: Graphics.cs:90
Pelialueella liikkuva olio. Käytä fysiikkapeleissä PhysicsObject-olioita.
Definition: Appearance.cs:34
override Vector?? Position
Definition: Dimensions.cs:72
GameObject(double width, double height)
Alustaa uuden peliolion.
Definition: GameObject.cs:79
override void Destroy()
Tuhoaa olion. Tuhottu olio poistuu pelistä.
Definition: GameObject.cs:55
override Vector Size
Olion koko pelimaailmassa. Kertoo olion äärirajat, ei muotoa.
Definition: Dimensions.cs:44
void Add(IGameObject childObject)
Lisää annetun peliolion tämän olion lapseksi. Lapsiolio liikkuu tämän olion mukana.
Definition: ChildObjects.cs:98
virtual Color Color
Väri, jonka värisenä olio piirretään, jos tekstuuria ei ole määritelty.
Definition: Appearance.cs:65
bool IsUpdated
Tarvitseeko olio päivittämistä. Kun perit oman luokkasi tästä luokasta, aseta tämä arvoon true,...
Kuva.
Definition: Image.cs:30
Kappale joka noudattaa fysiikan lakeja, johon voi törmätä. Vaatii että käytössä on fysiikkapeli.
Definition: Collisions.cs:7
bool IgnoresExplosions
Jättääkö räjähdysten paineaallon huomioimatta
virtual void Hit(Vector impulse)
Kohdistaa kappaleeseen impulssin. Tällä kappaleen saa nopeasti liikkeeseen.
Definition: Movement.cs:90
Satunnaisgeneraattori. Luo satunnaisia arvoja, mm. lukuja, vektoreita sekä kulmia.
Definition: RandomGen.cs:39
static double NextDouble(double min, double max)
Palauttaa satunnaisen liukuluvun parametrien
Definition: RandomGen.cs:70
double Width
Näytön leveys x-suunnassa.
Definition: View.cs:222
Kuvio.
Definition: Shapes.cs:47
static readonly Ellipse Circle
Ympyrä tai ellipsi.
Definition: Shapes.cs:63
Ääniefekti. Yhdestä efektistä voi luoda CreateSound-metodilla monta ääntä (Sound),...
Definition: SoundEffect.cs:17
Yleinen äänen toistamiseen käytettävä luokka. Tällä ei ole kovin suuria eroja SoundEffect-luokan kans...
Definition: Sound.cs:11
void Play(int retries=3)
Toistaa äänen
Definition: Sound.cs:80
Synkroninen lista, eli lista joka päivittyy vasta kun sen Update-metodia kutsutaan....
Yhteinen rajapinta kaikille fysiikkaolioille.
object Tag
Olion tagi, voi olla mitä tahansa
Definition: Tagged.cs:11
Väri.
Definition: Color.cs:13
Sisältää tiedon ajasta, joka on kulunut pelin alusta ja viime päivityksestä.
Definition: Time.cs:14
TimeSpan SinceLastUpdate
Aika joka on kulunut viime päivityksestä.
Definition: Time.cs:27
2D-vektori.
Definition: Vector.cs:67
double X
Vektorin X-komponentti.
Definition: Vector.cs:334
Angle Angle
Kulma radiaaneina.
Definition: Vector.cs:372
double Magnitude
Vektorin pituus.
Definition: Vector.cs:345
static Vector FromLengthAndAngle(double length, double angle)
Luo vektorin pituuden ja kulman perusteella.
Definition: Vector.cs:114