Action Points Movement Perfected

This commit is contained in:
Niklas Ulf Anders Cullberg
2012-10-29 16:44:59 +01:00
parent 82ad94eb4f
commit d1b3661eed
4 changed files with 786 additions and 759 deletions
+191 -183
View File
@@ -1,183 +1,191 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using AStar;
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
{
Position = new Point(aStarNode.X, aStarNode.Y),
F = aStarNode.F,
G = aStarNode.G
};
}
}
/// <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.FindPath(this.Parent.GetComponent<Transform>().Grid.Position, value, null);
}
}
/// <summary>
/// Is a path in progress?
/// </summary>
public bool IsMoving
{
get
{
return path != null && path.Count() != 0;
}
}
private AStar.PathFinderFast pathFinder;
private List<AStar.PathFinderNode> path;
public PathFinder(Entity parent)
: base(parent)
{
}
public override void Update(GameTime gameTime)
{
/*if (path != null && path.Count != 0)
{
var nextNode = path.Last();
var nodePos = new Point(nextNode.X, nextNode.Y);
Parent.Transform.Grid.Position = nodePos;
if (Parent.Transform.World == (Vector2)Parent.Transform.Grid)
path.Remove(nextNode);
}*/
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)
return null;
if (path.Count == 0)
return null;
var nextNode = path.Last();
path.Remove(nextNode);
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();
if (appendCollisionMap != null)
foreach (var point in appendCollisionMap)
mapCollisionMap[point.X, point.Y] = 0;
pathFinder = new AStar.PathFinderFast(mapCollisionMap);
pathFinder.Formula = AStar.HeuristicFormula.Manhattan;
pathFinder.Diagonals = false;
pathFinder.HeavyDiagonals = false;
pathFinder.HeuristicEstimate = 2;
pathFinder.PunishChangeDirection = false;
pathFinder.TieBreaker = false;
pathFinder.SearchLimit = 50000;
pathFinder.DebugProgress = false;
pathFinder.DebugFoundPath = false;
var _start = new System.Drawing.Point(start.X, start.Y);
var _goal = new System.Drawing.Point(goal.X, goal.Y);
//path = Core.PathFinder.FindPath(_start, _goal);
path = pathFinder.FindPath(_start, _goal);
if (path == null)
Debug.WriteLine(this.Parent.ToString() + ": Path not found!");
//this.CollisionMap = new byte[100, 100];
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);
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using AStar;
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
{
Position = new Point(aStarNode.X, aStarNode.Y),
F = aStarNode.F,
G = aStarNode.G
};
}
}
/// <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.FindPath(this.Parent.GetComponent<Transform>().Grid.Position, value, null);
}
}
/// <summary>
/// Is a path in progress?
/// </summary>
public bool IsMoving
{
get
{
return path != null && path.Count() != 0;
}
}
public int Length
{
get
{
return (path != null) ? path.Count : 0;
}
}
private AStar.PathFinderFast pathFinder;
private List<AStar.PathFinderNode> path;
public PathFinder(Entity parent)
: base(parent)
{
}
public override void Update(GameTime gameTime)
{
/*if (path != null && path.Count != 0)
{
var nextNode = path.Last();
var nodePos = new Point(nextNode.X, nextNode.Y);
Parent.Transform.Grid.Position = nodePos;
if (Parent.Transform.World == (Vector2)Parent.Transform.Grid)
path.Remove(nextNode);
}*/
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)
return null;
if (path.Count == 0)
return null;
var nextNode = path.Last();
path.Remove(nextNode);
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();
if (appendCollisionMap != null)
foreach (var point in appendCollisionMap)
mapCollisionMap[point.X, point.Y] = 0;
pathFinder = new AStar.PathFinderFast(mapCollisionMap);
pathFinder.Formula = AStar.HeuristicFormula.Manhattan;
pathFinder.Diagonals = false;
pathFinder.HeavyDiagonals = false;
pathFinder.HeuristicEstimate = 2;
pathFinder.PunishChangeDirection = false;
pathFinder.TieBreaker = false;
pathFinder.SearchLimit = 50000;
pathFinder.DebugProgress = false;
pathFinder.DebugFoundPath = false;
var _start = new System.Drawing.Point(start.X, start.Y);
var _goal = new System.Drawing.Point(goal.X, goal.Y);
//path = Core.PathFinder.FindPath(_start, _goal);
path = pathFinder.FindPath(_start, _goal);
if (path == null)
Debug.WriteLine(this.Parent.ToString() + ": Path not found!");
//this.CollisionMap = new byte[100, 100];
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);
}
}
}
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -140,7 +140,7 @@ namespace DepthsBelow
{
foreach (var unit in core.Squad)
{
unit.AP = 0;
unit.AP = unit.MaxActionPoints;
unit.Fired = false;
}
@@ -227,10 +227,10 @@ namespace DepthsBelow
cost = rocketCost;
type = "Rocket";
}
if (soldier.AP <= soldier.NumberOfActionPoints - cost)
if (soldier.AP >= cost)
{
core.Volley.Add(new Shot(core.EntityManager, soldier.GetComponent<Component.Stat>(), type));
soldier.AP += cost;
soldier.AP -= cost;
soldier.Fired = true;
}
else
+11 -11
View File
@@ -35,16 +35,16 @@ namespace DepthsBelow
}
}
public int NumberOfActionPoints = 10;
int spentActionPoints = 0;
public int MaxActionPoints = 10;
int actionPointsLeft = 0;
public int AP
{
get { return spentActionPoints; }
get { return actionPointsLeft; }
set
{
spentActionPoints = value;
GetComponent<Component.Stat>().GetStep = spentActionPoints;
actionPointsLeft = value;
GetComponent<Component.Stat>().GetStep = actionPointsLeft;
}
}
@@ -174,17 +174,17 @@ namespace DepthsBelow
if (Transform.World == nodeWorldPos)
{
if (AP < NumberOfActionPoints)
{
AP++;
//if (AP < NumberOfActionPoints)
//{
//AP++;
lastLastNode = lastNode;
lastNode = nextNode;
nextNode = GetComponent<PathFinder>().Next();
}
else
//}
/*else
{
GetComponent<PathFinder>().Stop();
}
}*/
}
}
}