/* * 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 } }