]> Dogcows Code - chaz/carfire/commitdiff
SaberMonster loads from map file and walks around using the path finder, and a lot...
authorCharles <Charles@92bb83a3-7c8f-8a45-bc97-515c4e399668>
Wed, 21 Apr 2010 03:03:20 +0000 (03:03 +0000)
committerCharles <Charles@92bb83a3-7c8f-8a45-bc97-515c4e399668>
Wed, 21 Apr 2010 03:03:20 +0000 (03:03 +0000)
git-svn-id: https://bd85.net/svn/cs3505_group@122 92bb83a3-7c8f-8a45-bc97-515c4e399668

12 files changed:
CarFire/CarFire/CarFire/CarFire.csproj
CarFire/CarFire/CarFire/Content/Maps/sandbox.cfmap
CarFire/CarFire/CarFire/Content/Maps/stable.cfmap
CarFire/CarFire/CarFire/Display.cs
CarFire/CarFire/CarFire/Game.cs
CarFire/CarFire/CarFire/Human.cs
CarFire/CarFire/CarFire/IEntity.cs [new file with mode: 0644]
CarFire/CarFire/CarFire/IPlayer.cs
CarFire/CarFire/CarFire/Map.cs
CarFire/CarFire/CarFire/MovementManager.cs
CarFire/CarFire/CarFire/PathFinder.cs
CarFire/CarFire/CarFire/SaberMonster.cs [new file with mode: 0644]

index 6548035b6c3c76a6bd78c464af151e63e920654d..0b85b765923542f4c63ba75fe7c748fa84fcc05b 100644 (file)
@@ -84,6 +84,8 @@
     </Reference>\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <Compile Include="IEntity.cs" />\r
+    <Compile Include="SaberMonster.cs" />\r
     <Compile Include="MovementManager.cs" />\r
     <Compile Include="PathFinder.cs" />\r
     <Compile Include="ChatInfo.cs" />\r
index e663d508386088c7e6d7a569c27dd4227d8c77f1..28050cf09acc976840ee7c27c75adac087b8a25a 100644 (file)
 \r
 [A]\r
        type = SaberMonster\r
+       speed = 10\r
        path = [1,1] [5,6] wait(5) [45,2]\r
-       loop = true\r
        create = [5,7] [2,3]\r
-[B]\r
-       condition = has(key)\r
-       event = wait(2) remove([2,6]) remove([2,7])\r
+;[B]\r
+;      condition = has(key)\r
+;      event = wait(2) remove([2,6]) remove([2,7])\r
 \r
 ; Function ideas:\r
 ; has(entity)           Player has given entity in his inventory.\r
 +------------------------------------------------------------------------------+\r
 |                                                                              |\r
 | 1                                                                            |\r
-|             B                                                                |\r
+|                                                                              |\r
 | 2                +----                                                       |\r
 |                  |                                                           |\r
-| 3                |        A                                                  |\r
+| 3                |                                                           |\r
 |                  |                                                           |\r
 | 4                |                                                           |\r
-|                  |                                                           |\r
+|                A |                                                           |\r
 +-------------+----+                                                           |\r
 |             |                                                                |\r
 |             |                                                                |\r
index fe5a7e29c1ed669ba83afdd72398f87355a02868..385626cabc621a1ce771c6c5b0f34cf6a1a0b854 100644 (file)
@@ -8,6 +8,11 @@
        tileset = FuturisticBuilding\r
        numplayers = <1,4>\r
 \r
+[M]\r
+       type = SaberMonster\r
+       speed = 10\r
+       path = [16,8] [20,6] wait(5) [56,9] [71,17] [75,2] [11,13]\r
+\r
 [maptable]\r
 +------------------------------------------------------------------------------+\r
 |                                                                              |\r
@@ -21,7 +26,7 @@
 |                  |                                       |                   |\r
 +-------------+----+                                       |      \       /    |\r
 |             |                                            |       \     /     |\r
-|             |                                            |        \   /      |\r
+|          M  |                                            |        \   /      |\r
 |             |                                            |         \ /       |\r
 |             |          \ @ # $ % ^ & * ( )               |          |        |\r
 |     +-------+                                            |         / \       |\r
index 9fecb5bcbdcdc849f02b64de42e7275b478e2129..aceadfe14dddf4165520be4f47d56a8aab6409e9 100644 (file)
@@ -26,14 +26,13 @@ namespace CarFire
         IPlayer[] mCharacters = new IPlayer[4];\r
         Texture2D everything;\r
         Texture2D projectile1;\r
-        Map mMap;\r
-        int currentCenterX = 5;\r
-        int currentCenterY = 5;\r
+        Game mGame;\r
 #if SINGLE_TEST\r
         List<Keys> mLastPressedKeys = new List<Keys>();\r
 #endif\r
-        public Display()\r
+        public Display(Game game)\r
         {\r
+            mGame = game;\r
             /*\r
             mMap = aMap;\r
             mCharacters = characters;\r
@@ -48,9 +47,6 @@ namespace CarFire
         {\r
             everything = contentManager.Load<Texture2D>("cs");\r
             projectile1 = contentManager.Load<Texture2D>("projectile");\r
-            mMap = contentManager.Load<Map>("Maps/stable");\r
-            Map.DefaultTile = contentManager.Load<Texture2D>("default");\r
-            mMap.CenterCell = new Vector2(currentCenterX,currentCenterY);\r
         }\r
 \r
         /// <summary>\r
@@ -99,7 +95,7 @@ namespace CarFire
             for (int i = 0; i < mProjectiles.Count; i++ )\r
             {\r
                 bool removed = false;\r
-                if (!mMap.IsCellOpen(new Point(mProjectiles[i].Coordinates.X, mProjectiles[i].Coordinates.Y)))\r
+                if (!mGame.State.Map.IsCellOpen(new Point(mProjectiles[i].Coordinates.X, mProjectiles[i].Coordinates.Y)))\r
                 {\r
                \r
                     mProjectiles.RemoveAt(i);\r
@@ -127,32 +123,32 @@ namespace CarFire
                 }\r
             }\r
             //Update input for each player\r
-            for (int i = 0; i < 4; i++)\r
+            for (int i = 0; i < mGame.State.NumberOfPlayers; i++)\r
             {\r
                 //If player has not selected a player yet let them select one.\r
                 if (mCharacters[i] == null)\r
                 {\r
-                    if (state.keysDown[i].Contains(Keys.Enter))\r
+                    if (mGame.State.GetKeysDown(i).Contains(Keys.Enter))\r
                     {\r
-                        mCharacters[i] = new Human(mMap, "", everything, projectile1, this, mMap.GetStartingPositionForPlayer(i+1));\r
+                        mCharacters[i] = new Human(mGame, "", everything, projectile1, this, mGame.State.Map.GetStartingPositionForPlayer(i + 1));\r
                     }\r
                 }\r
                 //Regular player input updates\r
                 else\r
                 {\r
 \r
-                    mCharacters[i].MovePlayer(timespan, state.keysDown[i]);\r
+                    mCharacters[i].MovePlayer(timespan, mGame.State.GetKeysDown(i));\r
                    \r
                 }\r
             }\r
             if (mCharacters[0] != null)\r
             {\r
-                mMap.CenterCell = mCharacters[0].Position;\r
+                mGame.State.Map.CenterCell = mCharacters[0].Position;\r
             }\r
                 //Handle wall collisions of projectiles again...\r
             for (int i = 0; i < mProjectiles.Count; i++)\r
             {\r
-                if (!mMap.IsCellOpen(new Point(mProjectiles[i].Coordinates.X, mProjectiles[i].Coordinates.Y)))\r
+                if (!mGame.State.Map.IsCellOpen(new Point(mProjectiles[i].Coordinates.X, mProjectiles[i].Coordinates.Y)))\r
                 {\r
                     mProjectiles.RemoveAt(i);\r
                     i--;\r
@@ -161,8 +157,8 @@ namespace CarFire
             }\r
 \r
 #if INGAME_ZOOM\r
-            if (Keyboard.GetState().IsKeyDown(Keys.PageUp)) mMap.Zoom = mMap.Zoom + 0.5f;\r
-            if (Keyboard.GetState().IsKeyDown(Keys.PageDown)) mMap.Zoom = mMap.Zoom - 0.5f;\r
+            if (Keyboard.GetState().IsKeyDown(Keys.PageUp)) mGame.State.Map.Zoom = mGame.State.Map.Zoom + 0.5f;\r
+            if (Keyboard.GetState().IsKeyDown(Keys.PageDown)) mGame.State.Map.Zoom = mGame.State.Map.Zoom - 0.5f;\r
 #endif\r
         }\r
 \r
@@ -172,12 +168,14 @@ namespace CarFire
         /// <param name="spriteBatch">Used to draw with</param>\r
         public void Draw(SpriteBatch spriteBatch)\r
         {\r
-            mMap.Draw(spriteBatch);\r
+            mGame.State.Map.Draw(spriteBatch);\r
+            mGame.State.Entities.ForEach(delegate(IEntity e) { e.Draw(spriteBatch); });\r
+\r
             foreach(Projectile projectile in mProjectiles)\r
             {\r
                 projectile.Draw(spriteBatch);\r
             }\r
-            for(int i = 0; i < 4; i++)//IPlayer character in mCharacters)\r
+            for(int i = 0; i < mGame.State.NumberOfPlayers; i++)//IPlayer character in mCharacters)\r
             {\r
 \r
                 if (mCharacters[i] != null)\r
index b1b723866dd838003522da855f9121f688c20eb0..fa3fbd1b9e7b6a5a4134b40f135cf1ddb1144d2a 100644 (file)
@@ -9,203 +9,258 @@ using Microsoft.Xna.Framework.Input;
 \r
 namespace CarFire\r
 {\r
-    // Everything in objects built from this class represent the critical game state\r
+    /// <summary>\r
+    /// Container class for the whole state of the game.\r
+    /// </summary>\r
     public class GameState\r
     {\r
-        public long frameNumber;\r
+        #region Public Properties\r
 \r
-        private long checksum;\r
-        public long Checksum { get { return checksum; } }\r
+        public long FrameNumber { get { return mFrameNumber; } }\r
 \r
-        public bool[] isGameOver;\r
-        public bool[] isTerminated;\r
+        public long Checksum { get { return mChecksum; } }\r
 \r
-        // Since this is not a game, I'll just keep track of the user inputs as the game state.\r
+        public int NumberOfPlayers { get { return mNumberOfPlayers; } }\r
 \r
-        public int[] mouseLocationX;\r
-        public int[] mouseLocationY;\r
-        public bool[] mouseButton;\r
-        public List<Keys>[] keysDown;\r
-        public int[] keypressCount;\r
+        public Map Map;\r
+        public List<IEntity> Entities = new List<IEntity>();\r
 \r
-        public long elapsedTime;\r
+        #endregion\r
 \r
-        /* Constructor */\r
-        public GameState()\r
-        {\r
-            frameNumber = 0;\r
-            checksum = 0;\r
 \r
-            isGameOver = new bool[4];\r
-            isTerminated = new bool[4];\r
+        #region Public Methods\r
 \r
-            mouseLocationX = new int[4];\r
-            mouseLocationY = new int[4];\r
-            mouseButton = new bool[4];\r
-            keysDown = new List<Keys>[4];\r
-            for (int i = 0; i < 4; i++)\r
-                keysDown[i] = new List<Keys>();\r
-            keypressCount = new int[4];\r
+        /// <summary>\r
+        /// Construct a game state container with the number of players.\r
+        /// </summary>\r
+        /// <param name="numPlayers">Number of players.</param>\r
+        public GameState(int numPlayers)\r
+        {\r
+            mNumberOfPlayers = numPlayers;\r
+            mFrameNumber = 0;\r
 \r
-            elapsedTime = 0;\r
+            mIsGameOver = new bool[numPlayers];\r
+            mIsTerminated = new bool[numPlayers];\r
 \r
-            checksum = 0;\r
+            mMouseLocation = new Point[numPlayers];\r
+            mMouseButton = new bool[numPlayers];\r
+            mKeysDown = new List<Keys>[numPlayers];\r
+            for (int i = 0; i < numPlayers; i++) mKeysDown[i] = new List<Keys>();\r
+\r
+            mKeypressCount = new int[numPlayers];\r
+            mElapsedTime = 0;\r
+            mChecksum = 0;\r
         }\r
 \r
-        /* The game engine! */\r
-        public void advanceFrame(NextInputs inputs, long milliseconds)\r
+        \r
+        /// <summary>\r
+        /// Should be called by the Game class to advance the state\r
+        /// to the next frame.\r
+        /// </summary>\r
+        /// <param name="inputs">The inputs that occurred to be\r
+        /// applied this coming frame.</param>\r
+        /// <param name="milliseconds">Milliseconds; used for the checksum.</param>\r
+        public void AdvanceFrame(NextInputs inputs, long milliseconds)\r
         {\r
-            // Advance frame number\r
-            frameNumber++;\r
-\r
-            // Advance game - for the test harness, just record statistics and input states.\r
+            mFrameNumber++;\r
+            mElapsedTime += milliseconds;\r
 \r
-            elapsedTime += milliseconds;\r
-\r
-            for (int player = 0; player < 4; player++)\r
+            for (int player = 0; player < NumberOfPlayers; player++)\r
             {\r
+                if (inputs.IsMousePressedChanged[player])\r
+                {\r
+                    mMouseButton[player] = inputs.MousePressed[player];\r
+                }\r
 \r
-                //if (isGameOver[player])\r
-                //    continue;\r
-\r
-                if (inputs.mousePressedChanged[player])\r
-                    mouseButton[player] = inputs.mousePressed[player];\r
-\r
-                if (inputs.mouseLocationChanged[player])\r
+                if (inputs.IsMouseLocationChanged[player])\r
                 {\r
-                    mouseLocationX[player] = inputs.mouseLocationX[player];\r
-                    mouseLocationY[player] = inputs.mouseLocationY[player];\r
+                    mMouseLocation[player] = inputs.MouseLocation[player];\r
                 }\r
 \r
-                foreach (Keys k in inputs.keysPressed[player])\r
-                    if (!keysDown[player].Contains(k))\r
+                foreach (Keys k in inputs.KeysPressed[player])\r
+                {\r
+                    if (!mKeysDown[player].Contains(k))\r
                     {\r
-                        keysDown[player].Add(k);\r
-                        keypressCount[player]++;\r
+                        mKeysDown[player].Add(k);\r
+                        mKeypressCount[player]++;\r
                     }\r
+                }\r
 \r
-                foreach (Keys k in inputs.keysReleased[player])\r
-                    keysDown[player].Remove(k);\r
-\r
-                // If the mouse was pressed for a certain player, activate game over or terminated states as appropriate\r
+                foreach (Keys k in inputs.KeysReleased[player]) mKeysDown[player].Remove(k);\r
+            }\r
 \r
-                if (inputs.mousePressed[player])\r
-                    for (int p = 0; p < 4; p++)\r
-                    {\r
-                        int x = 200 * p + 10;\r
-                        int y = 220;\r
-\r
-                        if (mouseLocationX[player] >= x && mouseLocationY[player] >= y &&\r
-                            mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25)\r
-                        {\r
-                            isGameOver[p] = true;\r
-                        }\r
-                        y += 25;\r
-                        if (mouseLocationX[player] >= x && mouseLocationY[player] >= y &&\r
-                            mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25)\r
-                        {\r
-                            isGameOver[p] = true;\r
-                            isTerminated[p] = true;\r
-                        }\r
-                    }\r
-                \r
+            ComputeChecksum();\r
+        }\r
 \r
-            }\r
 \r
-            // Advance the checksum.\r
+        /// <summary>\r
+        /// Get the mouse location for a player.\r
+        /// </summary>\r
+        /// <param name="playerNum">Player Number.</param>\r
+        /// <returns>Mouse location.</returns>\r
+        public Point GetMouseLocation(int playerNum)\r
+        {\r
+            return mMouseLocation[playerNum];\r
+        }\r
 \r
-            computeChecksum();\r
+        /// <summary>\r
+        /// Get the mouse button state for a player.\r
+        /// </summary>\r
+        /// <param name="playerNum">Player number.</param>\r
+        /// <returns>Mouse button state..</returns>\r
+        public bool GetMouseButton(int playerNum)\r
+        {\r
+            return mMouseButton[playerNum];\r
+        }\r
 \r
+        /// <summary>\r
+        /// Get the keyboard state for a player.\r
+        /// </summary>\r
+        /// <param name="playerNum">Player number.</param>\r
+        /// <returns>Keyboard state.</returns>\r
+        public List<Keys> GetKeysDown(int playerNum)\r
+        {\r
+            return mKeysDown[playerNum];\r
         }\r
 \r
-        /* Just hash the values */\r
-        private long computeChecksum()\r
+        #endregion\r
+\r
+\r
+        #region Private Methods\r
+\r
+        // Calculates a checksum for debugging network synchronization issues.\r
+        long ComputeChecksum()\r
         {\r
-            checksum += frameNumber;\r
-            for (int i = 0; i < 4; i++)\r
+            mChecksum += FrameNumber;\r
+            for (int i = 0; i < NumberOfPlayers; i++)\r
             {\r
-                checksum = checksum + keypressCount[i];\r
-                checksum = checksum * 3 + (isGameOver[i] ? 1 : 2);\r
-                checksum = checksum * 3 + (isTerminated[i] ? 1 : 2);\r
-                foreach (Keys k in keysDown[i])\r
-                    checksum = checksum * 257 + (int)k;\r
-                checksum = checksum * 25789 + mouseLocationX[i] * 259 + mouseLocationY[i] + 375;\r
-                checksum = checksum * 3 + (mouseButton[i] ? 1 : 2);\r
+                mChecksum = mChecksum + mKeypressCount[i];\r
+                mChecksum = mChecksum * 3 + (mIsGameOver[i] ? 1 : 2);\r
+                mChecksum = mChecksum * 3 + (mIsTerminated[i] ? 1 : 2);\r
+                foreach (Keys k in mKeysDown[i])\r
+                    mChecksum = mChecksum * 257 + (int)k;\r
+                mChecksum = mChecksum * 25789 + mMouseLocation[i].X * 259 + mMouseLocation[i].Y + 375;\r
+                mChecksum = mChecksum * 3 + (mMouseButton[i] ? 1 : 2);\r
 \r
             }\r
-            checksum += elapsedTime;\r
+            mChecksum += mElapsedTime;\r
 \r
-            return checksum;\r
+            return mChecksum;\r
         }\r
+\r
+        #endregion\r
+\r
+\r
+        #region Private Variables\r
+\r
+        int mNumberOfPlayers;\r
+        public Point[] mMouseLocation;\r
+        public bool[] mMouseButton;\r
+        public List<Keys>[] mKeysDown;\r
+\r
+        long mFrameNumber;\r
+\r
+        bool[] mIsGameOver;\r
+        bool[] mIsTerminated;\r
+\r
+        int[] mKeypressCount;\r
+        long mElapsedTime;\r
+        long mChecksum;\r
+\r
+        #endregion\r
     }\r
-    //code from Prof Jensen's TestHarness\r
-    // This class encapsulates inputs from the players.\r
+\r
+    /// <summary>\r
+    /// Container class for all the inputs for a single frame.\r
+    /// </summary>\r
     public class NextInputs\r
     {\r
-        public List<Keys>[] keysPressed;\r
-        public List<Keys>[] keysReleased;\r
-        public int[] mouseLocationX;\r
-        public int[] mouseLocationY;\r
-        public bool[] mouseLocationChanged;\r
-        public bool[] mousePressed;\r
-        public bool[] mousePressedChanged;\r
-\r
-        public NextInputs()\r
+        public List<Keys>[] KeysPressed;\r
+        public List<Keys>[] KeysReleased;\r
+        public Point[] MouseLocation;\r
+        public bool[] IsMouseLocationChanged;\r
+        public bool[] MousePressed;\r
+        public bool[] IsMousePressedChanged;\r
+\r
+        public NextInputs(int numPlayers)\r
         {\r
-            keysPressed = new List<Keys>[4];\r
-            keysReleased = new List<Keys>[4];\r
-            mouseLocationX = new int[4];\r
-            mouseLocationY = new int[4];\r
-            mouseLocationChanged = new bool[4];\r
-            mousePressed = new bool[4];\r
-            mousePressedChanged = new bool[4];\r
-            for (int i = 0; i < 4; i++)\r
-                keysPressed[i] = new List<Keys>();\r
-            for (int i = 0; i < 4; i++)\r
-                keysReleased[i] = new List<Keys>();\r
+            KeysPressed = new List<Keys>[numPlayers];\r
+            KeysReleased = new List<Keys>[numPlayers];\r
+            IsMouseLocationChanged = new bool[numPlayers];\r
+            MousePressed = new bool[numPlayers];\r
+            IsMousePressedChanged = new bool[numPlayers];\r
+            for (int i = 0; i < numPlayers; i++) KeysPressed[i] = new List<Keys>();\r
+            for (int i = 0; i < numPlayers; i++) KeysReleased[i] = new List<Keys>();\r
         }\r
-       \r
     }\r
 \r
+\r
+    /// <summary>\r
+    /// The big kahuna.\r
+    /// </summary>\r
     public class Game : IDeterministicGame\r
     {\r
-        #region IDeterministicGame Members\r
-        List<IPlayer> mPlayers;\r
-        NextInputs inputs;\r
-        Object[] playerIdentifiers;\r
-        Display mDisplay;\r
-        Map mMap;\r
+        #region Public Properties\r
+\r
+        /// <summary>\r
+        /// Get the content manager associated with this game.\r
+        /// </summary>\r
+        public ContentManager ContentManager { get { return mContentManager; } }\r
+\r
+        /// <summary>\r
+        /// Get the state.\r
+        /// </summary>\r
+        public GameState State;\r
+\r
+        public bool[,] Grid\r
+        {\r
+            get\r
+            {\r
+                bool[,] grid = State.Map.Grid;\r
+                foreach (IEntity entity in State.Entities)\r
+                {\r
+                    Point coordinates = entity.Coordinates;\r
+                    grid[coordinates.X, coordinates.Y] = true;\r
+                }\r
+                return grid;\r
+            }\r
+        }\r
+\r
+        #endregion\r
+\r
 \r
-        GameState state;\r
-        int thisPlayerID;\r
+        #region Public Methods\r
+\r
+        public bool IsCellOpen(Point point)\r
+        {\r
+            if (!State.Map.IsCellOpen(point)) return false;\r
+            foreach (IEntity entity in State.Entities)\r
+            {\r
+                if (entity.Coordinates == point) return false;\r
+            }\r
+            return true;\r
+        }\r
 \r
         public Game()\r
         {\r
-            mDisplay = new Display();\r
-            mPlayers = new List<IPlayer>();\r
-            playerIdentifiers = new Object[4];\r
+            mDisplay = new Display(this);\r
         }\r
         public void LoadContent(ContentManager contentManager)\r
         {\r
-            //Texture2D everything = contentManager.Load<Texture2D>("default");\r
+            mContentManager = contentManager;\r
             mDisplay.LoadContent(contentManager);\r
-            int currentCenterX = 5; //Creates a map like the one in Display\r
-            int currentCenterY = 5;\r
-            mMap = contentManager.Load<Map>("Maps/stable");\r
-            Map.DefaultTile = contentManager.Load<Texture2D>("default");\r
-            mMap.CenterCell = new Vector2(currentCenterX, currentCenterY);\r
-            \r
         }\r
 \r
         public void UnloadContent()\r
         {\r
         }\r
 \r
-        private int idPlayer(Object playerIdentifier)\r
+        private int GetPlayerNumber(Object playerIdentifier)\r
         {\r
-            for (int i = 0; i < playerIdentifiers.Length; i++)\r
-                if (playerIdentifiers[i] == playerIdentifier)\r
-                    return i;\r
+            for (int i = 0; i < mPlayerIdentifiers.Length; i++)\r
+            {\r
+                if (mPlayerIdentifiers[i] == playerIdentifier) return i;\r
+            }\r
             throw new Exception("Illegal player identifier" + playerIdentifier);\r
         }\r
 \r
@@ -224,21 +279,23 @@ namespace CarFire
             get { return 4; }\r
         }\r
 \r
-        public void ResetGame(object[] PlayerIdentifiers, object thisPlayer)\r
+        public void ResetGame(object[] playerIdentifiers, object thisPlayer)\r
         {\r
-            // Now the test harness will at least run with less than 4 players...\r
-            int numPlayers = PlayerIdentifiers.Count();\r
-            for (int i = 0; i < numPlayers; i++)\r
-                this.playerIdentifiers[i] = PlayerIdentifiers[i];\r
+            int numPlayers = playerIdentifiers.Count();\r
 \r
-            // Create new game state and inputs objects.\r
+            mPlayerIdentifiers = new object[numPlayers];\r
+            for (int i = 0; i < numPlayers; i++) mPlayerIdentifiers[i] = playerIdentifiers[i];\r
 \r
-            state = new GameState();\r
-            inputs = new NextInputs();\r
+            mThisPlayerID = GetPlayerNumber(thisPlayer);\r
 \r
-            // Record 'this' player.\r
+            State = new GameState(numPlayers);\r
+            mInputs = new NextInputs(numPlayers);\r
+\r
+            State.Map = mContentManager.Load<Map>("Maps/stable");\r
+            State.Map.Game = this;\r
+            State.Entities = State.Map.GetAllEntities();\r
+            Map.DefaultTile = mContentManager.Load<Texture2D>("default");\r
 \r
-            this.thisPlayerID = idPlayer(thisPlayer);\r
             /*\r
             mPlayers.Clear();\r
             for (int i = 0; i < PlayerIdentifiers.Length; i++)\r
@@ -255,13 +312,12 @@ namespace CarFire
                 Point starting = mMap.GetStartingPositionForPlayer(i + 1);\r
                 mPlayers[i].Spawn(new Vector2(starting.X, starting.Y));\r
             }\r
-             */\r
-           \r
+            */\r
         }\r
 \r
         public long CurrentFrameNumber\r
         {\r
-            get { return state.frameNumber; }\r
+            get { return State.FrameNumber; }\r
         }\r
 \r
         public long CurrentChecksum\r
@@ -272,13 +328,13 @@ namespace CarFire
         public void ApplyKeyInput(object playerIdentifier, Keys key, bool isKeyPressed)\r
         {\r
             //code from Prof Jensen's TestHarness\r
-            int player = idPlayer(playerIdentifier);\r
+            int player = GetPlayerNumber(playerIdentifier);\r
 \r
-            if (isKeyPressed && !inputs.keysPressed[player].Contains(key))\r
-                inputs.keysPressed[player].Add(key);\r
+            if (isKeyPressed && !mInputs.KeysPressed[player].Contains(key))\r
+                mInputs.KeysPressed[player].Add(key);\r
 \r
-            if (!isKeyPressed && !inputs.keysReleased[player].Contains(key))\r
-                inputs.keysReleased[player].Add(key);\r
+            if (!isKeyPressed && !mInputs.KeysReleased[player].Contains(key))\r
+                mInputs.KeysReleased[player].Add(key);\r
            \r
         }\r
 \r
@@ -304,11 +360,12 @@ namespace CarFire
 \r
         public long Update(TimeSpan elapsedTime)\r
         {\r
-            state.advanceFrame(inputs, elapsedTime.Milliseconds);  // Apply the inputs, advance game state.\r
-            mDisplay.Update(elapsedTime, state);\r
-            inputs = new NextInputs();  // Start with inputs cleared on the next frame.\r
+            State.AdvanceFrame(mInputs, elapsedTime.Milliseconds);  // Apply the inputs, advance game state.\r
+            mDisplay.Update(elapsedTime, State);\r
+            State.Entities.ForEach(delegate(IEntity e) { e.Update(elapsedTime); });\r
+            mInputs = new NextInputs(State.NumberOfPlayers);  // Start with inputs cleared on the next frame.\r
             //mDisplay.Update(elapsedTime);\r
-            return state.frameNumber;\r
+            return State.FrameNumber;\r
            \r
         }\r
 \r
@@ -319,5 +376,18 @@ namespace CarFire
         }\r
 \r
         #endregion\r
+\r
+\r
+        #region Private Variables\r
+\r
+        Display mDisplay;\r
+\r
+        ContentManager mContentManager;\r
+        NextInputs mInputs;\r
+\r
+        Object[] mPlayerIdentifiers;\r
+        int mThisPlayerID;\r
+\r
+        #endregion\r
     }\r
 }\r
index 519d9d02f14908767e150112472c01d7638d6bd1..08d962a1e682042ef420fab99b59b8fb52815d78 100644 (file)
@@ -22,7 +22,7 @@ namespace CarFire
         const int shootCoolDown = 10;\r
         State state;\r
         String CharName;\r
-        Map theMap;\r
+        Game game;\r
         Texture2D charModel;\r
         Texture2D projectileModel;\r
         int health;\r
@@ -40,9 +40,9 @@ namespace CarFire
         int projectileCoolDown;\r
         \r
 \r
-        public Human(Map _theMap, String Name, Texture2D model, Texture2D projectile, Display mDisplay, Point position)\r
+        public Human(Game theGame, String Name, Texture2D model, Texture2D projectile, Display mDisplay, Point position)\r
         {\r
-            theMap = _theMap;\r
+            game = theGame;\r
             CharName = Name;\r
             theDisplay = mDisplay;\r
             health = 100;\r
@@ -55,7 +55,7 @@ namespace CarFire
             projectileSpeed = 30;\r
 \r
             // Speed is the number of grid cells you can move through per second.\r
-            mMotion = new MovementManager(position, 5.0f);\r
+            mMotion = new MovementManager(position, 8.0f);\r
         }\r
 \r
         public void LoadContent(ContentManager contentManager)\r
@@ -65,26 +65,18 @@ namespace CarFire
 \r
         }\r
 \r
-        public void UnloadContent()\r
-        {\r
-\r
-        }\r
 \r
-        public long Update(GameTime gameTime, NetworkManager networkGame)\r
+        public void Update(TimeSpan timeSpan)\r
         {\r
-            return 0;\r
-\r
         }\r
         /// <summary>\r
         /// This method will draw a character to the screen.\r
         /// </summary>\r
         /// <param name="spriteBatch"></param>\r
-        /// <returns></returns>\r
-        public long Draw(SpriteBatch spriteBatch)\r
+        public void Draw(SpriteBatch spriteBatch)\r
         {\r
-            Rectangle position = theMap.GetRectangleFromCoordinates(mMotion.Position);\r
+            Rectangle position = game.State.Map.GetRectangleFromCoordinates(mMotion.Position);\r
             spriteBatch.Draw(charModel, position, Color.White);\r
-            return 0;\r
         }\r
 \r
         public int Health { get { return health; } }\r
@@ -124,7 +116,7 @@ namespace CarFire
             Point destination = MovementManager.GetNeighborCell(mMotion.Coordinates, moveLeft, moveRight, moveUp, moveDown);\r
             if (!keysPressed.Contains(Keys.LeftControl))\r
             {\r
-                if (theMap.IsCellOpen(destination))\r
+                if (game.IsCellOpen(destination))\r
                 {\r
                     mMotion.Update(timeSpan, moveLeft, moveRight, moveUp, moveDown);\r
                 }\r
@@ -173,7 +165,7 @@ namespace CarFire
                     toShoot.Normalize();\r
                     toShoot *= projectileSpeed;\r
                     projectileCoolDown = shootCoolDown;\r
-                    theDisplay.AddProjectiles(new Projectile(theMap, projectileModel,\r
+                    theDisplay.AddProjectiles(new Projectile(game.State.Map, projectileModel,\r
                         toShoot, new Point(startX, startY)));\r
 \r
                     /*\r
diff --git a/CarFire/CarFire/CarFire/IEntity.cs b/CarFire/CarFire/CarFire/IEntity.cs
new file mode 100644 (file)
index 0000000..cfa72c2
--- /dev/null
@@ -0,0 +1,45 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Content;\r
+using Microsoft.Xna.Framework.Graphics;\r
+\r
+namespace CarFire\r
+{\r
+    /// <summary>\r
+    /// A class to represent any object that can exist as an\r
+    /// independent piece of the game.\r
+    /// </summary>\r
+    public interface IEntity\r
+    {\r
+        /// <summary>\r
+        /// Load the resources the entity needs.\r
+        /// </summary>\r
+        /// <param name="contentManager">The foobar.</param>\r
+        void LoadContent(ContentManager contentManager);\r
+\r
+        /// <summary>\r
+        /// Update the entity's state.\r
+        /// </summary>\r
+        /// <param name="timeSpan">The timeslice.</param>\r
+        void Update(TimeSpan timeSpan);\r
+\r
+        /// <summary>\r
+        /// Render the entity on the screen.\r
+        /// </summary>\r
+        /// <param name="spriteBatch">The widget.</param>\r
+        void Draw(SpriteBatch spriteBatch);\r
+\r
+        /// <summary>\r
+        /// Get the actual position.\r
+        /// </summary>\r
+        Vector2 Position { get; }\r
+\r
+        /// <summary>\r
+        /// Get the coordinates on the grid.\r
+        /// </summary>\r
+        Point Coordinates { get; }\r
+    }\r
+}\r
index a65ced5f83dfbfe0701b366f1c39777bebd4bb5c..f90fc151afc8d2f5557c21a15938a3e4089ec13a 100644 (file)
@@ -9,16 +9,10 @@ using Microsoft.Xna.Framework.Input;
 \r
 namespace CarFire\r
 {\r
-    public interface ICharacter\r
+    public interface ICharacter : IEntity\r
     {\r
-        void LoadContent(ContentManager contentManager);\r
-        void UnloadContent();\r
-        long Update(GameTime gameTime, NetworkManager networkGame);\r
-        long Draw(SpriteBatch spriteBatch);\r
         int Health { get; }\r
         void causeDamageTo(int amount);\r
-        Vector2 Position { get; }\r
-        Point Coordinates { get; }\r
     }\r
 \r
     public interface IPlayer : ICharacter\r
index 93dc5ef6ba181c1f678298bf79015a0c62d6c118..8c744bad3e8a96962288d966ea47c991911d099a 100644 (file)
@@ -166,6 +166,16 @@ namespace CarFire
             set { mView.Zoom = value; }\r
         }\r
 \r
+\r
+        /// <summary>\r
+        /// Get and set the associated game object.\r
+        /// </summary>\r
+        public Game Game\r
+        {\r
+            get { return mData.Game; }\r
+            set { mData.Game = value; }\r
+        }\r
+\r
         #endregion\r
 \r
 \r
@@ -278,7 +288,7 @@ namespace CarFire
         /// thrown if there are entities without associated classes.\r
         /// </summary>\r
         /// <returns>List of entity objects loaded.</returns>\r
-        public List<object> GetAllEntities()\r
+        public List<IEntity> GetAllEntities()\r
         {\r
             return mData.GetAllEntities();\r
         }\r
@@ -358,6 +368,8 @@ namespace CarFire
             public Point[] PlayerPositions { get { return mPlayerPositions; } }\r
             public bool[,] Grid { get { return mBooleanGrid; } }\r
 \r
+            public Game Game;\r
+\r
 \r
             public Model(Metadata metadata, char[,] grid, char defaultTile,\r
                 List<RawEntity> entities, Point[] playerPositions)\r
@@ -426,9 +438,9 @@ namespace CarFire
             }\r
 \r
 \r
-            public List<object> GetAllEntities()\r
+            public List<IEntity> GetAllEntities()\r
             {\r
-                List<object> list = new List<object>();\r
+                List<IEntity> list = new List<IEntity>();\r
 \r
                 foreach (RawEntity raw in mEntities)\r
                 {\r
@@ -436,16 +448,20 @@ namespace CarFire
                     {\r
                         string typename = raw.Attributes["type"];\r
 \r
-                        object[] args = new object[3];\r
+                        object[] args = new object[4];\r
                         args[0] = raw.Id;\r
                         args[1] = raw.Position;\r
                         args[2] = raw.Attributes;\r
+                        args[3] = Game;\r
 \r
                         try\r
                         {\r
-\r
-                            object entity = Activator.CreateInstance(System.Type.GetType("CarFire." + typename), args);\r
-                            if (entity != null) list.Add(entity);\r
+                            IEntity entity = (IEntity)Activator.CreateInstance(System.Type.GetType("CarFire." + typename), args);\r
+                            if (entity != null)\r
+                            {\r
+                                entity.LoadContent(Game.ContentManager);\r
+                                list.Add(entity);\r
+                            }\r
                             else throw new RuntimeException();\r
                         }\r
 #pragma warning disable 0168\r
@@ -474,13 +490,18 @@ namespace CarFire
                 {\r
                     if (raw.Attributes.ContainsKey("type") && typename == raw.Attributes["type"])\r
                     {\r
-                        object[] args = new object[3];\r
+                        object[] args = new object[4];\r
                         args[0] = raw.Id;\r
                         args[1] = raw.Position;\r
                         args[2] = raw.Attributes;\r
+                        args[3] = Game;\r
 \r
                         T entity = (T)Activator.CreateInstance(type, args);\r
-                        if (entity != null) list.Add(entity);\r
+                        if (entity != null)\r
+                        {\r
+                            ((IEntity)entity).LoadContent(Game.ContentManager);\r
+                            list.Add(entity);\r
+                        }\r
                         else throw new RuntimeException("Entity of type " + typename + " not loaded because an entity class can't be found.");\r
                     }\r
                 }\r
index e7002035b6509caec0f80f5e5cf980c21190f8d5..3511e4202d1af2e711f2485a81088ee781cfd7f2 100644 (file)
@@ -103,6 +103,24 @@ namespace CarFire
             Update(timeSpan, false, false, false, false);\r
         }\r
 \r
+        /// <summary>\r
+        /// Update the movement manager with the timeslice and a direction.\r
+        /// </summary>\r
+        /// <param name="timeSpan">The timeslice.</param>\r
+        /// <param name="direction">Direction you want to move.</param>\r
+        public void Update(TimeSpan timeSpan, Direction direction)\r
+        {\r
+            if (direction == Direction.Left) Update(timeSpan, true, false, false, false);\r
+            else if (direction == Direction.UpperLeft) Update(timeSpan, true, false, true, false);\r
+            else if (direction == Direction.Up) Update(timeSpan, false, false, true, false);\r
+            else if (direction == Direction.UpperRight) Update(timeSpan, false, true, true, false);\r
+            else if (direction == Direction.Right) Update(timeSpan, false, true, false, false);\r
+            else if (direction == Direction.LowerRight) Update(timeSpan, false, true, false, true);\r
+            else if (direction == Direction.Down) Update(timeSpan, false, false, false, true);\r
+            else if (direction == Direction.LowerLeft) Update(timeSpan, true, false, false, true);\r
+            else Update(timeSpan);\r
+        }\r
+\r
         /// <summary>\r
         /// Update the movement manager with the timeslice and the directions\r
         /// the object is supposed to go.  The directions will be ignored if the\r
@@ -221,6 +239,34 @@ namespace CarFire
             else return Direction.None;\r
         }\r
 \r
+        /// <summary>\r
+        /// Helper method to get the general Direction type if you want to move\r
+        /// from one cell to another.\r
+        /// <param name="a">Starting point.</param>\r
+        /// <param name="b">Destination point.</param>\r
+        /// <returns>The direction toward the cell.</returns>\r
+        public static Direction GetDirection(Point a, Point b)\r
+        {\r
+            int dx = b.X - a.X;\r
+            int dy = b.Y - a.Y;\r
+\r
+            if (dx < 0)\r
+            {\r
+                if (dy < 0) return Direction.UpperLeft;\r
+                else if (dy > 0) return Direction.LowerLeft;\r
+                else return Direction.Left;\r
+            }\r
+            else if (dx > 0)\r
+            {\r
+                if (dy < 0) return Direction.UpperRight;\r
+                else if (dy > 0) return Direction.LowerRight;\r
+                else return Direction.Right;\r
+            }\r
+            else if (dy < 0) return Direction.Up;\r
+            else if (dy > 0) return Direction.Down;\r
+            else return Direction.None;\r
+        }\r
+\r
         #endregion\r
 \r
 \r
index 91724384ab2ac4cccca98b2c830b66c0bff2c1e7..53e148d1f2cc713b29940cd2613df0ac5462bcfb 100644 (file)
@@ -1,4 +1,8 @@
-using System;\r
+\r
+// Uncomment this to disable diagonal movemet.\r
+//#define ALLOW_DIAGONAL_MOVEMENT\r
+\r
+using System;\r
 using System.Collections.Generic;\r
 using System.Linq;\r
 using System.Text;\r
@@ -136,14 +140,16 @@ namespace CarFire
                 }\r
 \r
                 List<Point> neighbors = new List<Point>(8);\r
+                neighbors.Add(new Point(cell.Point.X, cell.Point.Y - 1));\r
+                neighbors.Add(new Point(cell.Point.X - 1, cell.Point.Y));\r
+                neighbors.Add(new Point(cell.Point.X + 1, cell.Point.Y));\r
+                neighbors.Add(new Point(cell.Point.X, cell.Point.Y + 1));\r
+#if ALLOW_DIAGONAL_MOVEMENT\r
                 neighbors.Add(new Point(cell.Point.X - 1, cell.Point.Y - 1));\r
-                neighbors.Add(new Point(cell.Point.X + 0, cell.Point.Y - 1));\r
                 neighbors.Add(new Point(cell.Point.X + 1, cell.Point.Y - 1));\r
-                neighbors.Add(new Point(cell.Point.X - 1, cell.Point.Y + 0));\r
-                neighbors.Add(new Point(cell.Point.X + 1, cell.Point.Y + 0));\r
                 neighbors.Add(new Point(cell.Point.X - 1, cell.Point.Y + 1));\r
-                neighbors.Add(new Point(cell.Point.X + 0, cell.Point.Y + 1));\r
                 neighbors.Add(new Point(cell.Point.X + 1, cell.Point.Y + 1));\r
+#endif\r
                 foreach (Point point in neighbors)\r
                 {\r
                     Cell inQueue = mCells[point.X, point.Y];\r
diff --git a/CarFire/CarFire/CarFire/SaberMonster.cs b/CarFire/CarFire/CarFire/SaberMonster.cs
new file mode 100644 (file)
index 0000000..06fd127
--- /dev/null
@@ -0,0 +1,171 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Content;\r
+using Microsoft.Xna.Framework.Graphics;\r
+\r
+namespace CarFire\r
+{\r
+    public enum AiState\r
+    {\r
+        Standing,\r
+        Pacing,\r
+        Chasing,\r
+        Dazed,\r
+        Fighting,\r
+        Retreating\r
+    }\r
+\r
+\r
+    public class SaberMonster : IMonster\r
+    {\r
+        public SaberMonster(char identifier, Point position, Dictionary<string, string> info, Game game)\r
+        {\r
+            mId = identifier;\r
+            mMotion = new MovementManager(position);\r
+            mGame = game;\r
+\r
+            string speedString;\r
+            if (info.TryGetValue("speed", out speedString))\r
+            {\r
+                int? speed = Parse.Integer(speedString);\r
+                if (speed != null) mMotion.Speed = speed.Value;\r
+            }\r
+\r
+            // Get the "idle path" coordinates loaded from the map.\r
+            string idlePath;\r
+            if (info.TryGetValue("path", out idlePath))\r
+            {\r
+                string[] idlePathPoints = Parse.List(idlePath);\r
+                foreach (string pathPoint in idlePathPoints)\r
+                {\r
+                    Point? point = Parse.Coordinates(pathPoint);\r
+                    if (point != null) mIdlePath.Add(point.Value);\r
+                }\r
+            }\r
+\r
+            StartPacing();\r
+        }\r
+\r
+\r
+        public void StartPacing()\r
+        {\r
+            mState = AiState.Pacing;\r
+\r
+            if (mIdlePath.Count == 0) return;\r
+\r
+            // Determine the best (closest) waypoint to start at.\r
+            mIdlePathIndex = 0;\r
+            int closest = int.MaxValue;\r
+            for (int i = 0; i < mIdlePath.Count; i++)\r
+            {\r
+                int distance = PathFinder.GetManhattanDistance(Coordinates, mIdlePath[i]);\r
+                if (distance < closest)\r
+                {\r
+                    mIdlePathIndex = i;\r
+                    closest = distance;\r
+                }\r
+            }\r
+\r
+            PathFinder pathFinder = new PathFinder(mGame.Grid);\r
+            mPath = new List<Point>(32);\r
+            mPath.Add(Coordinates);\r
+            mPath.AddRange(pathFinder.GetPath(mMotion.Coordinates, mIdlePath[mIdlePathIndex]));\r
+            mPath.Add(mIdlePath[mIdlePathIndex]);\r
+            mPathIndex = 0;\r
+        }\r
+\r
+        Direction GetDirectionToNextCell()\r
+        {\r
+            if (mPathIndex >= mPath.Count)\r
+            {\r
+                mIdlePathIndex++;\r
+                PathFinder pathFinder = new PathFinder(mGame.Grid);\r
+                mPath = new List<Point>(32);\r
+                mPath.Add(Coordinates);\r
+                mPath.AddRange(pathFinder.GetPath(mMotion.Coordinates, mIdlePath[mIdlePathIndex % mIdlePath.Count]));\r
+                mPath.Add(mIdlePath[mIdlePathIndex % mIdlePath.Count]);\r
+                mPathIndex = 0;\r
+            }\r
+\r
+            if (mPath[mPathIndex % mPath.Count] == mMotion.Coordinates)\r
+            {\r
+                mPathIndex++;\r
+                mPathDirection = MovementManager.GetDirection(mMotion.Coordinates, mPath[mPathIndex % mPath.Count]);\r
+            }\r
+\r
+            return mPathDirection;\r
+        }\r
+\r
+\r
+        #region IMonster Members\r
+\r
+        public bool visible\r
+        {\r
+            get { throw new NotImplementedException(); }\r
+        }\r
+\r
+        #endregion\r
+\r
+\r
+        #region ICharacter Members\r
+\r
+        public void LoadContent(ContentManager contentManager)\r
+        {\r
+            mTexture = contentManager.Load<Texture2D>("menuItem");\r
+        }\r
+\r
+        public void Update(TimeSpan timeSpan)\r
+        {\r
+            if (mState == AiState.Pacing)\r
+            {\r
+                mMotion.Update(timeSpan, GetDirectionToNextCell());\r
+            }\r
+        }\r
+\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
+        public int Health\r
+        {\r
+            get { throw new NotImplementedException(); }\r
+        }\r
+\r
+        public void causeDamageTo(int amount)\r
+        {\r
+            throw new NotImplementedException();\r
+        }\r
+\r
+        public Vector2 Position { get { return mMotion.Position; } }\r
+\r
+        public Point Coordinates { get { return mMotion.Coordinates; } }\r
+\r
+        #endregion\r
+\r
+\r
+        #region Private Variables\r
+\r
+        Game mGame;\r
+\r
+        char mId;\r
+        MovementManager mMotion;\r
+\r
+        List<Point> mIdlePath = new List<Point>();\r
+        int mIdlePathIndex;\r
+\r
+        List<Point> mPath;\r
+        int mPathIndex;\r
+        Direction mPathDirection;\r
+\r
+        AiState mState;\r
+\r
+        Texture2D mTexture;\r
+\r
+        #endregion\r
+    }\r
+}\r
This page took 0.061012 seconds and 4 git commands to generate.