Projectile.cs 5.3 KB

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