X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fcarfire;a=blobdiff_plain;f=CarFire%2FCarFire%2FCarFire%2FSaberMonster2.cs;fp=CarFire%2FCarFire%2FCarFire%2FSaberMonster2.cs;h=f522ab447763fc5faafd12d99f4024076c697127;hp=0000000000000000000000000000000000000000;hb=a716edefa6148bb1847b7029356d610a1886821f;hpb=0483d0578f0d160ea3e80bae57d4a3ba2b061d35 diff --git a/CarFire/CarFire/CarFire/SaberMonster2.cs b/CarFire/CarFire/CarFire/SaberMonster2.cs new file mode 100644 index 0000000..f522ab4 --- /dev/null +++ b/CarFire/CarFire/CarFire/SaberMonster2.cs @@ -0,0 +1,305 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace CarFire +{ + /// + /// A type for the states of an artificually intelligent entity. + /// + public enum AiState + { + Standing, + Pacing, + Chasing, + Dazed, + Fighting, + Retreating + } + + + /// + /// An example monster. This can serve as a starting place for + /// creating other monsters. This one just follows a path. + /// + public class SaberMonster2 : IMonster + { + //starting health + int health = 100; + /// + /// Construct this type of monster. This constructor is called + /// by the map when the game requests entities. + /// + /// The single character ID. + /// The initial position on the map. + /// More parameters. + /// The game object reference. + public SaberMonster2(char identifier, Point position, Dictionary info, Game game) + { + mId = identifier; + mMotion = new MovementManager(position); + + // We need to keep the game reference in order to get the grid when we + // need to find paths. + mGame = game; + + pathFinder = null; + + // Get the speed of the monster. If not set in the map, it defaults to + // whatever the default of MovementManager is... 1 I think. + string speedString; + if (info.TryGetValue("speed", out speedString)) + { + int? speed = Parse.Integer(speedString); + if (speed != null) mMotion.Speed = speed.Value; + } + + // Get the "idle path" coordinates loaded from the map. + string idlePath; + if (info.TryGetValue("path", out idlePath)) + { + string[] idlePathPoints = Parse.List(idlePath); + foreach (string pathPoint in idlePathPoints) + { + Point? point = Parse.Coordinates(pathPoint); + if (point != null) mIdlePath.Add(point.Value); + } + } + // Start doing something... + //StartPacing(); + } + + public void DefaultAction() + { + mState = AiState.Standing; + } + + public void Chasing(Point Chase) + { + Chasing(Chase.X, Chase.Y); + } + + /// + /// Call this to switch the monster AI state to Chasing and set up + /// the initial paths. A path to . + /// + public void Chasing(int X, int Y) + { + mState = AiState.Chasing; + + // Determine the best (closest) waypoint to start at. + // We may not be on the path, so we have to walk to get on it. + /* + mIdlePathIndex = 0; + int closest = int.MaxValue; + for (int i = 0; i < mIdlePath.Count; i++) + { + int distance = PathFinder.GetManhattanDistance(Coordinates, mIdlePath[i]); + if (distance < closest) + { + mIdlePathIndex = i; + closest = distance; + } + } + */ + + // Find the path to get to the closest waypoint. + if (pathFinder == null) + pathFinder = new PathFinder(mGame.Grid); + + mPath = new List(32); + mPath.Add(Coordinates); + List path = pathFinder.GetPath(mMotion.Coordinates, new Point(X,Y)); + if (path != null) + { + mPath.AddRange(path); + //mPath.Add(mIdlePath[mIdlePathIndex]); + } + mPathIndex = 0; + } + + /// + /// Call this to switch the monster AI state to pacing and set up + /// the initial paths. The monster will start following the path it + /// was defined with in the map file. + /// + public void StartPacing() + { + mState = AiState.Pacing; + + if (mIdlePath.Count == 0) return; + + // Determine the best (closest) waypoint to start at. + // We may not be on the path, so we have to walk to get on it. + mIdlePathIndex = 0; + int closest = int.MaxValue; + for (int i = 0; i < mIdlePath.Count; i++) + { + int distance = PathFinder.GetManhattanDistance(Coordinates, mIdlePath[i]); + if (distance < closest) + { + mIdlePathIndex = i; + closest = distance; + } + } + + // Find the path to get to the closest waypoint. + PathFinder pathFinder = new PathFinder(mGame.Grid); + mPath = new List(32); + mPath.Add(Coordinates); + List path = pathFinder.GetPath(mMotion.Coordinates, mIdlePath[mIdlePathIndex]); + if (path != null) + { + mPath.AddRange(path); + mPath.Add(mIdlePath[mIdlePathIndex]); + } + mPathIndex = 0; + } + + Direction GetDirectionToNextCell() + { + if (mPathIndex >= mPath.Count) + { + mState = AiState.Standing; + } + + // We need to make sure out direction is set to the next cell + // we want to be. If our current coordinates match that, we need + // to change our direction to get to the next cell. + if (mPath[mPathIndex % mPath.Count] == mMotion.Coordinates) + { + mPathIndex++; + mPathDirection = MovementManager.GetDirection(mMotion.Coordinates, mPath[mPathIndex % mPath.Count]); + } + + return mPathDirection; + } + + + #region IMonster Members + + /// + /// I don't know what this is for. + /// + public bool visible + { + get { throw new NotImplementedException(); } + } + + #endregion + + + #region ICharacter Members + + /// + /// Load the monster's content. This is called by the map when + /// the game requests the entities. + /// + /// The zaphnod. + public void LoadContent(ContentManager contentManager) + { + mTexture = contentManager.Load("menuItem"); + } + + /// + /// Update the monster's state. This should be called by the game + /// every "frame" (whenever the game is updating its state). In this + /// simple monster, all we need to do is update the motion manager. + /// + /// + public void Update(TimeSpan timeSpan) + { + switch (mState) + { + case AiState.Pacing: + case AiState.Chasing: + mMotion.Update(timeSpan, GetDirectionToNextCell()); + break; + case AiState.Standing: + case AiState.Dazed: + case AiState.Fighting: + case AiState.Retreating: + break; + + } + } + + /// + /// Draw the monster. We just ask the map for our screen position, + /// passing it the position which the motion manager keeps track of. + /// + /// The + public void Draw(SpriteBatch spriteBatch) + { + Rectangle position = mGame.State.Map.GetRectangleFromCoordinates(mMotion.Position); + spriteBatch.Draw(mTexture, position, Color.White); + } + + /// + /// A monster should keep track of its health. This one doesn't. + /// + public int Health + { + get { return this.health; } + + } + + /// + /// This monster is invincible. + /// + /// + public void causeDamageTo(int amount) + { + this.health -= amount; + } + + public bool IsCollidable { get { return true; } } + + /// + /// Get the smoothed position. + /// + public Vector2 Position { get { return mMotion.Position; } } + + /// + /// Get the grid coordinates. + /// + public Point Coordinates { + get { return mMotion.Coordinates; } + set { mMotion = new MovementManager(value, mMotion.Speed); } + } + + /// + /// Get the entity identifier. + /// + public char Identifier { get { return mId; } } + + #endregion + + + #region Private Variables + + Game mGame; + + char mId; + MovementManager mMotion; + + PathFinder pathFinder; + List mIdlePath = new List(); // List of waypoints that we got from the map. + int mIdlePathIndex; // Index to the waypoint we're heading for. + + List mPath; // List of cells in the path between the position between where + // we started and the waypoint we're heading for. + int mPathIndex; // Index to the cell we're heading for. + Direction mPathDirection; // The direction between our current position and the place we're going. + + AiState mState; // What is the monster doing? + + Texture2D mTexture; // Obvious. + + #endregion + } +}