/*
* EntitySpawnable.cs
* Author: Mike DeMauro
* Copyright (c) 2007-2008 Cornell University
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using System.Collections.Generic;
using System.Text;
using tAC_Engine.Graphics.Entities;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Random=Util.Random;
namespace StellarProspector
{
///
/// An EntitySprite with states, times, and spawning limits.
///
internal class EntitySpawnable : EntitySprite
{
///
/// Different states to label functionality of an EntitySpawnable
///
public enum SpawnableState
{
///
/// The spawnable is currently dead
///
Dead,
///
/// The spawnable is currently alive
///
Alive,
///
/// The spawnable is currently waiting to spawn
///
Waiting,
///
/// The spawnable is currently being collected/removed
///
Suspended
}
#region Fields
///
/// The current state of the EntitySpawnable.
///
protected SpawnableState mState = SpawnableState.Dead;
///
/// The origin of the spawning circle in SpriteBatch coordinates.
///
protected Vector2 mOrigin = Vector2.Zero;
///
/// The angle in degrees that this spawnable is located at
///
protected double mTheta;
///
/// The length of time to display
///
protected double mLifeTime;
///
/// The maximum length of time to display
///
protected double mMaxLifeTime;
///
/// The length of time to wait before spawning
///
protected double mWaitTime;
///
/// The maximum length of time to wait before spawning
///
protected double mMaxWaitTime = double.PositiveInfinity;
///
/// The minimum length of time to wait before spawning
///
protected double mMinWaitTime;
///
/// The angle of each sector
///
protected double mSectorAngle = MathHelper.PiOver4;
///
/// The sector the entity is currently in
///
protected int mSector;
///
/// The distance in pixels from the center this spawnable is located at
///
protected int mRadialDistance;
///
/// The minimum radius of the spawning circle
///
protected int mMinSpawnRadius;
///
/// The maximum radius of the spawning circle
///
protected int mMaxSpawnRadius;
///
/// The number of sectors in the spawning circle
///
protected int mNumSectors;
///
/// The score to collect
///
protected int mProgressToCollect;
#endregion
#region Properties
///
/// Gets the angle in degrees that this spawnable is located at
///
public double Theta { get { return mTheta + (double)MathHelper.PiOver2; } }
///
/// Gets the sector the entity is currently in
///
public int Sector { get { return mSector; } }
///
/// Gets the distance in pixels from the center this spawnable is located at
///
public int RadialDistance { get { return mRadialDistance; } }
///
/// Gets/Sets the current state of the EntitySpawnable.
///
public SpawnableState State
{
get { return mState; }
set { mState = value; }
}
///
/// Gets/Sets the origin of the spawning circle in SpriteBatch coordinates.
///
public Vector2 Origin
{
get { return mOrigin; }
set { mOrigin = value; }
}
///
/// Gets/Sets the length of time to display.
///
public double LifeTime
{
get { return mLifeTime; }
set { mLifeTime = value; }
}
///
/// Gets/Sets the maximum length of time to display.
///
public double MaxLifeTime
{
get { return mMaxLifeTime; }
set { mMaxLifeTime = value; }
}
///
/// Gets/Sets the length of time to wait before spawning.
///
public double WaitTime
{
get { return mWaitTime; }
set { mWaitTime = value; }
}
///
/// Gets/Sets the maximum length of time to wait before spawning.
///
public double MaxWaitTime
{
get { return mMaxWaitTime; }
set { mMaxWaitTime = value; }
}
///
/// Gets/Sets the minimum length of time to wait before spawning.
///
public double MinWaitTime
{
get { return mMinWaitTime; }
set { mMinWaitTime = value; }
}
///
/// Gets/Sets the angle of each sector.
///
public double SectorAngle
{
get { return mSectorAngle; }
set { mSectorAngle = value; }
}
///
/// Gets/Sets the minimum radius of the spawning circle.
///
public int MinSpawnRadius
{
get { return mMinSpawnRadius; }
set { mMinSpawnRadius = value; }
}
///
/// Gets/Sets the maximum radius of the spawning circle.
///
public int MaxSpawnRadius
{
get { return mMaxSpawnRadius; }
set { mMaxSpawnRadius = value; }
}
///
/// Gets/Sets the number of sectors in the spawning circle.
///
public int NumSectors
{
get { return mNumSectors; }
set { mNumSectors = value; }
}
///
/// Gets/Sets the score to collect.
///
public int ProgressToCollect
{
get { return mProgressToCollect; }
set { mProgressToCollect = value; }
}
#endregion
#region Creation
///
/// Creates a new EntitySpawnable
///
/// The ContentManager used to load content.
/// The name of the texture to load.
public EntitySpawnable(ContentManager content, string textureName)
: base(content, textureName) { }
#endregion
#region Update
///
/// Updates the EntitySpawnable. This should be called by XNA.
///
/// Amount of time that has passed in game
public override void Update(GameTime gameTime)
{
if (mState == SpawnableState.Alive)
{
mLifeTime -= gameTime.ElapsedGameTime.TotalMilliseconds;
if (mLifeTime <= 0)
{
Die();
}
}
else if(mState == SpawnableState.Waiting)
{
mWaitTime -= gameTime.ElapsedGameTime.TotalMilliseconds;
}
base.Update(gameTime);
}
#endregion
#region State Modifiers
///
/// Sets the state to Alive
///
/// The sector number to spawn in.
/// If the stimulus can spawn outside the given sector
public virtual void Spawn(int sectorNum, bool errorEnabled)
{
mSector = sectorNum;
mState = SpawnableState.Alive;
}
///
/// Sets the state to Dead
///
public virtual void Die()
{
mState = SpawnableState.Dead;
}
///
/// Sets the state to Waiting. Remains in this state until a
/// random amount of time between MinWaitTime and MaxWaitTime has elapsed
///
public void Wait()
{
mState = SpawnableState.Waiting;
mWaitTime = Random.NextDouble(mMinWaitTime, mMaxWaitTime);
}
#endregion
#region Calculations
///
/// The angle between the stimulus' position vector on screen and the distance of the player from the screen vector
///
public double Rho(double resolution)
{
return Math.Atan(Math.Sqrt((Util.Settings.PhysicalScreenHeight * Util.Settings.PhysicalScreenHeight) +
(Util.Settings.PhysicalScreenHeight * Util.Settings.PhysicalScreenHeight)) *
(mRadialDistance / resolution) / Util.Settings.PhysicalScreenDistance);
}
///
/// Calculates the angle between the stimulus' x vector on screen and the distance of the player from the screen vector
///
/// The width of the screen in pixels
/// The offset from the top of the screen to the origin
/// The angle between the stimulus' x vector on screen and the distance of the player from the screen vector
public double AzimuthPhi(int xResolution, float xOffset)
{
return Math.Atan(Util.Settings.PhysicalScreenWidth * (X - xOffset) / Util.Settings.PhysicalScreenDistance);
}
///
/// Calculates the angle between the stimulus' y vector on screen and the distance of the player from the screen vector
///
/// The height of the screen in pixels
/// The offset from the of the left edge of the screen to the origin
/// The angle between the stimulus' y vector on screen and the distance of the player from the screen vector
public double ElevationLambda(int yResolution, float yOffset)
{
return Math.Atan(Util.Settings.PhysicalScreenHeight * (Y - yOffset) / Util.Settings.PhysicalScreenDistance);
}
#endregion
}
}