Projectile.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // Projectile.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Graphics;
  13. #endregion
  14. namespace NetRumble
  15. {
  16. /// <summary>
  17. /// Base public class for all projectiles that exist in the game.
  18. /// </summary>
  19. abstract public class Projectile : GameplayObject
  20. {
  21. #region Gameplay Data
  22. /// <summary>
  23. /// The player who fired this projectile.
  24. /// </summary>
  25. protected Ship owner;
  26. public Ship Owner
  27. {
  28. get { return owner; }
  29. }
  30. /// <summary>
  31. /// The amount that this projectile hurts it's target and those around it.
  32. /// </summary>
  33. protected float damageAmount = 0f;
  34. /// <summary>
  35. /// The radius at which this projectile hurts others when it explodes.
  36. /// </summary>
  37. protected float damageRadius = 0f;
  38. /// <summary>
  39. /// If true, this object will damage it's owner if it hits it
  40. /// </summary>
  41. protected bool damageOwner = true;
  42. /// <summary>
  43. /// The amount of time before this projectile dies on it's own.
  44. /// </summary>
  45. protected float duration = 0f;
  46. #endregion
  47. #region Initialization Methods
  48. /// <summary>
  49. /// Constructs a new projectile.
  50. /// </summary>
  51. /// <param name="owner">The ship that fired this projectile.</param>
  52. /// <param name="direction">The initial direction for this projectile.</param>
  53. protected Projectile(Ship owner, Vector2 direction)
  54. : base()
  55. {
  56. // safety-check the parameter
  57. if (owner == null)
  58. {
  59. throw new ArgumentNullException("owner");
  60. }
  61. // apply the parameters
  62. this.owner = owner;
  63. this.velocity = direction; // speed will be applied in the subclass
  64. // initialize the graphics data
  65. this.position = owner.Position;
  66. this.rotation = (float)Math.Acos(Vector2.Dot(Vector2.UnitY, direction));
  67. if (direction.X > 0f)
  68. {
  69. this.rotation *= -1f;
  70. }
  71. }
  72. #endregion
  73. #region Updating Methods
  74. /// <summary>
  75. /// Update the projectile.
  76. /// </summary>
  77. /// <param name="elapsedTime">The amount of elapsed time, in seconds.</param>
  78. public override void Update(float elapsedTime)
  79. {
  80. // projectiles can "time out"
  81. if (duration > 0f)
  82. {
  83. duration -= elapsedTime;
  84. if (duration < 0f)
  85. {
  86. Die(null, false);
  87. }
  88. }
  89. base.Update(elapsedTime);
  90. }
  91. #endregion
  92. #region Drawing Methods
  93. /// <summary>
  94. /// Draw the projectile.
  95. /// </summary>
  96. /// <param name="elapsedTime">The amount of elapsed time, in seconds.</param>
  97. /// <param name="spriteBatch">The SpriteBatch object used to draw.</param>
  98. public abstract void Draw(float elapsedTime, SpriteBatch spriteBatch);
  99. #endregion
  100. #region Interaction
  101. /// <summary>
  102. /// Defines the interaction between this projectile and a target GameplayObject
  103. /// when they touch.
  104. /// </summary>
  105. /// <param name="target">The GameplayObject that is touching this one.</param>
  106. /// <returns>True if the objects meaningfully interacted.</returns>
  107. public override bool Touch(GameplayObject target)
  108. {
  109. // check the target, if we have one
  110. if (target != null)
  111. {
  112. // don't bother hitting any power-ups
  113. if (target is PowerUp)
  114. {
  115. return false;
  116. }
  117. // don't hit the owner if the damageOwner flag isn't set
  118. if ((this.damageOwner == false) && (target == owner))
  119. {
  120. return false;
  121. }
  122. // don't hit other projectiles from the same ship
  123. Projectile projectile = target as Projectile;
  124. if ((projectile != null) && (projectile.Owner == this.Owner))
  125. {
  126. return false;
  127. }
  128. // damage the target
  129. target.Damage(this, this.damageAmount);
  130. }
  131. // either we hit something or the target is null - in either case, die
  132. Die(target, false);
  133. return base.Touch(target);
  134. }
  135. /// <summary>
  136. /// Kills this projectile, in response to the given GameplayObject.
  137. /// </summary>
  138. /// <param name="source">The GameplayObject responsible for the kill.</param>
  139. /// <param name="cleanupOnly">
  140. /// If true, the object dies without any further effects.
  141. /// </param>
  142. public override void Die(GameplayObject source, bool cleanupOnly)
  143. {
  144. if (active)
  145. {
  146. if (!cleanupOnly)
  147. {
  148. CollisionManager.Explode(this, source, damageAmount, Position,
  149. damageRadius, damageOwner);
  150. }
  151. }
  152. base.Die(source, cleanupOnly);
  153. }
  154. #endregion
  155. }
  156. }