/* * Wormhole.cs * Authors: August Zinsser, Adam Nabinger * 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 Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace MaritimeDefender { /// /// Creates wormholes in the meteor madness game. /// The player can connect to a wormhole with their "wormhole connector beam." /// The wormhole disappears from memory after fading out several seconds after connection, leaving /// the meteor madness game to spawn a UFO in its location. /// internal class Wormhole : Collidable { #region Constants // Constant for how fast the wormhole is rotating. private const float mRotationSpeed = MathHelper.PiOver2; #endregion #region Fields // Whether the wormhole is opening for the player or for an enemy/friendly ship. private readonly bool mIsPlayer; // Holds the original spawning position so UFOs can spawn where the wormhole initially appeared. private readonly float mSpawnedArcPosition; // Whether the wormhole is visible or not. private bool mVisible; // Whether or not the wormhole is currently fading in/out. private bool mFading; // Whether the wormhole is currently fading in or fading out. private bool mFadeIn; // Counter for the current life of the fade in/out effect. private float mFadeCounter; // Total duration of time for the fade in/out effect. private float mFadeLifeSpan; // The opacity of the wormhole. Used for fade in/out effect. private float opacity; // Rotational position of the base wormhole layer private float mAngle1; // Rotational position of the middle wormhole layer private float mAngle2; // Texture for the base wormhole layer private Texture2D mLayer1; // Texture for the middle wormhole layer private Texture2D mLayer2; // Color of the base wormhole layer private Color mColor1 = Color.White; // Color of the middle wormhole layer private Color mColor2 = Color.White; // Position of the base wormhole layer in terms of x,y coordinates. private Vector2 mOrigin1; // Position of the middle wormhole layer in terms of x,y coordinates. private Vector2 mOrigin2; // Size of the wormhole in terms of width, height, and depth. private Vector3 mSpace3DSize; #endregion #region Properties /// /// Gets the size of the wormhole in terms of width, height, and depth. /// public override Vector3 Size { get { return mSpace3DSize; } } /// /// Position of the wormhole along the outside circular perimeter /// public float SpawnedArcPosition { get { return mSpawnedArcPosition; } } /// /// Gets/Sets the width of the wormhole. /// public override float Width { get { return mSpace3DSize.X; } set { mSpace3DSize.X = value; } } /// /// Gets/Sets the height of the wormhole. /// public override float Height { get { return mSpace3DSize.Y; } set { mSpace3DSize.Y = value; } } /// /// Gets/Sets whether the wormhole is visible or not. /// public bool Visible { get { return mVisible; } set { mVisible = value; } } #endregion #region Creation /// /// Constructor /// /// Width of the wormhole /// Height of the wormhole /// Depth of the wormhole /// Position of the wormhole along the outside circular perimeter /// Whether the wormhole is for the player or for an enemy/friendly ship internal Wormhole(float width, float height, float depth, float spawnedArcPosition, bool isPlayer) { mSpace3DSize = new Vector3(width, height, depth); mSpawnedArcPosition = spawnedArcPosition; mIsPlayer = isPlayer; } #endregion #region Management /// /// Loads in any necessary information for all content dependent objects /// /// Reference to the current content manager for loading content internal void LoadContent(Microsoft.Xna.Framework.Content.ContentManager content) { mLayer1 = content.Load(@"MiniGames\WormholeP"); mLayer2 = mIsPlayer ? content.Load(@"MiniGames\WormholeG") : content.Load(@"MiniGames\WormholeR"); mOrigin1 = new Vector2(mLayer1.Width >> 1, mLayer1.Height >> 1); mOrigin2 = new Vector2(mLayer2.Width >> 1, mLayer2.Height >> 1); } #endregion #region Update /// /// Performs necessary logic, including position and rotation updates /// /// Time that has passed in game internal void Update(GameTime gameTime) { float dt = (float)gameTime.ElapsedGameTime.TotalSeconds; mAngle1 += mRotationSpeed * dt; mAngle2 += mRotationSpeed * 1.75F * dt; if (mAngle1 >= MathHelper.TwoPi) { mAngle1 -= MathHelper.TwoPi; } if (mAngle2 >= MathHelper.TwoPi) { mAngle2 -= MathHelper.TwoPi; } // Update fading if (mFading) { if (mFadeIn) { mFadeCounter -= dt; if (mFadeCounter >= 0) { opacity = 1.0F - (mFadeCounter / mFadeLifeSpan); } else { mFadeCounter = 0; opacity = 1.0F; mFading = false; } mVisible = true; } else { mFadeCounter -= dt; if (mFadeCounter >= 0) { opacity = mFadeCounter / mFadeLifeSpan; } else { opacity = 0; mFadeCounter = 0; mVisible = false; mFading = false; } } mColor1 = new Color(255, 255, 255, (byte)(Math.Max(opacity - .25f, 0f) * 255)); mColor2 = new Color(255, 255, 255, (byte)(Math.Max(opacity - .50f, 0f) * 255)); } } #endregion #region Render /// /// Renders the wormhole and its individual layers /// /// Reference to the current spritebatch for rendering sprites /// Reference to the gameboard for graphical dimensions and positions internal void Draw(SpriteBatch spriteBatch, Space3D gameBoard) { // Ignore drawing invisible wormholes if (!mVisible) { return; } // Project into screen coordinates Rectangle projected = Space3D.Project(Position.X, Position.Y, Position.Z, mSpace3DSize.X, mSpace3DSize.Y); // Draw all layers float depth = Position.Z - gameBoard.MinZ + Space3D.mMeteorCameraFocalLength; float depthRange = gameBoard.MaxZ - gameBoard.MinZ + Space3D.mMeteorCameraFocalLength; // Layer 1 spriteBatch.Draw( mLayer1, projected, null, mColor1, mAngle1, mOrigin1, SpriteEffects.None, 1F * depth / depthRange ); // Layer 2 spriteBatch.Draw( mLayer2, new Rectangle(projected.X, projected.Y, (int)(projected.Width * .80f), (int)(projected.Height * .80f)), null, mColor2, mAngle2, mOrigin2, SpriteEffects.None, .9999F * depth / depthRange ); } #endregion #region Fade /// /// Sets the wormhole to fade in with a total fade time equal to the given amount of seconds /// /// The duration of time in which the wormhole will fade in internal void FadeIn(float seconds) { mFading = true; mFadeIn = true; opacity = 0F; mFadeCounter = seconds; mFadeLifeSpan = seconds; } /// /// Sets the wormhole to fade out with a total fade time equal to the given amount of seconds /// /// The duration of time in which the wormhole will fade out internal void FadeOut(float seconds) { mFading = true; mFadeIn = false; opacity = 1F; mFadeCounter = seconds; mFadeLifeSpan = seconds; } #endregion } }