Working unit frames and dynamic soldier grouping
This commit is contained in:
@@ -35,11 +35,27 @@ namespace DepthsBelow
|
||||
return Vector2.Transform(screenPos, Matrix.Invert(Transform));
|
||||
}
|
||||
|
||||
public Rectangle ScreenToWorld(Rectangle screenRectangle)
|
||||
{
|
||||
var pos = ScreenToWorld(new Vector2(screenRectangle.X, screenRectangle.Y));
|
||||
screenRectangle.X = (int)pos.X;
|
||||
screenRectangle.Y = (int)pos.Y;
|
||||
return screenRectangle;
|
||||
}
|
||||
|
||||
public Vector2 WorldToScreen(Vector2 worldPos)
|
||||
{
|
||||
return Vector2.Transform(worldPos, Transform);
|
||||
}
|
||||
|
||||
public Rectangle WorldToScreen(Rectangle screenRectangle)
|
||||
{
|
||||
var pos = WorldToScreen(new Vector2(screenRectangle.X, screenRectangle.Y));
|
||||
screenRectangle.X = (int)pos.X;
|
||||
screenRectangle.Y = (int)pos.Y;
|
||||
return screenRectangle;
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
float elapsed = gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
|
||||
@@ -85,6 +101,11 @@ namespace DepthsBelow
|
||||
Transform *= Matrix.CreateTranslation(new Vector3(change.X, change.Y, 0));
|
||||
}
|
||||
|
||||
Transform = Matrix.Identity
|
||||
* Matrix.CreateRotationZ(Rotation)
|
||||
* Matrix.CreateScale(Zoom)
|
||||
* Matrix.CreateTranslation(new Vector3(Position.X, Position.Y, 0));
|
||||
|
||||
lastMouseState = ms;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,28 @@ using System.Text;
|
||||
|
||||
namespace DepthsBelow.Component
|
||||
{
|
||||
public class Stat : Component
|
||||
{
|
||||
protected int hp = 0;
|
||||
public class Stat : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The current health points of the unit
|
||||
/// </summary>
|
||||
public float HP = 0;
|
||||
public float _MaxHP = 100;
|
||||
/// <summary>
|
||||
/// Gets or sets the max HP.
|
||||
/// </summary>
|
||||
public float MaxHP
|
||||
{
|
||||
get { return _MaxHP; }
|
||||
set
|
||||
{
|
||||
_MaxHP = value;
|
||||
if (HP == 0)
|
||||
HP = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected int hp = 0;
|
||||
protected int defence = 0;
|
||||
protected int stepsTaken = 0;
|
||||
protected int distanceToTarget = 0;
|
||||
@@ -65,7 +84,8 @@ namespace DepthsBelow.Component
|
||||
return panic + GetPenalty(stepsTaken) + (int)(GetPenalty(distance) / 2);
|
||||
}
|
||||
|
||||
public Stat(Entity parent) : base (parent)
|
||||
public Stat(Entity parent)
|
||||
: base (parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ namespace DepthsBelow
|
||||
|
||||
public static MouseInput MouseInput;
|
||||
public static KeyboardInput KeyboardInput;
|
||||
public List<Soldier> Squad;
|
||||
public List<Soldier> Squad;
|
||||
public DynamicGroupManager GroupManager;
|
||||
public List<SmallEnemy> Swarm;
|
||||
public List<Shot> Volley;
|
||||
public static Map Map;
|
||||
@@ -42,20 +43,16 @@ namespace DepthsBelow
|
||||
public Core()
|
||||
{
|
||||
GraphicsDeviceManager = new GraphicsDeviceManager(this);
|
||||
Content.RootDirectory = "Content";
|
||||
|
||||
GraphicsDeviceManager.PreferredBackBufferWidth = 1280;
|
||||
GraphicsDeviceManager.PreferredBackBufferHeight = 720;
|
||||
GraphicsDeviceManager.IsFullScreen = false;
|
||||
|
||||
//graphics.SynchronizeWithVerticalRetrace = false;
|
||||
this.IsFixedTimeStep = false;
|
||||
GraphicsDeviceManager.ApplyChanges();
|
||||
|
||||
this.IsFixedTimeStep = false;
|
||||
this.IsMouseVisible = true;
|
||||
|
||||
GameServices.AddService<GraphicsDevice>(GraphicsDevice);
|
||||
GameServices.AddService<ContentManager>(Content);
|
||||
Content.RootDirectory = "Content";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -66,19 +63,21 @@ namespace DepthsBelow
|
||||
/// </summary>
|
||||
protected override void Initialize()
|
||||
{
|
||||
Lua = new Lua();
|
||||
|
||||
// TODO: Add your initialization logic here
|
||||
EntityManager = new EntityManager();
|
||||
TurnManager = new TurnManager(new string[] { "Player", "Computer" });
|
||||
|
||||
GameServices.AddService<GraphicsDevice>(GraphicsDevice);
|
||||
GameServices.AddService<ContentManager>(Content);
|
||||
|
||||
Lua = new Lua();
|
||||
|
||||
EntityManager = new EntityManager();
|
||||
TurnManager = new TurnManager(new string[] { "Player", "Computer" });
|
||||
|
||||
Camera = new Camera(this);
|
||||
Interface = new Interface(this);
|
||||
|
||||
Squad = new List<Soldier>();
|
||||
Swarm = new List<SmallEnemy>();
|
||||
Volley = new List<Shot>();
|
||||
|
||||
Interface = new Interface(this);
|
||||
|
||||
Squad = new List<Soldier>();
|
||||
Swarm = new List<SmallEnemy>();
|
||||
Volley = new List<Shot>();
|
||||
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
@@ -94,6 +93,8 @@ namespace DepthsBelow
|
||||
Map = Content.Load<Map>("maps/Cave.Level1");
|
||||
// Load map objects
|
||||
Map.ParseObjects(this);
|
||||
GroupManager = new DynamicGroupManager(Squad.Cast<Entity>().ToList(), (float)Grid.TileSize * 1.5f);
|
||||
Interface.CreateUnitFrames(Squad);
|
||||
|
||||
// TODO: use this.Content to load your game content here
|
||||
Soldier.LoadContent();
|
||||
@@ -139,6 +140,7 @@ namespace DepthsBelow
|
||||
|
||||
EntityManager.Update(gameTime);
|
||||
|
||||
Interface.Update(gameTime);
|
||||
GUIManager.Update(gameTime);
|
||||
|
||||
base.Update(gameTime);
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Camera.cs" />
|
||||
<Compile Include="DynamicGroupManager.cs" />
|
||||
<Compile Include="TurnManager.cs" />
|
||||
<Compile Include="CustomExtensions.cs" />
|
||||
<Compile Include="EntityManager.cs" />
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace DepthsBelow
|
||||
{
|
||||
public class DynamicGroupManager
|
||||
{
|
||||
public class Group
|
||||
{
|
||||
public List<Entity> Entities;
|
||||
public float Panic;
|
||||
}
|
||||
|
||||
private List<Entity> entities;
|
||||
|
||||
public float MaxRange;
|
||||
|
||||
public List<Group> Groups;
|
||||
|
||||
public DynamicGroupManager(List<Entity> entities, float maxRange)
|
||||
{
|
||||
this.entities = entities;
|
||||
this.MaxRange = maxRange;
|
||||
|
||||
UpdateGroups();
|
||||
}
|
||||
|
||||
public void UpdateGroups()
|
||||
{
|
||||
if (Groups == null)
|
||||
Groups = new List<Group>();
|
||||
|
||||
var newGroups = CreateGroups(MaxRange);
|
||||
|
||||
foreach (var newGroup in newGroups)
|
||||
{
|
||||
foreach (var entity in newGroup.Entities)
|
||||
{
|
||||
Group oldGroup = null;
|
||||
// Find the group the entity belonged to before
|
||||
foreach (var group in Groups)
|
||||
{
|
||||
if (group.Entities.Contains(entity))
|
||||
{
|
||||
oldGroup = group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldGroup != null)
|
||||
newGroup.Panic += oldGroup.Panic / oldGroup.Entities.Count;
|
||||
else
|
||||
newGroup.Panic = 10;
|
||||
}
|
||||
}
|
||||
|
||||
Groups = newGroups;
|
||||
}
|
||||
|
||||
private List<Group> CreateGroups(float maxRange)
|
||||
{
|
||||
var alreadyGrouped = new List<Entity>();
|
||||
var groups = new List<Group>();
|
||||
|
||||
for (int index = 0; index < entities.Count; index++)
|
||||
{
|
||||
var soldier = entities[index];
|
||||
|
||||
if (!alreadyGrouped.Contains(soldier))
|
||||
{
|
||||
var group = new List<Entity>();
|
||||
GetNearChain(ref group, soldier, maxRange);
|
||||
alreadyGrouped.AddRange(group);
|
||||
|
||||
if (group.Count > 0)
|
||||
groups.Add(new Group() { Entities = group });
|
||||
}
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
// Get all entities who are close to each other in a chain
|
||||
private void GetNearChain(ref List<Entity> group, Entity entity, float maxRange)
|
||||
{
|
||||
for (int index = 0; index < entities.Count; index++)
|
||||
{
|
||||
var nearSoldier = entities[index];
|
||||
|
||||
if (!group.Contains(nearSoldier))
|
||||
{
|
||||
float distance = Vector2.Distance(nearSoldier.Transform.World + nearSoldier.Transform.World.Origin,
|
||||
entity.Transform.World + entity.Transform.World.Origin);
|
||||
if (distance <= maxRange)
|
||||
{
|
||||
group.Add(nearSoldier);
|
||||
GetNearChain(ref group, nearSoldier, maxRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,19 @@ namespace DepthsBelow
|
||||
set { this.Transform.Grid.Y = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Storage for property data
|
||||
/// </summary>
|
||||
public Dictionary<string, object> Properties = new Dictionary<string, object>();
|
||||
/// <summary>
|
||||
/// Shorthand for frame properties.
|
||||
/// </summary>
|
||||
public object this[string key]
|
||||
{
|
||||
get { return Properties[key]; }
|
||||
set { Properties[key] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a game object and adds it to the referenced entity manager.
|
||||
/// </summary>
|
||||
|
||||
@@ -29,10 +29,10 @@ namespace DepthsBelow.GUI
|
||||
|
||||
}
|
||||
|
||||
public Button(Frame parent)
|
||||
: this()
|
||||
public Button(Frame parent)
|
||||
: base(parent)
|
||||
{
|
||||
this.Parent = parent;
|
||||
|
||||
}
|
||||
|
||||
public override void Update(GameTime gameTime)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
@@ -81,16 +83,17 @@ namespace DepthsBelow.GUI
|
||||
/// </summary>
|
||||
public Rectangle Rectangle;
|
||||
/// <summary>
|
||||
/// Absolute rectangle of the frame. Takes parent frame positions in consideration.
|
||||
/// Absolute rectangle of the frame.
|
||||
/// Takes parent frame positions in consideration and converts negative widths and heights.
|
||||
/// </summary>
|
||||
public Rectangle AbsoluteRectangle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Parent != null)
|
||||
return new Rectangle(Parent.AbsoluteRectangle.X + Rectangle.X, Parent.AbsoluteRectangle.Y + Rectangle.Y, Rectangle.Width, Rectangle.Height);
|
||||
return Utility.MakeRectanglePositive(new Rectangle(Parent.AbsoluteRectangle.X + Rectangle.X, Parent.AbsoluteRectangle.Y + Rectangle.Y, Rectangle.Width, Rectangle.Height));
|
||||
else
|
||||
return Rectangle;
|
||||
return Utility.MakeRectanglePositive(Rectangle);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -101,10 +104,16 @@ namespace DepthsBelow.GUI
|
||||
/// Texture color tint.
|
||||
/// </summary>
|
||||
public Color Color;
|
||||
|
||||
public bool _Visible = true;
|
||||
/// <summary>
|
||||
/// If the frame is visible or not.
|
||||
/// </summary>
|
||||
public bool Visible = true;
|
||||
public bool Visible
|
||||
{
|
||||
get { return (Parent != null) ? _Visible && Parent.Visible : _Visible; }
|
||||
set { _Visible = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The layer of the frame.
|
||||
@@ -132,47 +141,142 @@ namespace DepthsBelow.GUI
|
||||
/// </summary>
|
||||
public List<Frame> Children;
|
||||
|
||||
/// <summary>
|
||||
/// Storage for property data
|
||||
/// </summary>
|
||||
public Dictionary<string, object> Properties = new Dictionary<string, object>();
|
||||
/// <summary>
|
||||
/// Shorthand for frame properties.
|
||||
/// </summary>
|
||||
public object this[string key]
|
||||
{
|
||||
get { return Properties[key]; }
|
||||
set { Properties[key] = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether mouse events can be handled by the frame.
|
||||
/// </summary>
|
||||
public bool MouseEnabled = false;
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Handler for click events.
|
||||
/// </summary>
|
||||
/// <param name="frame">The frame.</param>
|
||||
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
|
||||
public delegate void OnClickHandler(Frame frame, GUIManager.MouseEventArgs args);
|
||||
/// <summary>
|
||||
/// Occurs when the frame is clicked inside it's bounding rectangle.
|
||||
/// </summary>
|
||||
public event OnClickHandler OnClick;
|
||||
/// <summary>
|
||||
/// Gets the number of subscribers to the <see cref="OnClickHandler" /> event.
|
||||
/// </summary>
|
||||
public int OnClickCount
|
||||
{
|
||||
get { return (OnClick != null) ? OnClick.GetInvocationList().Length : 0; }
|
||||
}
|
||||
/// <summary>
|
||||
/// <see cref="OnClickHandler" /> event arguments.
|
||||
/// </summary>
|
||||
public class OnClickArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The position of the click relative to the frame position.
|
||||
/// </summary>
|
||||
public Point Position;
|
||||
|
||||
/// <summary>
|
||||
/// The time of the click, since the start of the program.
|
||||
/// </summary>
|
||||
public TimeSpan Time;
|
||||
}
|
||||
/// <summary>
|
||||
/// Handler for click events.
|
||||
/// Handler for press events.
|
||||
/// </summary>
|
||||
/// <param name="frame">The clicked frame.</param>
|
||||
/// <param name="e">The <see cref="OnClickArgs" /> instance containing the event data.</param>
|
||||
public delegate void OnClickHandler(Frame frame, OnClickArgs e);
|
||||
/// <param name="frame">The frame.</param>
|
||||
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
|
||||
public delegate void OnPressHandler(Frame frame, GUIManager.MouseEventArgs args);
|
||||
/// <summary>
|
||||
/// Raise an <see cref="OnClick" /> event on the frame.
|
||||
/// Occurs when the frame is clicked inside it's bounding rectangle.
|
||||
/// </summary>
|
||||
/// <param name="e">The <see cref="OnClickArgs" /> instance containing the event data.</param>
|
||||
public void Click(OnClickArgs e)
|
||||
public event OnPressHandler OnPress;
|
||||
|
||||
/// <summary>
|
||||
/// Handler for release events.
|
||||
/// </summary>
|
||||
/// <param name="frame">The frame.</param>
|
||||
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
|
||||
public delegate void OnReleaseHandler(Frame frame, GUIManager.MouseEventArgs args);
|
||||
/// <summary>
|
||||
/// Occurs when the frame is clicked inside it's bounding rectangle.
|
||||
/// </summary>
|
||||
public event OnReleaseHandler OnRelease;
|
||||
|
||||
/// <summary>
|
||||
/// Handler for mouse over events.
|
||||
/// </summary>
|
||||
/// <param name="frame">The frame.</param>
|
||||
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
|
||||
public delegate void OnMouseOverHandler(Frame frame, GUIManager.MouseEventArgs args);
|
||||
/// <summary>
|
||||
/// Occurs when the frame is clicked inside it's bounding rectangle.
|
||||
/// </summary>
|
||||
public event OnMouseOverHandler OnMouseOver;
|
||||
|
||||
/// <summary>
|
||||
/// Handler for mouse out events.
|
||||
/// </summary>
|
||||
/// <param name="frame">The frame.</param>
|
||||
/// <param name="args">The <see cref="GUIManager.MouseEventArgs" /> instance containing the event data.</param>
|
||||
public delegate void OnMouseOutHandler(Frame frame, GUIManager.MouseEventArgs args);
|
||||
/// <summary>
|
||||
/// Occurs when the frame is clicked inside it's bounding rectangle.
|
||||
/// </summary>
|
||||
public event OnMouseOutHandler OnMouseOut;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Raises the specified event by name.
|
||||
/// </summary>
|
||||
/// <param name="eventName">Name of the event.</param>
|
||||
/// <param name="eventArgs">The <see cref="EventArgs" /> instance containing the event data.</param>
|
||||
/// <returns>Returns true if any event was raised.</returns>
|
||||
public bool Raise(string eventName, EventArgs eventArgs)
|
||||
{
|
||||
if (OnClick != null)
|
||||
OnClick(this, e);
|
||||
// Get the event field info
|
||||
var fieldInfo = this.GetType().GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
// If the event exists
|
||||
if (fieldInfo != null)
|
||||
{
|
||||
var eventDelegate = (MulticastDelegate)fieldInfo.GetValue(this);
|
||||
// If there's any subscribed events...
|
||||
if (eventDelegate != null)
|
||||
{
|
||||
// Invoke their raise methods
|
||||
foreach (var handler in eventDelegate.GetInvocationList())
|
||||
{
|
||||
try
|
||||
{
|
||||
handler.Method.Invoke(handler.Target, new object[] { this, eventArgs });
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the subscriber count for a specific event.
|
||||
/// </summary>
|
||||
/// <param name="eventName">Name of the event.</param>
|
||||
/// <returns>Returns the number of subscribers of the event.</returns>
|
||||
public int GetSubscriberCount(string eventName)
|
||||
{
|
||||
// Get the event field info
|
||||
var fieldInfo = this.GetType().GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
// If the event exists
|
||||
if (fieldInfo != null)
|
||||
{
|
||||
var eventDelegate = (MulticastDelegate)fieldInfo.GetValue(this);
|
||||
// If there's any subscribed events...
|
||||
if (eventDelegate != null)
|
||||
return eventDelegate.GetInvocationList().Length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -189,7 +293,7 @@ namespace DepthsBelow.GUI
|
||||
|
||||
this.Children = new List<Frame>();
|
||||
|
||||
UID = GUIManager.Add(this);
|
||||
this.UID = GUIManager.Add(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -258,7 +362,7 @@ namespace DepthsBelow.GUI
|
||||
{
|
||||
if (OnClick != null)
|
||||
{
|
||||
var args = new OnClickArgs()
|
||||
var args = new MouseEventArgs()
|
||||
{
|
||||
Position = new Point(ms.X - AbsoluteRectangle.X, ms.Y - AbsoluteRectangle.Y),
|
||||
Time = gameTime.TotalGameTime
|
||||
@@ -270,19 +374,19 @@ namespace DepthsBelow.GUI
|
||||
|
||||
lastMouseState = ms;*/
|
||||
|
||||
foreach (var child in Children)
|
||||
child.Update(gameTime);
|
||||
/*foreach (var child in Children)
|
||||
child.Update(gameTime);*/
|
||||
}
|
||||
|
||||
public virtual void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (Visible)
|
||||
{
|
||||
{
|
||||
if (Texture != null)
|
||||
spriteBatch.Draw(Texture, AbsoluteRectangle, Color);
|
||||
|
||||
foreach (var child in Children)
|
||||
child.Draw(spriteBatch);
|
||||
/*foreach (var child in Children)
|
||||
child.Draw(spriteBatch);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ namespace DepthsBelow.GUI
|
||||
}
|
||||
|
||||
public Text(Frame parent)
|
||||
: this()
|
||||
: base(parent)
|
||||
{
|
||||
this.Parent = parent;
|
||||
this.Color = Color.White;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -47,8 +47,8 @@ namespace DepthsBelow.GUI
|
||||
{
|
||||
base.Draw(spriteBatch);
|
||||
|
||||
if (Parent.Visible && this.Visible && Font != null)
|
||||
spriteBatch.DrawString(Font, Value, new Vector2(Rectangle.X + Parent.Rectangle.X, Rectangle.Y + Parent.Rectangle.Y), Color);
|
||||
if (Visible && Font != null)
|
||||
spriteBatch.DrawString(Font, Value, new Vector2(Rectangle.X + Parent.AbsoluteRectangle.X, Rectangle.Y + Parent.AbsoluteRectangle.Y), Color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,18 +6,35 @@ using System.Text;
|
||||
using DepthsBelow.GUI;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace DepthsBelow
|
||||
{
|
||||
static class GUIManager
|
||||
public static class GUIManager
|
||||
{
|
||||
/// <summary>
|
||||
/// GUI mouse event arguments.
|
||||
/// </summary>
|
||||
public class MouseEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The XNA mouse state.
|
||||
/// </summary>
|
||||
public MouseState MouseState;
|
||||
|
||||
/// <summary>
|
||||
/// The time of the click, since the start of the program.
|
||||
/// </summary>
|
||||
public TimeSpan Time;
|
||||
}
|
||||
|
||||
public static List<Frame> Frames = new List<Frame>();
|
||||
private static int uidIndex = 0;
|
||||
|
||||
public static int Add(Frame frame)
|
||||
{
|
||||
Frames.Add(frame);
|
||||
return uidIndex++;
|
||||
return CreateUID();
|
||||
}
|
||||
|
||||
public static void Remove(Frame frame)
|
||||
@@ -25,24 +42,35 @@ namespace DepthsBelow
|
||||
Frames.Remove(frame);
|
||||
}
|
||||
|
||||
public static void Click(Point position, TimeSpan time)
|
||||
public static int CreateUID()
|
||||
{
|
||||
var clickRectangle = new Rectangle(position.X, position.Y, 1, 1);
|
||||
return uidIndex++;
|
||||
}
|
||||
|
||||
// Create a list of all frames which have an OnClick handler and intersects with the click position
|
||||
var intersections = Frames.Where(frame => frame.OnClickCount > 0).Where(frame => clickRectangle.Intersects(frame.AbsoluteRectangle)).ToList();
|
||||
/// <summary>
|
||||
/// Calculates which frames are intersecting a point.
|
||||
/// </summary>
|
||||
/// <param name="point">A point on the screen.</param>
|
||||
/// <returns>Returns a list of frames intersecting the point.</returns>
|
||||
public static List<Frame> FramesIntersectingPoint(Point point)
|
||||
{
|
||||
var rect = new Rectangle(point.X, point.Y, 1, 1);
|
||||
return Frames.Where(frame => rect.Intersects(frame.AbsoluteRectangle)).ToList();
|
||||
}
|
||||
|
||||
public static bool RaiseAt(string eventName, EventArgs eventArgs, Point position)
|
||||
{
|
||||
// Create a list of all frames which intersects with the click position
|
||||
var intersections = FramesIntersectingPoint(position);
|
||||
// Filter it by event
|
||||
intersections = intersections.Where(frame => frame.GetSubscriberCount(eventName) > 0).ToList();
|
||||
// Get the topmost frame of that list
|
||||
var topFrame = GetTopFrame(intersections);
|
||||
|
||||
if (topFrame != null)
|
||||
{
|
||||
var e = new Frame.OnClickArgs()
|
||||
{
|
||||
Position = position,
|
||||
Time = time
|
||||
};
|
||||
topFrame.Click(e);
|
||||
}
|
||||
return topFrame.Raise(eventName, eventArgs);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -6,6 +6,7 @@ using DepthsBelow.GUI;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace DepthsBelow
|
||||
{
|
||||
@@ -13,10 +14,132 @@ namespace DepthsBelow
|
||||
{
|
||||
Core core;
|
||||
|
||||
/// <summary>
|
||||
/// The master frame covering the whole game screen. Parent of all frames.
|
||||
/// This frame handles all mouse interaction with the game world
|
||||
/// </summary>
|
||||
public Frame UIParent;
|
||||
|
||||
public List<Frame> PanicFrames = new List<Frame>();
|
||||
public List<Frame> UnitFrames = new List<Frame>();
|
||||
public Dictionary<Soldier, Frame> SoldierToFrame = new Dictionary<Soldier, Frame>();
|
||||
|
||||
Random random = new Random();
|
||||
|
||||
public Interface(Core core)
|
||||
{
|
||||
this.core = core;
|
||||
|
||||
UIParent = new Frame();
|
||||
UIParent.Width = GameServices.GetService<GraphicsDevice>().Viewport.Width;
|
||||
UIParent.Height = GameServices.GetService<GraphicsDevice>().Viewport.Height;
|
||||
|
||||
// Selection rectangle
|
||||
var selectionFrame = new Frame(UIParent);
|
||||
selectionFrame.Texture = Utility.GetSolidTexture();
|
||||
selectionFrame.Color = Color.Red * 0.5f;
|
||||
selectionFrame.Visible = false;
|
||||
UIParent["selectionFrame"] = selectionFrame;
|
||||
|
||||
// OnClick
|
||||
UIParent.OnClick += delegate(Frame frame, GUIManager.MouseEventArgs args)
|
||||
{
|
||||
KeyboardState ks = Keyboard.GetState();
|
||||
MouseState ms = args.MouseState;
|
||||
|
||||
var mousePos = new Point(ms.X, ms.Y);
|
||||
var mouseRectangle = new Rectangle(mousePos.X, mousePos.Y, 1, 1);
|
||||
var mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(mousePos.X, mousePos.Y));
|
||||
var mouseWorldRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 1, 1);
|
||||
|
||||
// Deselect all units
|
||||
if (!ks.IsKeyDown(Keys.LeftControl))
|
||||
{
|
||||
foreach (var unit in core.Squad)
|
||||
unit.Selected = false;
|
||||
|
||||
foreach (var unitFrame in UnitFrames)
|
||||
unitFrame.Color = Color.Black;
|
||||
}
|
||||
|
||||
// Select all units in the rectangle
|
||||
foreach (var soldier in core.Squad)
|
||||
{
|
||||
if (mouseWorldRectangle.Intersects(soldier.GetComponent<Component.Collision>().Rectangle))
|
||||
{
|
||||
soldier.Selected = true;
|
||||
|
||||
foreach (var unitFrame in UnitFrames)
|
||||
{
|
||||
if (unitFrame["soldier"] == soldier)
|
||||
unitFrame.Color = Color.Blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send orders with right click
|
||||
if (ks.IsKeyDown(Keys.LeftControl))
|
||||
foreach (var unit in core.Squad)
|
||||
if (unit.Selected)
|
||||
unit.GetComponent<Component.PathFinder>().Goal = Grid.WorldToGrid(mouseWorldPos);
|
||||
|
||||
|
||||
// Hide the selection rectangle
|
||||
//selectionRectangle = Rectangle.Empty;
|
||||
};
|
||||
|
||||
// OnPress
|
||||
UIParent.OnPress += delegate(Frame frame, GUIManager.MouseEventArgs args)
|
||||
{
|
||||
//KeyboardState ks = Keyboard.GetState();
|
||||
MouseState ms = args.MouseState;
|
||||
|
||||
var mousePos = new Point(ms.X, ms.Y);
|
||||
var mouseRectangle = new Rectangle(mousePos.X, mousePos.Y, 1, 1);
|
||||
var mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(mousePos.X, mousePos.Y));
|
||||
var mouseWorldRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 1, 1);
|
||||
|
||||
// Show the selection frame
|
||||
var selectFrame = (GUI.Frame)frame["selectionFrame"];
|
||||
if (!selectFrame.Visible)
|
||||
{
|
||||
selectFrame.X = (int)mousePos.X;
|
||||
selectFrame.Y = (int)mousePos.Y;
|
||||
selectFrame.Visible = true;
|
||||
}
|
||||
};
|
||||
|
||||
// OnRelease
|
||||
UIParent.OnRelease += delegate(Frame frame, GUIManager.MouseEventArgs args)
|
||||
{
|
||||
// Show the selection frame
|
||||
var selectFrame = (GUI.Frame)frame["selectionFrame"];
|
||||
if (selectFrame.Visible)
|
||||
{
|
||||
var intersectionRectangle = core.Camera.ScreenToWorld(selectFrame.AbsoluteRectangle);
|
||||
|
||||
// Select all units in the rectangle
|
||||
foreach (var soldier in core.Squad)
|
||||
{
|
||||
if (intersectionRectangle.Intersects(soldier.GetComponent<Component.Collision>().Rectangle))
|
||||
{
|
||||
soldier.Selected = true;
|
||||
foreach (var unitFrame in UnitFrames)
|
||||
{
|
||||
if (unitFrame["soldier"] == soldier)
|
||||
unitFrame.Color = Color.Blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectFrame.Visible = false;
|
||||
}
|
||||
};
|
||||
|
||||
var leftEdge = new Frame(UIParent);
|
||||
leftEdge.Width = 20;
|
||||
leftEdge.Height = GameServices.GetService<GraphicsDevice>().Viewport.Height;
|
||||
|
||||
// Test GUI frames
|
||||
/*var frame = new GUI.Frame()
|
||||
{
|
||||
@@ -39,30 +162,29 @@ namespace DepthsBelow
|
||||
text.Value = "Hello world!";*/
|
||||
|
||||
// Create some unit frames
|
||||
|
||||
/*var panicFrame = CreatePanicFrame();
|
||||
var unit1 = CreateUnitFrame("Flight captain Rainbow");
|
||||
unit1.X = panicFrame.X;
|
||||
unit1.Y = panicFrame.Y + panicFrame.Height;
|
||||
unit1.OnClick += delegate(Frame frame, Frame.OnClickArgs args)
|
||||
unit1.OnClick += delegate(Frame frame, Frame.MouseEventArgs args)
|
||||
{
|
||||
frame.Color = Color.Red;
|
||||
};
|
||||
var unit2 = CreateUnitFrame("Mr. Sparkle");
|
||||
unit2.X = unit1.X;
|
||||
unit2.Y = unit1.Y + unit1.Height;
|
||||
unit2.OnClick += delegate(Frame frame, Frame.OnClickArgs args)
|
||||
unit2.OnClick += delegate(Frame frame, Frame.MouseEventArgs args)
|
||||
{
|
||||
frame.Color = Color.Red;
|
||||
};*/
|
||||
|
||||
var frame1 = new GUI.Frame();
|
||||
/*var frame1 = new GUI.Frame();
|
||||
frame1.Layer = 0;
|
||||
frame1.SetTexture("images/Enter");
|
||||
frame1.Color = Color.Red;
|
||||
frame1.Width = 100;
|
||||
frame1.Height = 100;
|
||||
frame1.OnClick += delegate(Frame frame, Frame.OnClickArgs args)
|
||||
frame1.OnClick += delegate(Frame frame, Frame.MouseEventArgs args)
|
||||
{
|
||||
if (frame.Color == Color.Red)
|
||||
frame.Color = Color.Green;
|
||||
@@ -76,13 +198,6 @@ namespace DepthsBelow
|
||||
frame1_child.Height = 60;
|
||||
frame1_child.X = 20;
|
||||
frame1_child.Y = 20;
|
||||
frame1_child.OnClick += delegate(Frame frame, Frame.OnClickArgs args)
|
||||
{
|
||||
if (frame.Color == Color.Purple)
|
||||
frame.Color = Color.Pink;
|
||||
else
|
||||
frame.Color = Color.Purple;
|
||||
};
|
||||
|
||||
var frame2 = new GUI.Frame();
|
||||
frame2.Layer = 0;
|
||||
@@ -92,71 +207,208 @@ namespace DepthsBelow
|
||||
frame2.Height = 100;
|
||||
frame2.X = 50;
|
||||
frame2.Y = 50;
|
||||
frame2.OnClick += delegate(Frame frame, Frame.OnClickArgs args)
|
||||
frame2.OnClick += delegate(Frame frame, Frame.MouseEventArgs args)
|
||||
{
|
||||
if (frame.Color == Color.Blue)
|
||||
frame.Color = Color.Yellow;
|
||||
else
|
||||
frame.Color = Color.Blue;
|
||||
};
|
||||
};*/
|
||||
}
|
||||
|
||||
private GUI.Frame CreatePanicFrame()
|
||||
{
|
||||
var frame = new GUI.Frame();
|
||||
var frame = new GUI.Frame(UIParent);
|
||||
frame.SetTexture("images/GUI/unit_background");
|
||||
frame.Color = Color.Black;
|
||||
frame.Width = 164;
|
||||
frame.Height = 19;
|
||||
|
||||
var healthBg = new GUI.Frame(frame);
|
||||
healthBg.SetTexture("images/GUI/health_background");
|
||||
healthBg.Width = 136;
|
||||
healthBg.Height = 13;
|
||||
healthBg.X = 3;
|
||||
healthBg.Y = 3;
|
||||
|
||||
var healthBar = new GUI.Frame(healthBg);
|
||||
healthBar.SetTexture("images/GUI/bar_solid");
|
||||
healthBar.Color = new Color(87, 55, 253);
|
||||
healthBar.Width = (int)(healthBg.Width * 0.5);
|
||||
healthBar.Height = 11;
|
||||
healthBar.X = 1;
|
||||
healthBar.Y = 1;
|
||||
var panicBarBg = new GUI.Frame(frame);
|
||||
panicBarBg.SetTexture("images/GUI/health_background");
|
||||
panicBarBg.Width = 136;
|
||||
panicBarBg.Height = 13;
|
||||
panicBarBg.X = 3;
|
||||
panicBarBg.Y = 3;
|
||||
frame["panicBarBg"] = panicBarBg;
|
||||
|
||||
var panicBar = new GUI.Frame(panicBarBg);
|
||||
panicBar.SetTexture("images/GUI/bar_solid");
|
||||
panicBar.Color = new Color(87, 55, 253);
|
||||
panicBar.Width = (int)(panicBarBg.Width * 0.5);
|
||||
panicBar.Height = 11;
|
||||
panicBar.X = 1;
|
||||
panicBar.Y = 1;
|
||||
frame["panicBar"] = panicBar;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
private GUI.Frame CreateUnitFrame(string unitName)
|
||||
private GUI.Frame CreateUnitFrame(Soldier soldier)
|
||||
{
|
||||
var frame = new GUI.Frame();
|
||||
var frame = new GUI.Frame(UIParent);
|
||||
frame.SetTexture("images/GUI/unit_background");
|
||||
frame.Color = Color.Black;
|
||||
frame.Width = 164;
|
||||
frame.Height = 35;
|
||||
|
||||
var nameText = new GUI.Text(frame);
|
||||
nameText.SetFont("fonts/UnitName");
|
||||
nameText.Value = unitName;
|
||||
nameText.X = 4;
|
||||
nameText.Y = 1;
|
||||
var nameText = new GUI.Text(frame);
|
||||
nameText.SetFont("fonts/UnitName");
|
||||
nameText.Value = soldier.Name + " " + soldier.GetHashCode();
|
||||
nameText.X = 4;
|
||||
nameText.Y = 1;
|
||||
frame["nameText"] = nameText;
|
||||
|
||||
var healthBg = new GUI.Frame(frame);
|
||||
healthBg.SetTexture("images/GUI/health_background");
|
||||
healthBg.Width = 136;
|
||||
healthBg.Height = 13;
|
||||
healthBg.X = 3;
|
||||
healthBg.Y = 19;
|
||||
var healthBarBg = new GUI.Frame(frame);
|
||||
healthBarBg.SetTexture("images/GUI/health_background");
|
||||
healthBarBg.Width = 136;
|
||||
healthBarBg.Height = 13;
|
||||
healthBarBg.X = 3;
|
||||
healthBarBg.Y = 19;
|
||||
frame["healthBarBg"] = healthBarBg;
|
||||
|
||||
var healthBar = new GUI.Frame(healthBg);
|
||||
healthBar.SetTexture("images/GUI/bar_solid");
|
||||
healthBar.Color = Color.Red;
|
||||
healthBar.Width = (int)(healthBg.Width * 0.5f);
|
||||
healthBar.Height = 11;
|
||||
healthBar.X = 1;
|
||||
healthBar.Y = 1;
|
||||
var healthBar = new GUI.Frame(healthBarBg);
|
||||
healthBar.SetTexture("images/GUI/bar_solid");
|
||||
healthBar.Color = Color.Red;
|
||||
healthBar.Width = (int)((healthBarBg.Width - 2) * (soldier.GetComponent<Component.Stat>().HP / soldier.GetComponent<Component.Stat>().MaxHP));
|
||||
healthBar.Height = 11;
|
||||
healthBar.X = 1;
|
||||
healthBar.Y = 1;
|
||||
frame["healthBar"] = healthBar;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
public void CreateUnitFrames(List<Soldier> squad)
|
||||
{
|
||||
// TODO: ForEach squad in Squads...
|
||||
/*GUI.Frame lastFrame = null;
|
||||
foreach (Soldier soldier in squad)
|
||||
{
|
||||
// TODO: Remove this test ;)
|
||||
soldier.GetComponent<Component.Stat>().HP = random.Next(0, (int) soldier.GetComponent<Component.Stat>().MaxHP - 1);
|
||||
|
||||
var uFrame = CreateUnitFrame(soldier);
|
||||
uFrame["soldier"] = soldier;
|
||||
soldier["unitFrame"] = uFrame;
|
||||
if (lastFrame != null)
|
||||
{
|
||||
uFrame.X = lastFrame.X;
|
||||
uFrame.Y = lastFrame.Y + lastFrame.Height;
|
||||
}
|
||||
uFrame.OnClick += delegate(Frame f, GUIManager.MouseEventArgs e)
|
||||
{
|
||||
var s = (Soldier) f["soldier"];
|
||||
KeyboardState ks = Keyboard.GetState();
|
||||
|
||||
if (!ks.IsKeyDown(Keys.LeftControl))
|
||||
{
|
||||
// Deselect all units
|
||||
foreach (var unitFrame in UnitFrames)
|
||||
{
|
||||
((Soldier) unitFrame["soldier"]).Selected = false;
|
||||
unitFrame.Color = Color.Black;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.Selected)
|
||||
{
|
||||
s.Selected = true;
|
||||
uFrame.Color = Color.Blue;
|
||||
}
|
||||
};
|
||||
UnitFrames.Add(uFrame);
|
||||
lastFrame = uFrame;
|
||||
}*/
|
||||
|
||||
foreach (var soldier in squad)
|
||||
{
|
||||
PanicFrames.Add(CreatePanicFrame());
|
||||
|
||||
// TODO: Remove this test ;)
|
||||
soldier.GetComponent<Component.Stat>().HP = random.Next(0, (int)soldier.GetComponent<Component.Stat>().MaxHP - 1);
|
||||
|
||||
var uFrame = CreateUnitFrame(soldier);
|
||||
uFrame["soldier"] = soldier;
|
||||
soldier["unitFrame"] = uFrame;
|
||||
uFrame.OnClick += delegate(Frame f, GUIManager.MouseEventArgs e)
|
||||
{
|
||||
var s = (Soldier)f["soldier"];
|
||||
KeyboardState ks = Keyboard.GetState();
|
||||
|
||||
if (!ks.IsKeyDown(Keys.LeftControl))
|
||||
{
|
||||
// Deselect all units
|
||||
foreach (var unitFrame in UnitFrames)
|
||||
{
|
||||
((Soldier)unitFrame["soldier"]).Selected = false;
|
||||
unitFrame.Color = Color.Black;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.Selected)
|
||||
{
|
||||
s.Selected = true;
|
||||
uFrame.Color = Color.Blue;
|
||||
}
|
||||
};
|
||||
UnitFrames.Add(uFrame);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateUnitFrames()
|
||||
{
|
||||
core.GroupManager.UpdateGroups();
|
||||
var groups = core.GroupManager.Groups;
|
||||
|
||||
foreach (var panicFrame in PanicFrames)
|
||||
panicFrame.Visible = false;
|
||||
|
||||
GUI.Frame lastFrame = null;
|
||||
for (int index = 0; index < groups.Count; index++)
|
||||
{
|
||||
var group = groups[index];
|
||||
|
||||
var pFrame = PanicFrames[index];
|
||||
var pFrameBarBg = (GUI.Frame)pFrame["panicBarBg"];
|
||||
var pFrameBar = (GUI.Frame)pFrame["panicBar"];
|
||||
pFrameBar.Width = (int)(pFrameBarBg.Width * (group.Panic / 100f));
|
||||
|
||||
pFrame.Visible = true;
|
||||
if (lastFrame != null)
|
||||
{
|
||||
pFrame.X = lastFrame.X;
|
||||
pFrame.Y = lastFrame.Y + lastFrame.Height + 15;
|
||||
}
|
||||
lastFrame = pFrame;
|
||||
|
||||
foreach (Soldier soldier in @group.Entities)
|
||||
{
|
||||
var frame = (GUI.Frame) soldier["unitFrame"];
|
||||
frame.X = lastFrame.X;
|
||||
frame.Y = lastFrame.Y + lastFrame.Height;
|
||||
lastFrame = frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
MouseState ms = Mouse.GetState();
|
||||
var mousePos = new Point(ms.X, ms.Y);
|
||||
var mouseRectangle = new Rectangle(mousePos.X, mousePos.Y, 1, 1);
|
||||
var mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(mousePos.X, mousePos.Y));
|
||||
var mouseWorldRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 1, 1);
|
||||
|
||||
// Update the selection rectangle
|
||||
var selectionFrame = (GUI.Frame)UIParent["selectionFrame"];
|
||||
if (selectionFrame.Visible)
|
||||
{
|
||||
selectionFrame.Width = (int)mousePos.X - selectionFrame.X;
|
||||
selectionFrame.Height = (int)mousePos.Y - selectionFrame.Y;
|
||||
}
|
||||
|
||||
UpdateUnitFrames();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
@@ -22,7 +23,85 @@ namespace DepthsBelow
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
/*public List<List<Soldier>> GetGroups(List<Soldier> soldiers)
|
||||
{
|
||||
var ungrouped = soldiers.ToList();
|
||||
var groups = new List<List<Soldier>>();
|
||||
|
||||
for (int index = 0; index < soldiers.Count; index++)
|
||||
{
|
||||
var checkingSoldier = soldiers[index];
|
||||
var group = new List<Soldier>();
|
||||
|
||||
for (int i = 0; i < soldiers.Count; i++)
|
||||
{
|
||||
var soldier = soldiers[i];
|
||||
if (ungrouped.Contains(soldier))
|
||||
{
|
||||
float distance = Vector2.Distance(checkingSoldier.Transform.World + checkingSoldier.Transform.World.Origin,
|
||||
soldier.Transform.World + soldier.Transform.World.Origin);
|
||||
if (distance <= ((float) Grid.TileSize * 1f))
|
||||
{
|
||||
ungrouped.Remove(soldier);
|
||||
group.Add(soldier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (group.Count > 0)
|
||||
groups.Add(group);
|
||||
}
|
||||
|
||||
return groups;
|
||||
}*/
|
||||
|
||||
// Get a list of dynamic soldier groups
|
||||
public List<List<Soldier>> GetGroups(List<Soldier> soldiers, float maxRange)
|
||||
{
|
||||
var alreadyGrouped = new List<Soldier>();
|
||||
var groups = new List<List<Soldier>>();
|
||||
|
||||
for (int index = 0; index < soldiers.Count; index++)
|
||||
{
|
||||
var soldier = soldiers[index];
|
||||
|
||||
if (!alreadyGrouped.Contains(soldier))
|
||||
{
|
||||
var group = new List<Soldier>();
|
||||
GetNearChain(ref group, soldiers, soldier, maxRange);
|
||||
alreadyGrouped.AddRange(group);
|
||||
|
||||
if (group.Count > 0)
|
||||
groups.Add(group);
|
||||
}
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
// Get all soldiers who are close to each other in a chain
|
||||
public void GetNearChain(ref List<Soldier> group, List<Soldier> soldiers, Soldier soldier, float maxRange)
|
||||
{
|
||||
for (int index = 0; index < soldiers.Count; index++)
|
||||
{
|
||||
var nearSoldier = soldiers[index];
|
||||
|
||||
if (!group.Contains(nearSoldier))
|
||||
{
|
||||
float distance = Vector2.Distance(nearSoldier.Transform.World + nearSoldier.Transform.World.Origin,
|
||||
soldier.Transform.World + soldier.Transform.World.Origin);
|
||||
if (distance <= maxRange)
|
||||
{
|
||||
group.Add(nearSoldier);
|
||||
GetNearChain(ref group, soldiers, nearSoldier, maxRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DynamicGroupManager groupManager;
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
KeyboardState ks = Keyboard.GetState();
|
||||
|
||||
@@ -30,6 +109,25 @@ namespace DepthsBelow
|
||||
if (ks.IsKeyUp(Keys.R) && lastKeyboardState.IsKeyDown(Keys.R))
|
||||
{
|
||||
core.Lua.Reload();
|
||||
}
|
||||
|
||||
// Debug test: grouping
|
||||
if (ks.IsKeyUp(Keys.K) && lastKeyboardState.IsKeyDown(Keys.K))
|
||||
{
|
||||
if (groupManager == null)
|
||||
groupManager = new DynamicGroupManager(core.Squad.Cast<Entity>().ToList(), Grid.TileSize * 1.5f);
|
||||
groupManager.UpdateGroups();
|
||||
//var groups = GetGroups(core.Squad, (float)Grid.TileSize * 1.5f);
|
||||
var groups = groupManager.Groups;
|
||||
foreach (var group in groups)
|
||||
{
|
||||
Debug.WriteLine("Group #" + groups.IndexOf(group) + " Panic: " + group.Panic);
|
||||
foreach (var entity in group.Entities)
|
||||
{
|
||||
var soldier = (Soldier)entity;
|
||||
Debug.WriteLine(soldier.Name + " " + soldier.GetHashCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Next turn
|
||||
|
||||
@@ -73,6 +73,7 @@ namespace DepthsBelow
|
||||
if (mapObject.Type == "SquadStart")
|
||||
{
|
||||
var soldier = new Soldier(core.EntityManager, ref core.Squad);
|
||||
soldier.Name = "Derp";
|
||||
// HACK: For some reason, the tile object coordinates are offset by one tile on the Y-axis in the Tiled map file (https://github.com/bjorn/tiled/issues/91)
|
||||
var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize);
|
||||
var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos);
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace DepthsBelow
|
||||
|
||||
bool checkingDirection = false;
|
||||
bool readjust = false;
|
||||
|
||||
private Point pressLocation;
|
||||
|
||||
public MouseInput(Core core)
|
||||
{
|
||||
@@ -43,9 +45,50 @@ namespace DepthsBelow
|
||||
gridTexture.SetData(new Color[] { Color.White });
|
||||
}
|
||||
|
||||
public void OnPress(MouseState ms, GameTime gameTime)
|
||||
{
|
||||
pressLocation = new Point(ms.X, ms.Y);
|
||||
var mouseEvent = new GUIManager.MouseEventArgs()
|
||||
{
|
||||
MouseState = ms,
|
||||
Time = gameTime.TotalGameTime
|
||||
};
|
||||
bool handledByUI = GUIManager.RaiseAt("OnPress", mouseEvent, pressLocation);
|
||||
|
||||
if (handledByUI)
|
||||
return;
|
||||
|
||||
// If the mouse event is above a GUI frame that handles mouse events, do nothing
|
||||
//if (GUIManager.FramesIntersectingPoint(mousePos).Any(frame => frame.MouseEnabled))
|
||||
// return;
|
||||
}
|
||||
|
||||
public void OnRelease(MouseState ms, GameTime gameTime)
|
||||
{
|
||||
var mouseEvent = new GUIManager.MouseEventArgs()
|
||||
{
|
||||
MouseState = ms,
|
||||
Time = gameTime.TotalGameTime
|
||||
};
|
||||
|
||||
bool handledByUI = GUIManager.RaiseAt("OnRelease", mouseEvent, pressLocation);
|
||||
|
||||
if (handledByUI)
|
||||
return;
|
||||
}
|
||||
|
||||
public void OnClick(MouseState ms, GameTime gameTime)
|
||||
{
|
||||
GUIManager.Click(new Point(ms.X, ms.Y), gameTime.TotalGameTime);
|
||||
var mouseEvent = new GUIManager.MouseEventArgs()
|
||||
{
|
||||
MouseState = ms,
|
||||
Time = gameTime.TotalGameTime
|
||||
};
|
||||
|
||||
bool handledByUI = GUIManager.RaiseAt("OnClick", mouseEvent, new Point(ms.X, ms.Y));
|
||||
|
||||
if (handledByUI)
|
||||
return;
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
@@ -54,14 +97,24 @@ namespace DepthsBelow
|
||||
Vector2 mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(ms.X, ms.Y));
|
||||
Rectangle mouseWorldRectangle = new Rectangle((int)mouseWorldPos.X, (int)mouseWorldPos.Y, 1, 1);
|
||||
KeyboardState ks = Keyboard.GetState();
|
||||
|
||||
// OnPress event
|
||||
if (
|
||||
(ms.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Released)
|
||||
|| (ms.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Released)
|
||||
)
|
||||
OnPress(ms, gameTime);
|
||||
|
||||
// OnClick event
|
||||
// OnRelease event
|
||||
if (
|
||||
(ms.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed)
|
||||
|| (ms.RightButton == ButtonState.Released && lastMouseState.RightButton == ButtonState.Pressed)
|
||||
)
|
||||
{
|
||||
OnClick(ms, gameTime);
|
||||
|
||||
OnRelease(ms, gameTime);
|
||||
}
|
||||
|
||||
|
||||
// Tooltip stuff
|
||||
var tooltip = core.Lua.GetObject<GUI.Frame>("ToolTip");
|
||||
@@ -87,7 +140,7 @@ namespace DepthsBelow
|
||||
if (core.TurnManager.CurrentTurn == core.TurnManager["Player"])
|
||||
{
|
||||
// Selection rectangle
|
||||
if (ms.LeftButton == ButtonState.Pressed)
|
||||
/*if (ms.LeftButton == ButtonState.Pressed)
|
||||
{
|
||||
|
||||
if (selectionRectangle == Rectangle.Empty)
|
||||
@@ -118,9 +171,10 @@ namespace DepthsBelow
|
||||
readjust = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// When the mouse is released
|
||||
if (ms.LeftButton == ButtonState.Released && selectionRectangle != Rectangle.Empty)
|
||||
/*if (ms.LeftButton == ButtonState.Released && selectionRectangle != Rectangle.Empty)
|
||||
{
|
||||
// Deselect all units
|
||||
if (!ks.IsKeyDown(Keys.LeftControl))
|
||||
@@ -138,7 +192,7 @@ namespace DepthsBelow
|
||||
|
||||
// Hide the selection rectangle
|
||||
selectionRectangle = Rectangle.Empty;
|
||||
}
|
||||
}*/
|
||||
|
||||
// Send orders with right click
|
||||
if (ms.RightButton == ButtonState.Released && lastMouseState.RightButton == ButtonState.Pressed)
|
||||
|
||||
@@ -11,8 +11,8 @@ namespace DepthsBelow
|
||||
public class Soldier : Entity
|
||||
{
|
||||
public static Texture2D Texture;
|
||||
public Color Color;
|
||||
public static Point Origin;
|
||||
public Color Color;
|
||||
public string Name;
|
||||
private bool _selected;
|
||||
|
||||
public List<Soldier> Squad;
|
||||
@@ -66,7 +66,8 @@ namespace DepthsBelow
|
||||
|
||||
var stat = new Component.Stat(this)
|
||||
{
|
||||
Life = 10,
|
||||
MaxHP = 100,
|
||||
//Life = 10,
|
||||
Defence = 10,
|
||||
Strength = 10,
|
||||
GetAim = 10,
|
||||
|
||||
@@ -63,5 +63,43 @@ namespace DepthsBelow
|
||||
angle, Vector2.Zero, new Vector2(length, width),
|
||||
SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
private static Texture2D solidTexture = null;
|
||||
/// <summary>
|
||||
/// Creates a 1x1 solid white XNA texture.
|
||||
/// </summary>
|
||||
/// <returns>Returns a 1x1 solid white Texture2D object.</returns>
|
||||
public static Texture2D GetSolidTexture()
|
||||
{
|
||||
if (solidTexture == null)
|
||||
{
|
||||
solidTexture = new Texture2D(GameServices.GetService<GraphicsDevice>(), 1, 1);
|
||||
solidTexture.SetData(new Color[] { Color.White });
|
||||
}
|
||||
|
||||
return solidTexture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts rectangles with negative sizes to positive sizes with its position offset.
|
||||
/// </summary>
|
||||
/// <param name="rect">The rectangle with potentially negative sizes.</param>
|
||||
/// <returns>Returns a rectangle with positive sizes.</returns>
|
||||
public static Rectangle MakeRectanglePositive(Rectangle rect)
|
||||
{
|
||||
if (rect.Width < 0)
|
||||
{
|
||||
rect.X += rect.Width;
|
||||
rect.Width = -rect.Width;
|
||||
}
|
||||
|
||||
if (rect.Height < 0)
|
||||
{
|
||||
rect.Y += rect.Height;
|
||||
rect.Height = -rect.Height;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user