Jypeli  5
The simple game programming library
Weapon.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 
30 using System;
31 
32 namespace Jypeli.Assets
33 {
37  public abstract class Weapon : GameObject
38  {
39  private TimeSpan timeOfLastUse;
40 
45  public virtual bool IsReady
46  {
47  get
48  {
49  return ( Ammo > 0 ) && ( ( Game.Time.SinceStartOfGame - timeOfLastUse ) > TimeBetweenUse );
50  }
51  }
52 
56  public bool CanHitOwner { get; set; }
57 
61  public DoubleMeter Power { get; protected set; }
62 
66  public IntMeter Ammo { get; protected set; }
67 
71  public bool InfiniteAmmo
72  {
73  get { return Ammo.Value == Int32.MaxValue; }
74  set
75  {
76  if ( !value && Ammo.Value == Int32.MaxValue )
77  Ammo.Value = 100;
78  else if ( value )
79  Ammo.Value = Int32.MaxValue;
80  }
81  }
82 
86  public bool AmmoIgnoresGravity { get; set; }
87 
91  public bool AmmoIgnoresExplosions { get; set; }
92 
97  public TimeSpan MaxAmmoLifetime { get; set; }
98 
102  public SoundEffect AttackSound { get; set; }
103 
107  public TimeSpan TimeBetweenUse { get; set; }
108 
112  public double FireRate
113  {
114  get { return 1 / TimeBetweenUse.TotalSeconds; }
115  set
116  {
117  if (value < 0) throw new ArgumentException("Fire rate cannot be negative!");
118  if (value == 0) TimeBetweenUse = TimeSpan.MaxValue;
119  else TimeBetweenUse = TimeSpan.FromSeconds( 1 / value );
120  }
121  }
122 
128  public event Action<PhysicsObject> Shooting;
129 
130  protected void OnShooting( PhysicsObject projectile )
131  {
132  if ( Shooting != null )
133  Shooting( projectile );
134  }
135 
139  public CollisionHandler<PhysicsObject, PhysicsObject> ProjectileCollision { get; set; }
140 
146  public Weapon( double width, double height )
147  : base( width, height )
148  {
150  Power = new DoubleMeter( 0 );
151  Power.MinValue = 0;
152  Ammo = new IntMeter( Int32.MaxValue, 0, Int32.MaxValue );
153  Ammo.MinValue = 0;
154  MaxAmmoLifetime = TimeSpan.MaxValue;
155  }
156 
162  protected abstract PhysicsObject CreateProjectile();
163 
175  {
176  if ( IsReady )
177  {
178  timeOfLastUse = Game.Time.SinceStartOfGame;
179 
180  if (AttackSound != null)
181  AttackSound.Play();
182 
183  PhysicsObject p = CreateProjectile();
184 
185  SetCollisionHandler( p, ProjectileCollision );
186  p.IgnoresGravity = AmmoIgnoresGravity;
187  p.IgnoresExplosions = AmmoIgnoresExplosions;
188  p.MaximumLifetime = MaxAmmoLifetime;
189  ShootProjectile( p, Power.Value );
190  if ( !InfiniteAmmo ) Ammo.Value--;
191  Power.Reset();
192  OnShooting( p );
193 
194  return p;
195  }
196 
197  return null;
198  }
199 
200  protected void ShootProjectile( PhysicsObject projectile, double power )
201  {
202  if ( !IsAddedToGame )
203  return;
204 
205  Vector impulse = Vector.FromLengthAndAngle( power, AbsoluteAngle );
206  Vector direction = Vector.FromLengthAndAngle( 1.0, AbsoluteAngle );
207  Vector position = this.Position;
208 
209  if ( Parent != null )
210  {
211  //0.75 * max(width, height) -> projectiles don't hit the PlatformCharacter's collisionHelpers.
212  //Would be better to choose the width or height manually based on the direction.
213  position = this.AbsolutePosition + direction * 0.75 * ( Math.Max(this.Parent.Width, this.Parent.Height) );
214  }
215 
216  projectile.Position = position;
217  projectile.Angle = this.AbsoluteAngle;
218 
219  if ( Parent is PhysicsObject && !CanHitOwner )
220  {
221  // The projectile can not hit the owner of the weapon.
222  // Owner's CollisionIgnorer can be null if no CollisionIgnorer is set for the owner
223  // Must set CollisionIgnorer separetly for PlatformCharacter because of it's CollisionHelpers
224  PhysicsObject physParent = (PhysicsObject)Parent;
225  if (physParent.Body.CollisionIgnorer == null)
226  {
227  if (physParent is PlatformCharacter)
228  (physParent as PlatformCharacter).CollisionIgnorer = new Physics2DDotNet.Ignorers.ObjectIgnorer();
229  else
230  physParent.Body.CollisionIgnorer = new Physics2DDotNet.Ignorers.ObjectIgnorer();
231  }
232  projectile.Body.CollisionIgnorer = physParent.Body.CollisionIgnorer;
233  }
234 
235  Game.Instance.Add( projectile );
236  projectile.Hit( impulse );
237  }
238 
240  {
241  if ( handler == null )
242  return;
243 
244  if ( Game.Instance is PhysicsGameBase )
245  {
246  PhysicsGameBase pg = (PhysicsGameBase)Game.Instance;
247  pg.AddCollisionHandler( projectile, handler );
248  }
249  else
250  throw new InvalidOperationException( "Cannot set a collision handler to non-physics game!" );
251  }
252  }
253 }
void AddCollisionHandler(IPhysicsObject obj, CollisionHandler< IPhysicsObject, IPhysicsObject > handler)
Määrää, mihin aliohjelmaan siirrytään kun yleinen fysiikkaolio
Kuvio.
Definition: Shapes.cs:48
TimeSpan MaximumLifetime
Olion suurin mahdollinen elinaika. Kun Lifetime on suurempi kuin tämä, olio kuolee.
static readonly Rectangle Rectangle
Suorakulmio.
Definition: Shapes.cs:72
bool IgnoresGravity
Jättääkö olio painovoiman huomioimatta.
TimeSpan SinceStartOfGame
Aika joka on kulunut pelin alusta.
Definition: Time.cs:32
Ääniefekti. Yhdestä efektistä voi luoda CreateSound-metodilla monta ääntä (Sound), jotka voivat soida yhtäaikaa. Ääntä ei tarvitse kuitenkaan luoda itse, jos vain kutsuu Play-metodia.
Definition: SoundEffect.cs:15
void OnShooting(PhysicsObject projectile)
Definition: Weapon.cs:130
Peliolio, joka noudattaa fysiikkamoottorin määräämiä fysiikan lakeja. Voidaan kuitenkin myös laittaa ...
Definition: Coefficients.cs:36
static Game Instance
Definition: Game.cs:149
override Angle Angle
Kulma, jossa olio on. Oliota voi pyörittää kulmaa vaihtamalla.
Definition: Dimensions.cs:80
Action< PhysicsObject > Shooting
Tapahtumankäsittelijä ampumiselle, parametrinä ammus. Voit antaa kaikille aseesta lähteville ammuksil...
Definition: Weapon.cs:128
Mittari, joka mittaa double-tyyppisiä arvoja. Sidottavissa näyttöihin, kuten ValueDisplay ja BarGauge...
Definition: Meter.cs:515
void ShootProjectile(PhysicsObject projectile, double power)
Definition: Weapon.cs:200
void SetCollisionHandler(PhysicsObject projectile, CollisionHandler< PhysicsObject, PhysicsObject > handler)
Definition: Weapon.cs:239
void Add(IGameObject o)
Lisää olion peliin. Tavalliset oliot tulevat automaattisesti kerrokselle 0 ja ruutuoliot päällimmäise...
Definition: Game.cs:691
virtual void Hit(Vector impulse)
Kohdistaa kappaleeseen impulssin. Tällä kappaleen saa nopeasti liikkeeseen.
Definition: Movement.cs:147
Peliluokka reaaliaikaisille peleille.
Definition: DebugScreen.cs:10
Weapon(double width, double height)
Luo uuden aseen.
Definition: Weapon.cs:146
Mittari, joka mittaa int-tyyppisiä arvoja. Sidottavissa näyttöihin, kuten ValueDisplay ja BarGauge...
Definition: Meter.cs:387
Body Body
Fysiikkamoottorin käyttämä tietorakenne.
Definition: Dimensions.cs:42
Kantaluokka fysiikkapeleille.
Tasohyppelypelin hahmo. Voi liikkua ja hyppiä. Lisäksi sillä voi olla ase.
override Vector Position
Olion paikka koordinaatistossa. Käsittää sekä X- että Y-koordinaatin.
Definition: Dimensions.cs:49
bool IgnoresExplosions
Jättääkö olio räjähdyksen paineaallon huomiotta.
static Time Time
Peliaika. Sisältää tiedon siitä, kuinka kauan peliä on pelattu (Time.SinceStartOfGame) ja kuinka kaua...
Definition: Game.cs:309
2D-vektori.
Definition: Vector.cs:56
Kokoelma valmiita törmäyksenkäsittelijöitä.
Pelialueella liikkuva olio. Käytä fysiikkapeleissä PhysicsObject-olioita.
Definition: __GameObject.cs:54
PhysicsObject Shoot()
Ampuu aseella, ja palauttaa ammuksen tai null, jos ampuminen ei onnistu (esimerkiksi jos panokset ova...
Definition: Weapon.cs:174