#region File Description
//-----------------------------------------------------------------------------
// Projectile.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
#endregion
namespace Spacewar
{
///
/// Represents a projectile in SpacewarGame - retro or evolved
///
public class Projectile : SpacewarSceneItem
{
private static int[] projectileCount = new int[3];
///
/// Which player this projectile came from
///
private PlayerIndex player;
///
/// The damage that this bullet does
///
private int damage;
private double endTime;
private int projectileType;
private bool exploded = false;
private Particles particles;
private bool projectileArmed;
private Vector3 thrust;
#region Properties
public static int[] ProjectileCount
{
get
{
return projectileCount;
}
}
public int Damage
{
get
{
return damage;
}
}
#endregion
///
/// Cretes a new projectile
///
/// Instance of the game
/// Which player it came from
/// The start position
/// The start velocity
/// The direction its facing
/// The time the projectile was fired
public Projectile(Game game, PlayerIndex player, Vector3 position, Vector3 velocity, float angle, TimeSpan time, Particles particles)
: base(game)
{
this.player = player;
this.velocity = velocity;
this.position = position;
projectileCount[(int)player]++;
if (SpacewarGame.GameState == GameState.PlayEvolved)
{
projectileType = (int)SpacewarGame.Players[(int)player].ProjectileType;
this.particles = particles;
endTime = time.TotalSeconds + SpacewarGame.Settings.Weapons[projectileType].Lifetime;
thrust = Vector3.Multiply(Vector3.Normalize(velocity), SpacewarGame.Settings.Weapons[projectileType].Acceleration);
radius = 2;
damage = SpacewarGame.Settings.Weapons[projectileType].Damage;
if (SpacewarGame.GameState == GameState.PlayEvolved)
{
shape = new BasicEffectShape(GameInstance, BasicEffectShapes.Projectile, projectileType, LightingType.InGame);
//Evolved needs scaling
scale.X =
scale.Y =
scale.Z = SpacewarGame.Settings.BulletScale;
rotation.X = MathHelper.ToRadians(90);
rotation.Y = 0;
rotation.Z = (float)angle;
}
}
else
{
//Build up a retro weapon
damage = 5; //One shot kill
projectileType = (int)ProjectileType.Peashooter;
radius = 1;
endTime = time.TotalSeconds + 2.0;
acceleration = Vector3.Zero;
}
//Play 'shoot' sound
switch (projectileType)
{
case (int)ProjectileType.Peashooter:
Sound.PlayCue(Sounds.PeashooterFire);
break;
case (int)ProjectileType.MachineGun:
Sound.PlayCue(Sounds.MachineGunFire);
break;
case (int)ProjectileType.DoubleMachineGun:
Sound.PlayCue(Sounds.DoubleMachineGunFire);
break;
case (int)ProjectileType.Rocket:
Sound.PlayCue(Sounds.RocketExplode);
break;
case (int)ProjectileType.BFG:
Sound.PlayCue(Sounds.BFGFire);
break;
}
}
///
/// Updates the bullet. Removes it from scene when item is timed out
///
/// Current game time
/// Elapsed time since last update
public override void Update(TimeSpan time, TimeSpan elapsedTime)
{
//See if this bullets lifespan has expired
if (time.TotalSeconds > endTime)
{
//BFG explodes and has a blast radius
if (SpacewarGame.GameState == GameState.PlayEvolved && projectileType == 4 && !exploded)
{
Sound.PlayCue(Sounds.Explosion);
particles.AddExplosion(Position);
//We don't delete it this frame but we change the radius and the damage
exploded = true;
radius = 30;
damage = 3;
}
else
{
DeleteProjectile();
}
}
acceleration = thrust;
//For the rocket we need particles
if (projectileType == 3)
{
particles.AddRocketTrail(shape.World, new Vector2(acceleration.X, -acceleration.Y));
}
base.Update(time, elapsedTime);
}
public void DeleteProjectile()
{
if (!delete)
projectileCount[(int)player]--;
delete = true;
}
///
/// Checks if there is a collision between the this and the passed in item
///
/// A scene item to check
/// True if there is a collision
public override bool Collide(SceneItem item)
{
// Until we get collision meshes sorted just do a simple sphere (well circle!) check
float currentDistance = (Position - item.Position).Length();
bool colliding = base.Collide(item);
// For projectiles, do not allow them to destroy the ship that just fired them!
Ship shipItem = item as Ship;
if ((shipItem != null) && (shipItem.Player == player))
{
if (colliding && !projectileArmed)
{
colliding = false;
}
else if (!colliding && !projectileArmed)
{
// Once projectile is at least 2 ship radii away, it can arm!
// This is becuase the bolt launches with your velocity at the time
// and the ship can "catch up" to the bolt pretty easily if you are
// thrusting in the direction you are firing.
if (currentDistance > item.Radius * 2.0f)
projectileArmed = true;
}
}
return colliding;
}
}
}