Documentation added to Component.*, Entity, EntityManager, Grid, GUI.* and Utility classes.

Minor cleanups.
This commit is contained in:
Simon Holmberg
2012-10-18 01:34:08 +02:00
parent c59ff9778a
commit 9f47ad9a57
14 changed files with 424 additions and 100 deletions
+34 -6
View File
@@ -8,25 +8,53 @@ using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow.Component
{
/// <summary>
/// Component for handling collisions.
/// Contains a rectangle which defines its hitbox.
/// </summary>
public class Collision : Component
{
/// <summary>
/// The collision rectangle.
/// </summary>
public Rectangle Rectangle;
public int Width;
public int Height;
/// <summary>
/// Width of the collision rectangle.
/// </summary>
public int Width
{
get { return this.Rectangle.Width; }
set { this.Rectangle.Width = value; }
}
/// <summary>
/// Height of the collision rectangle.
/// </summary>
public int Height
{
get { return this.Rectangle.Height; }
set { this.Rectangle.Height = value; }
}
/// <summary>
/// Create a collision component.
/// </summary>
/// <param name="parent">Parent entity.</param>
/// <param name="width">Width of the collision rectangle.</param>
/// <param name="height">Height of the collision rectangle.</param>
public Collision(Entity parent, int width, int height)
: base(parent)
{
this.Width = width;
this.Height = height;
this.Rectangle = new Rectangle(0, 0, width, height);
}
/// <summary>
/// Updates the position of the collision rectangle to the position of its parent entity.
/// </summary>
/// <param name="gameTime"></param>
public override void Update(GameTime gameTime)
{
Transform transform = this.Parent.GetComponent<Transform>();
var transform = this.Parent.GetComponent<Transform>();
this.Rectangle.X = (int)transform.World.X;
this.Rectangle.Y = (int)transform.World.Y;
}
@@ -6,8 +6,14 @@ using Microsoft.Xna.Framework;
namespace DepthsBelow.Component
{
/// <summary>
/// Base component.
/// </summary>
public class Component
{
/// <summary>
/// Parent entity of which the component belongs.
/// </summary>
public Entity Parent;
public Component(Entity parent)
@@ -15,6 +21,10 @@ namespace DepthsBelow.Component
Parent = parent;
}
/// <summary>
/// Virtual component update function.
/// </summary>
/// <param name="gameTime"></param>
public virtual void Update(GameTime gameTime)
{
@@ -8,14 +8,34 @@ using Microsoft.Xna.Framework;
namespace DepthsBelow.Component
{
/// <summary>
/// Component that handles pathfinding.
/// </summary>
public class PathFinder : Component
{
/// <summary>
/// A pathfinder node.
/// </summary>
public class Node
{
/// <summary>
/// Grid position of the node.
/// </summary>
public Point Position;
/// <summary>
/// A* F-score
/// </summary>
public int F;
/// <summary>
/// A* G-score
/// </summary>
public int G;
/// <summary>
/// Explicit conversion between A* library node and Node object.
/// </summary>
/// <param name="aStarNode"></param>
/// <returns></returns>
public static explicit operator Node(AStar.PathFinderNode aStarNode)
{
return new Node
@@ -27,22 +47,36 @@ namespace DepthsBelow.Component
}
}
/// <summary>
/// Start position of the path.
/// </summary>
public Point Start { get; private set; }
/// <summary>
/// A collision bytemap.
/// 0 = unwalkable node
/// 1 = walkable node
/// </summary>
public byte[,] CollisionMap;
private Point goal;
/// <summary>
/// Sets a goal point and finds a path to it.
/// After a path is created, call Next() go get the next node in the path.
/// </summary>
public Point Goal
{
get { return goal; }
set
{
this.goal = value;
//this.Start = this.Parent.GetComponent<Transform>().Grid.Position;
this.FindPath(this.Parent.GetComponent<Transform>().Grid.Position, value, null);
}
}
/// <summary>
/// Is a path in progress?
/// </summary>
public bool IsMoving
{
get
@@ -74,6 +108,10 @@ namespace DepthsBelow.Component
base.Update(gameTime);
}
/// <summary>
/// Gets the next node of the current path.
/// </summary>
/// <returns>The next node in the path.</returns>
public Node Next()
{
if (path == null)
@@ -87,11 +125,21 @@ namespace DepthsBelow.Component
return (Node)nextNode;
}
/// <summary>
/// Cancels the current path in memory.
/// </summary>
public void Stop()
{
path = null;
}
/// <summary>
/// Finds a path between two points.
/// </summary>
/// <param name="start">The start point.</param>
/// <param name="goal">The goal point.</param>
/// <param name="appendCollisionMap">A list of unwalkable points that will be joined with the original collision map.</param>
/// <returns></returns>
private List<AStar.PathFinderNode> FindPath(Point start, Point goal, List<Point> appendCollisionMap)
{
byte[,] mapCollisionMap = Core.Map.GetCollisionMap();
@@ -123,6 +171,10 @@ namespace DepthsBelow.Component
return path;
}
/// <summary>
/// Recreate the current path in memory with a list of unwalkable points that will be joined with the original collision map.
/// </summary>
/// <param name="appendCollisionMap">A list of unwalkable points that will be joined with the collision map.</param>
public void RecreatePath(List<Point> appendCollisionMap)
{
FindPath(this.Parent.GetComponent<Transform>().Grid.Position, this.Goal, appendCollisionMap);
@@ -7,14 +7,28 @@ using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow.Component
{
/// <summary>
/// Sprite render component.
/// Handles rendering of a 2D texture.
/// </summary>
public class SpriteRenderer : Component
{
/// <summary>
/// The texture to be rendered.
/// </summary>
public Texture2D Texture;
/// <summary>
/// Color modifier.
/// </summary>
public Color Color;
/// <summary>
/// Scale of the texture.
/// </summary>
public float Scale;
public SpriteEffects SpriteEffects;
public SpriteRenderer(Entity parent) : base(parent)
public SpriteRenderer(Entity parent)
: base(parent)
{
this.Color = Color.White;
this.Scale = 1;
@@ -23,8 +37,7 @@ namespace DepthsBelow.Component
public void Draw(SpriteBatch spriteBatch)
{
Transform transform = this.Parent.GetComponent<Transform>();
//spriteBatch.Draw(Texture, tc.Position, this.Color);
var transform = this.Parent.GetComponent<Transform>();
spriteBatch.Draw(Texture, transform.World.Position + new Vector2(Grid.TileSize / 2, Grid.TileSize / 2), null, Color, transform.World.Rotation, transform.World.Origin, Scale, SpriteEffects, 0);
}
}
+73 -5
View File
@@ -7,11 +7,21 @@ using Microsoft.Xna.Framework;
namespace DepthsBelow.Component
{
/// <summary>
/// Transform component.
/// Handles both grid and world positions and rotations, while keeping them in sync.
/// </summary>
public class Transform : Component
{
/// <summary>
/// Represents a grid position.
/// </summary>
public class GridTransform
{
private Point position;
/// <summary>
/// Sets the grid position and updates the world position of WorldTransform.
/// </summary>
public Point Position
{
get { return position; }
@@ -22,6 +32,9 @@ namespace DepthsBelow.Component
}
}
/// <summary>
/// Shorthand for the grid x-position.
/// </summary>
public int X
{
get { return position.X; }
@@ -31,6 +44,10 @@ namespace DepthsBelow.Component
masterTransform.World.SetWithoutRelation((Vector2)this);
}
}
/// <summary>
/// Shorthand for the grid y-position.
/// </summary>
public int Y
{
get { return position.Y; }
@@ -41,11 +58,17 @@ namespace DepthsBelow.Component
}
}
/// <summary>
/// Implicit conversion between GridTransform and a Point grid position.
/// </summary>
public static implicit operator Point(GridTransform gridTransform)
{
return gridTransform.position;
}
/// <summary>
/// Explicit conversion between GridTransform and a Vector2 world position.
/// </summary>
public static explicit operator Vector2(GridTransform gridTransform)
{
var worldPosition = DepthsBelow.Grid.GridToWorld(gridTransform.Position);
@@ -53,11 +76,19 @@ namespace DepthsBelow.Component
}
private readonly Transform masterTransform;
/// <summary>
/// Create a GridTransform within a master Transform component.
/// </summary>
/// <param name="masterTransform">The master Transform component.</param>
public GridTransform(Transform masterTransform)
{
this.masterTransform = masterTransform;
}
/// <summary>
/// Sets the position data without updating the associated world position.
/// </summary>
/// <param name="position">The grid position.</param>
public void SetWithoutRelation(Point position)
{
this.position = position;
@@ -67,6 +98,9 @@ namespace DepthsBelow.Component
public class WorldTransform
{
private Vector2 position;
/// <summary>
/// Sets the world position and updates the grid position of GridTransform.
/// </summary>
public Vector2 Position
{
get { return position; }
@@ -77,6 +111,9 @@ namespace DepthsBelow.Component
}
}
/// <summary>
/// Shorthand for the world x-position.
/// </summary>
public float X
{
get { return position.X; }
@@ -86,6 +123,10 @@ namespace DepthsBelow.Component
masterTransform.Grid.SetWithoutRelation((Point)this);
}
}
/// <summary>
/// Shorthand for the world y-position.
/// </summary>
public float Y
{
get { return position.Y; }
@@ -96,20 +137,27 @@ namespace DepthsBelow.Component
}
}
/// <summary>
/// Rotation in radians.
/// </summary>
public float Rotation;
public void Rotate(int directionX, int directionY)
{
Rotation = (float)Math.Atan(directionY/directionX);
}
/// <summary>
/// Origin to rotate around.
/// </summary>
public Vector2 Origin;
/// <summary>
/// Implicit conversion between WorldTransform and a Vector2 world position.
/// </summary>
public static implicit operator Vector2(WorldTransform worldTransform)
{
return worldTransform.Position;
}
/// <summary>
/// Explicit conversion between WorldTransform and a Point grid position.
/// </summary>
public static explicit operator Point(WorldTransform worldTransform)
{
var gridPosition = DepthsBelow.Grid.WorldToGrid(worldTransform.Position);
@@ -117,18 +165,32 @@ namespace DepthsBelow.Component
}
private readonly Transform masterTransform;
/// <summary>
/// Create a WorldTransform within a master Transform component.
/// </summary>
/// <param name="masterTransform">The master Transform component.</param>
public WorldTransform(Transform masterTransform)
{
this.masterTransform = masterTransform;
}
/// <summary>
/// Sets the position data without updating the associated grid position.
/// </summary>
/// <param name="position">The world position.</param>
public void SetWithoutRelation(Vector2 position)
{
this.position = position;
}
}
/// <summary>
/// The grid position.
/// </summary>
public GridTransform Grid;
/// <summary>
/// The world position.
/// </summary>
public WorldTransform World;
public Transform(Entity parent)
@@ -138,11 +200,17 @@ namespace DepthsBelow.Component
World = new WorldTransform(this);
}
/// <summary>
/// Implicit conversion between Transform and a Point grid position.
/// </summary>
public static implicit operator Point(Transform transform)
{
return transform.Grid;
}
/// <summary>
/// Implicit conversion between Transform and a Vector2 world position.
/// </summary>
public static implicit operator Vector2(Transform transform)
{
return transform.World;
+1 -1
View File
@@ -47,6 +47,7 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<XnaCompressContent>false</XnaCompressContent>
<DocumentationFile>bin\x86\Debug\DepthsBelow.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
@@ -193,7 +194,6 @@
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="DepthsBelow_TemporaryKey.pfx" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
Binary file not shown.
+103 -68
View File
@@ -1,83 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace DepthsBelow
{
public class Entity : IDisposable
{
List<Component.Component> Components;
public Component.Transform Transform;
public int X
{
get { return this.Transform.Grid.X; }
set
{
this.Transform.Grid.X = value;
}
}
public int Y
{
get { return this.Transform.Grid.Y; }
set
{
this.Transform.Grid.Y = value;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace DepthsBelow
{
/// <summary>
/// Game object.
/// </summary>
public class Entity : IDisposable
{
List<Component.Component> Components;
/// <summary>
/// Shorthand for transform component.
/// </summary>
public Component.Transform Transform;
private EntityManager entityManager;
/// <summary>
/// Shorthand to the grid transform position.
/// </summary>
public Point Position
{
get { return this.Transform.Grid.Position; }
set { this.Transform.Grid.Position = value; }
}
/// <summary>
/// Shorthand to the grid transform x-position.
/// </summary>
public int X
{
get { return this.Transform.Grid.X; }
set { this.Transform.Grid.X = value; }
}
/// <summary>
/// Shorthand to the grid transform y-position.
/// </summary>
public int Y
{
get { return this.Transform.Grid.Y; }
set { this.Transform.Grid.Y = value; }
}
private EntityManager entityManager;
public Entity(EntityManager entityManager)
/// <summary>
/// Creates a game object and adds it to the referenced entity manager.
/// </summary>
/// <param name="entityManager">An instance of EntityManager to add the entity to.</param>
public Entity(EntityManager entityManager)
{
this.entityManager = entityManager;
entityManager.Add(this);
Components = new List<Component.Component>();
Transform = new Component.Transform(this);
AddComponent(Transform);
Components = new List<Component.Component>();
Transform = new Component.Transform(this);
AddComponent(Transform);
}
/// <summary>
/// Implementation of IDisposable.
/// Dispose of any unmanaged resources.
/// </summary>
public virtual void Dispose()
{
}
}
/// <summary>
/// Removes the entity from the game world and disposes
/// potential unmanaged resources.
/// </summary>
public virtual void Remove()
{
entityManager.Remove(this);
Dispose();
}
public virtual void Kill()
}
/// <summary>
/// Get the reference to a component contained in the entity.
/// </summary>
/// <typeparam name="T">The component type.</typeparam>
/// <returns>Returns the component of requested type.</returns>
public T GetComponent<T>() where T : Component.Component
{
Remove();
}
public T GetComponent<T>() where T : Component.Component
{
foreach (Component.Component c in Components)
{
if (c is T)
return (T)c;
}
return null;
}
public void AddComponent(Component.Component c)
{
Components.Add(c);
}
public virtual void Update(GameTime gameTime)
{
// Update components
foreach (Component.Component c in Components)
c.Update(gameTime);
}
}
}
foreach (Component.Component c in Components)
{
if (c is T)
return (T)c;
}
return null;
}
/// <summary>
/// Add a component to the entity.
/// </summary>
/// <param name="c">the component to add</param>
public void AddComponent(Component.Component c)
{
Components.Add(c);
}
/// <summary>
/// Update the entity and all child components.
/// </summary>
/// <param name="gameTime"></param>
public virtual void Update(GameTime gameTime)
{
// Update components
foreach (Component.Component c in Components)
c.Update(gameTime);
}
}
}
+28
View File
@@ -7,6 +7,9 @@ using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow
{
/// <summary>
/// Manages a group of entities.
/// </summary>
public class EntityManager : IDisposable
{
private List<Entity> entities;
@@ -16,22 +19,39 @@ namespace DepthsBelow
entities = new List<Entity>();
}
/// <summary>
/// Implementation of IDisposable.
/// Dispose of the entity manager, and all entities it contains.
/// </summary>
public void Dispose()
{
foreach (var entity in entities)
entity.Dispose();
entities = null;
}
/// <summary>
/// Add an entity to the entity manager.
/// </summary>
/// <param name="entity">The entity to add.</param>
public void Add(Entity entity)
{
entities.Add(entity);
}
/// <summary>
/// Remove an entity from the entity manager.
/// </summary>
/// <param name="entity">The entity to remove.</param>
public void Remove(Entity entity)
{
entities.Remove(entity);
}
/// <summary>
/// Reset the entity manager, disposing any entities it contains.
/// </summary>
public void Reset()
{
foreach (var entity in entities)
@@ -40,12 +60,20 @@ namespace DepthsBelow
entities.Clear();
}
/// <summary>
/// Update all entities handled by the entity manager.
/// </summary>
/// <param name="gameTime"></param>
public void Update(GameTime gameTime)
{
foreach (var entity in entities)
entity.Update(gameTime);
}
/// <summary>
/// Draw all entities handled by the entity manager.
/// </summary>
/// <param name="spriteBatch"></param>
public void Draw(SpriteBatch spriteBatch)
{
foreach (var entity in entities)
+7 -13
View File
@@ -9,19 +9,20 @@ using Microsoft.Xna.Framework.Input;
namespace DepthsBelow.GUI
{
/// <summary>
/// A button frame which can handle clicks.
/// </summary>
public class Button : Frame
{
public delegate void OnClickHandler(Point pos);
/// <summary>
/// Handler of OnClick events.
/// </summary>
public OnClickHandler OnClick;
private MouseState lastMouseState;
/*public void OnClick(Point pos)
{
Debug.WriteLine(this + " was clicked at (" + pos.X + "," + pos.Y + ")");
}*/
public Button()
: base()
{
@@ -29,7 +30,7 @@ namespace DepthsBelow.GUI
}
public Button(Frame parent)
: this()
: this()
{
this.Parent = parent;
}
@@ -59,12 +60,5 @@ namespace DepthsBelow.GUI
lastMouseState = ms;
}
public override void Draw(SpriteBatch spriteBatch)
{
//spriteBatch.DrawString(Font, Value, new Vector2(Rectangle.X + Parent.Rectangle.X, Rectangle.Y + Parent.Rectangle.Y), Color);
base.Draw(spriteBatch);
}
}
}
+59 -1
View File
@@ -8,48 +8,87 @@ using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow.GUI
{
/// <summary>
/// A generic GUI frame.
/// </summary>
public class Frame
{
public string Name;
/// <summary>
/// Width of the frame.
/// </summary>
public int Width
{
get { return this.Rectangle.Width; }
set { this.Rectangle.Width = value; }
}
/// <summary>
/// Height of the frame.
/// </summary>
public int Height
{
get { return this.Rectangle.Height; }
set { this.Rectangle.Height = value; }
}
/// <summary>
/// X-position of the frame.
/// </summary>
public int X
{
get { return this.Rectangle.X; }
set { this.Rectangle.X = value; }
}
/// <summary>
/// Y-position of the frame.
/// </summary>
public int Y
{
get { return this.Rectangle.Y; }
set { this.Rectangle.Y = value; }
}
/// <summary>
/// Rectangle of the frame.
/// </summary>
public Rectangle Rectangle;
/// <summary>
/// Absolute rectangle of the frame. Takes parent frame positions in consideration.
/// </summary>
public Rectangle AbsoluteRectangle
{
get
{
if (Parent != null)
return new Rectangle(Parent.Rectangle.X + Rectangle.X, Parent.Rectangle.Y + Rectangle.Y, Rectangle.Width, Rectangle.Height);
return new Rectangle(Parent.AbsoluteRectangle.X + Rectangle.X, Parent.AbsoluteRectangle.Y + Rectangle.Y, Rectangle.Width, Rectangle.Height);
else
return Rectangle;
}
}
/// <summary>
/// Optional background texture of the frame.
/// </summary>
public Texture2D Texture;
/// <summary>
/// Texture color tint.
/// </summary>
public Color Color;
/// <summary>
/// If the frame is visible or not.
/// </summary>
public bool Visible = true;
/// <summary>
/// Potential parent frame.
/// </summary>
public Frame Parent;
/// <summary>
/// Potential children frames.
/// </summary>
public List<Frame> Children;
/// <summary>
/// Create a blank frame.
/// </summary>
public Frame()
{
this.Rectangle = Rectangle.Empty;
@@ -61,12 +100,20 @@ namespace DepthsBelow.GUI
GUIManager.Add(this);
}
/// <summary>
/// Create a blank frame as the child of a frame.
/// </summary>
/// <param name="parentFrame">The parent frame.</param>
public Frame(Frame parentFrame)
: this()
{
this.Parent = parentFrame;
}
/// <summary>
/// Add a child frame to the frame.
/// </summary>
/// <param name="childFrame">The child frame to add.</param>
public void AddChild(Frame childFrame)
{
childFrame.Parent = this;
@@ -74,12 +121,19 @@ namespace DepthsBelow.GUI
Children.Add(childFrame);
}
/// <summary>
/// Remove a child frame from the frame.
/// </summary>
/// <param name="childFrame">The child frame to remove.</param>
public void RemoveChild(Frame childFrame)
{
if (Children.Contains(childFrame))
Children.Remove(childFrame);
}
/// <summary>
/// Destroys the frame and all its children.
/// </summary>
public void Destroy()
{
if (Parent != null)
@@ -88,6 +142,10 @@ namespace DepthsBelow.GUI
GUIManager.Remove(this);
}
/// <summary>
/// Set the background texture of the frame.
/// </summary>
/// <param name="fileName">Filename of the texture.</param>
public void SetTexture(string fileName)
{
Texture = GameServices.GetService<ContentManager>().Load<Texture2D>(fileName);
+13
View File
@@ -8,9 +8,18 @@ using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow.GUI
{
/// <summary>
/// A basic text control.
/// </summary>
class Text : Frame
{
/// <summary>
/// Text to display.
/// </summary>
public String Value;
/// <summary>
/// Font to use while rendering.
/// </summary>
public SpriteFont Font;
public Text()
@@ -25,6 +34,10 @@ namespace DepthsBelow.GUI
this.Parent = parent;
}
/// <summary>
/// Set the font to use while rendering.
/// </summary>
/// <param name="spriteFontName">Filename of the font.</param>
public void SetFont(string spriteFontName)
{
Font = GameServices.GetService<ContentManager>().Load<SpriteFont>(spriteFontName);
+16
View File
@@ -3,15 +3,31 @@ using Microsoft.Xna.Framework;
namespace DepthsBelow
{
/// <summary>
/// Global grid utility functions.
/// </summary>
public static class Grid
{
/// <summary>
/// The size of a tile in pixels.
/// </summary>
public const int TileSize = 32;
/// <summary>
/// Converts a grid position into a world position.
/// </summary>
/// <param name="gridPos">The grid position to convert.</param>
/// <returns>Returns a Vector2 world position.</returns>
public static Vector2 GridToWorld(Point gridPos)
{
return new Vector2(gridPos.X * TileSize, gridPos.Y * TileSize);
}
/// <summary>
/// Converts a world position into a grid position.
/// </summary>
/// <param name="screenPos">The world position to convert.</param>
/// <returns>Returns a Point grid position.</returns>
public static Point WorldToGrid(Vector2 screenPos)
{
return new Point(
+11 -2
View File
@@ -6,8 +6,17 @@ using Microsoft.Xna.Framework;
namespace DepthsBelow
{
/// <summary>
/// Various global utility functions.
/// </summary>
static class Utility
{
/// <summary>
/// Calculate the chance of an entity with a Stat component to hit another unit.
/// </summary>
/// <param name="attacker">The attacking unit.</param>
/// <param name="defender">The recieving unit.</param>
/// <returns>Returns a hit chance percentage.</returns>
public static int CalculateHitChance(Entity attacker, Entity defender)
{
Component.Stat shooting = attacker.GetComponent<Component.Stat>();
@@ -23,7 +32,7 @@ namespace DepthsBelow
//Console.WriteLine(chanceToHit);
return chanceToHit;
}
public static bool HitTest(Entity attacker, Entity defender, int chanceToHit)
/*public static bool HitTest(Entity attacker, Entity defender, int chanceToHit)
{
Component.Stat shooting = attacker.GetComponent<Component.Stat>();
Component.Stat dodging = defender.GetComponent<Component.Stat>();
@@ -34,6 +43,6 @@ namespace DepthsBelow
return true;
}
return false;
}
}*/
}
}