\r
namespace CarFire\r
{\r
+ /// <summary>\r
+ /// A type for the states of an artificually intelligent entity.\r
+ /// </summary>\r
public enum AiState\r
{\r
Standing,\r
}\r
\r
\r
+ /// <summary>\r
+ /// An example monster. This can serve as a starting place for\r
+ /// creating other monsters. This one just follows a path.\r
+ /// </summary>\r
public class SaberMonster : IMonster\r
{\r
+ /// <summary>\r
+ /// Construct this type of monster. This constructor is called\r
+ /// by the map when the game requests entities.\r
+ /// </summary>\r
+ /// <param name="identifier">The single character ID.</param>\r
+ /// <param name="position">The initial position on the map.</param>\r
+ /// <param name="info">More parameters.</param>\r
+ /// <param name="game">The game object reference.</param>\r
public SaberMonster(char identifier, Point position, Dictionary<string, string> info, Game game)\r
{\r
mId = identifier;\r
mMotion = new MovementManager(position);\r
+\r
+ // We need to keep the game reference in order to get the grid when we\r
+ // need to find paths.\r
mGame = game;\r
\r
+ // Get the speed of the monster. If not set in the map, it defaults to\r
+ // whatever the default of MovementManager is... 1 I think.\r
string speedString;\r
if (info.TryGetValue("speed", out speedString))\r
{\r
}\r
}\r
\r
+ // Start doing something...\r
StartPacing();\r
}\r
\r
\r
+ /// <summary>\r
+ /// Call this to switch the monster AI state to pacing and set up\r
+ /// the initial paths. The monster will start following the path it\r
+ /// was defined with in the map file.\r
+ /// </summary>\r
public void StartPacing()\r
{\r
mState = AiState.Pacing;\r
if (mIdlePath.Count == 0) return;\r
\r
// Determine the best (closest) waypoint to start at.\r
+ // We may not be on the path, so we have to walk to get on it.\r
mIdlePathIndex = 0;\r
int closest = int.MaxValue;\r
for (int i = 0; i < mIdlePath.Count; i++)\r
}\r
}\r
\r
+ // Find the path to get to the closest waypoint.\r
PathFinder pathFinder = new PathFinder(mGame.Grid);\r
mPath = new List<Point>(32);\r
mPath.Add(Coordinates);\r
{\r
if (mPathIndex >= mPath.Count)\r
{\r
+ // We're done with the current path, so find the path to\r
+ // the next waypoint... forever.\r
mIdlePathIndex++;\r
PathFinder pathFinder = new PathFinder(mGame.Grid);\r
mPath = new List<Point>(32);\r
mPathIndex = 0;\r
}\r
\r
+ // We need to make sure out direction is set to the next cell\r
+ // we want to be. If our current coordinates match that, we need\r
+ // to change our direction to get to the next cell.\r
if (mPath[mPathIndex % mPath.Count] == mMotion.Coordinates)\r
{\r
mPathIndex++;\r
\r
#region IMonster Members\r
\r
+ /// <summary>\r
+ /// I don't know what this is for.\r
+ /// </summary>\r
public bool visible\r
{\r
get { throw new NotImplementedException(); }\r
\r
#region ICharacter Members\r
\r
+ /// <summary>\r
+ /// Load the monster's content. This is called by the map when\r
+ /// the game requests the entities.\r
+ /// </summary>\r
+ /// <param name="contentManager">The zaphnod.</param>\r
public void LoadContent(ContentManager contentManager)\r
{\r
mTexture = contentManager.Load<Texture2D>("menuItem");\r
}\r
\r
+ /// <summary>\r
+ /// Update the monster's state. This should be called by the game\r
+ /// every "frame" (whenever the game is updating its state). In this\r
+ /// simple monster, all we need to do is update the motion manager.\r
+ /// </summary>\r
+ /// <param name="timeSpan"></param>\r
public void Update(TimeSpan timeSpan)\r
{\r
if (mState == AiState.Pacing)\r
}\r
}\r
\r
+ /// <summary>\r
+ /// Draw the monster. We just ask the map for our screen position,\r
+ /// passing it the position which the motion manager keeps track of.\r
+ /// </summary>\r
+ /// <param name="spriteBatch">The </param>\r
public void Draw(SpriteBatch spriteBatch)\r
{\r
Rectangle position = mGame.State.Map.GetRectangleFromCoordinates(mMotion.Position);\r
spriteBatch.Draw(mTexture, position, Color.White);\r
}\r
\r
+ /// <summary>\r
+ /// A monster should keep track of its health. This one doesn't.\r
+ /// </summary>\r
public int Health\r
{\r
get { throw new NotImplementedException(); }\r
}\r
\r
+ /// <summary>\r
+ /// This monster is invincible.\r
+ /// </summary>\r
+ /// <param name="amount"></param>\r
public void causeDamageTo(int amount)\r
{\r
throw new NotImplementedException();\r
}\r
\r
+ /// <summary>\r
+ /// Get the smoothed position.\r
+ /// </summary>\r
public Vector2 Position { get { return mMotion.Position; } }\r
\r
+ /// <summary>\r
+ /// Get the grid coordinates.\r
+ /// </summary>\r
public Point Coordinates { get { return mMotion.Coordinates; } }\r
\r
#endregion\r
char mId;\r
MovementManager mMotion;\r
\r
- List<Point> mIdlePath = new List<Point>();\r
- int mIdlePathIndex;\r
+ List<Point> mIdlePath = new List<Point>(); // List of waypoints that we got from the map.\r
+ int mIdlePathIndex; // Index to the waypoint we're heading for.\r
\r
- List<Point> mPath;\r
- int mPathIndex;\r
- Direction mPathDirection;\r
+ List<Point> mPath; // List of cells in the path between the position between where\r
+ // we started and the waypoint we're heading for.\r
+ int mPathIndex; // Index to the cell we're heading for.\r
+ Direction mPathDirection; // The direction between our current position and the place we're going.\r
\r
- AiState mState;\r
+ AiState mState; // What is the monster doing?\r
\r
- Texture2D mTexture;\r
+ Texture2D mTexture; // Obvious.\r
\r
#endregion\r
}\r