/* * PrimitiveLine.cs * Authors: Mike Dapiran * 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; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Util; namespace ColonySim { /// /// A class to make primitive 2D objects out of lines. /// public class PrimitiveLine : DrawableGameScreenComponent { #region Fields // Pixel texture used to render line private readonly Texture2D pixel; // List of vector private readonly ArrayList vectors; // The sprite batch used for rendering private readonly SpriteBatch spriteBatch; /// /// Gets/sets the colour of the primitive line object. /// public Color Colour; /// /// Gets/sets the position of the primitive line object. /// public Vector2 Position; /// /// Gets/sets the render depth of the primitive line object (0 = front, 1 = back) /// public float Depth; /// /// Whether or not this could auto clear /// public bool AutoClear = true; #endregion #region Properties /// /// Gets the number of vectors which make up the primtive line object. /// public int CountVectors { get { return vectors.Count; } } #endregion #region Creation /// /// Creates a new primitive line object. /// /// The Graphics Device object to use. /// The sprite batch to render with public PrimitiveLine(GraphicsDevice graphicsDevice, SpriteBatch pSpriteBatch) { // create pixels pixel = new Texture2D(graphicsDevice, 1, 1, 1, TextureUsage.None, SurfaceFormat.Color); Color[] pixels = new Color[1]; pixels[0] = Color.White; pixel.SetData(pixels); Colour = Color.White; Position = new Vector2(0, 0); Depth = 0; vectors = new ArrayList(); spriteBatch = pSpriteBatch; } #endregion #region Render /// /// Renders the primtive line object. /// /// Time that has passed in game so far public override void Draw(GameTime gameTime) { if (vectors.Count < 2) return; for (int i = 1; i < vectors.Count; i++) { Vector2 vector1 = (Vector2)vectors[i - 1]; Vector2 vector2 = (Vector2)vectors[i]; // calculate the distance between the two vectors float distance = Vector2.Distance(vector1, vector2); // calculate the angle between the two vectors float angle = (float)Math.Atan2(vector2.Y - vector1.Y, vector2.X - vector1.X); // stretch the pixel between the two vectors spriteBatch.Begin(); spriteBatch.Draw(pixel, Position + vector1, null, Colour, angle, Vector2.Zero, new Vector2(distance, 1), SpriteEffects.None, Depth); spriteBatch.End(); } if (AutoClear) { ClearVectors(); } } #endregion #region Vector Modifiers /// /// Adds a vector to the primive live object. /// /// The vector to add. public void AddVector(Vector2 vector) { vectors.Add(vector); } /// /// Insers a vector into the primitive line object. /// /// The index to insert it at. /// The vector to insert. public void InsertVector(int index, Vector2 vector) { vectors.Insert(index, vectors); } /// /// Removes a vector from the primitive line object. /// /// The vector to remove. public void RemoveVector(Vector2 vector) { vectors.Remove(vector); } /// /// Removes a vector from the primitive line object. /// /// The index of the vector to remove. public void RemoveVector(int index) { vectors.RemoveAt(index); } /// /// Clears all vectors from the primitive line object. /// public void ClearVectors() { vectors.Clear(); } #endregion #region Util /// /// Creates a circle at the given position with the given radius. /// /// The position origin of the circle /// The radius (half the width) of the circle. /// The number of sides on the circle (the more the detailed). public void CreateCircle(Vector2 position, float radius, int sides) { vectors.Clear(); const float max = MathHelper.TwoPi; float step = max / sides; for (float theta = 0; theta < max; theta += step) { vectors.Add(position + new Vector2(radius * (float)Math.Cos(theta), radius * (float)Math.Sin(theta))); } // then add the first vector again so it's a complete loop vectors.Add(position + new Vector2(radius * (float)Math.Cos(0), radius * (float)Math.Sin(0))); } #endregion } }