From f5b00f187579c137436bb023c5f4c71dbeb02847 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 19 Apr 2010 02:11:57 +0000 Subject: [PATCH] Incorporated networking into the game git-svn-id: https://bd85.net/svn/cs3505_group@99 92bb83a3-7c8f-8a45-bc97-515c4e399668 --- CarFire/CarFire/CarFire/Game.cs | 186 +++++++++++++++++++++++++++++--- 1 file changed, 174 insertions(+), 12 deletions(-) diff --git a/CarFire/CarFire/CarFire/Game.cs b/CarFire/CarFire/CarFire/Game.cs index 7374522..b1b7238 100644 --- a/CarFire/CarFire/CarFire/Game.cs +++ b/CarFire/CarFire/CarFire/Game.cs @@ -9,6 +9,135 @@ using Microsoft.Xna.Framework.Input; namespace CarFire { + // Everything in objects built from this class represent the critical game state + public class GameState + { + public long frameNumber; + + private long checksum; + public long Checksum { get { return checksum; } } + + public bool[] isGameOver; + public bool[] isTerminated; + + // Since this is not a game, I'll just keep track of the user inputs as the game state. + + public int[] mouseLocationX; + public int[] mouseLocationY; + public bool[] mouseButton; + public List[] keysDown; + public int[] keypressCount; + + public long elapsedTime; + + /* Constructor */ + public GameState() + { + frameNumber = 0; + checksum = 0; + + isGameOver = new bool[4]; + isTerminated = new bool[4]; + + mouseLocationX = new int[4]; + mouseLocationY = new int[4]; + mouseButton = new bool[4]; + keysDown = new List[4]; + for (int i = 0; i < 4; i++) + keysDown[i] = new List(); + keypressCount = new int[4]; + + elapsedTime = 0; + + checksum = 0; + } + + /* The game engine! */ + public void advanceFrame(NextInputs inputs, long milliseconds) + { + // Advance frame number + frameNumber++; + + // Advance game - for the test harness, just record statistics and input states. + + elapsedTime += milliseconds; + + for (int player = 0; player < 4; player++) + { + + //if (isGameOver[player]) + // continue; + + if (inputs.mousePressedChanged[player]) + mouseButton[player] = inputs.mousePressed[player]; + + if (inputs.mouseLocationChanged[player]) + { + mouseLocationX[player] = inputs.mouseLocationX[player]; + mouseLocationY[player] = inputs.mouseLocationY[player]; + } + + foreach (Keys k in inputs.keysPressed[player]) + if (!keysDown[player].Contains(k)) + { + keysDown[player].Add(k); + keypressCount[player]++; + } + + foreach (Keys k in inputs.keysReleased[player]) + keysDown[player].Remove(k); + + // If the mouse was pressed for a certain player, activate game over or terminated states as appropriate + + if (inputs.mousePressed[player]) + for (int p = 0; p < 4; p++) + { + int x = 200 * p + 10; + int y = 220; + + if (mouseLocationX[player] >= x && mouseLocationY[player] >= y && + mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25) + { + isGameOver[p] = true; + } + y += 25; + if (mouseLocationX[player] >= x && mouseLocationY[player] >= y && + mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25) + { + isGameOver[p] = true; + isTerminated[p] = true; + } + } + + + } + + // Advance the checksum. + + computeChecksum(); + + } + + /* Just hash the values */ + private long computeChecksum() + { + checksum += frameNumber; + for (int i = 0; i < 4; i++) + { + checksum = checksum + keypressCount[i]; + checksum = checksum * 3 + (isGameOver[i] ? 1 : 2); + checksum = checksum * 3 + (isTerminated[i] ? 1 : 2); + foreach (Keys k in keysDown[i]) + checksum = checksum * 257 + (int)k; + checksum = checksum * 25789 + mouseLocationX[i] * 259 + mouseLocationY[i] + 375; + checksum = checksum * 3 + (mouseButton[i] ? 1 : 2); + + } + checksum += elapsedTime; + + return checksum; + } + } //code from Prof Jensen's TestHarness // This class encapsulates inputs from the players. public class NextInputs @@ -35,6 +164,7 @@ namespace CarFire for (int i = 0; i < 4; i++) keysReleased[i] = new List(); } + } public class Game : IDeterministicGame @@ -46,10 +176,14 @@ namespace CarFire Display mDisplay; Map mMap; + GameState state; + int thisPlayerID; + public Game() { mDisplay = new Display(); mPlayers = new List(); + playerIdentifiers = new Object[4]; } public void LoadContent(ContentManager contentManager) { @@ -60,11 +194,7 @@ namespace CarFire mMap = contentManager.Load("Maps/stable"); Map.DefaultTile = contentManager.Load("default"); mMap.CenterCell = new Vector2(currentCenterX, currentCenterY); - - Human player = new Human(mMap, ""); - player.LoadContent(contentManager); - mPlayers.Add(player); - mDisplay.AddCharacters(player); + } public void UnloadContent() @@ -94,17 +224,44 @@ namespace CarFire get { return 4; } } - public void ResetGame(object[] playerIdentifiers, object thisPlayer) + public void ResetGame(object[] PlayerIdentifiers, object thisPlayer) { - foreach (IPlayer player in mPlayers) + // Now the test harness will at least run with less than 4 players... + int numPlayers = PlayerIdentifiers.Count(); + for (int i = 0; i < numPlayers; i++) + this.playerIdentifiers[i] = PlayerIdentifiers[i]; + + // Create new game state and inputs objects. + + state = new GameState(); + inputs = new NextInputs(); + + // Record 'this' player. + + this.thisPlayerID = idPlayer(thisPlayer); + /* + mPlayers.Clear(); + for (int i = 0; i < PlayerIdentifiers.Length; i++) { - player.Spawn(mMap.CenterCell); + Human player = new Human(mMap, ""); + mPlayers.Add(player); + mDisplay.AddCharacters(player); + mPlayers.Add(player); + mDisplay.AddCharacters(player); } + this.playerIdentifiers = PlayerIdentifiers; + for (int i = 0; i < mPlayers.Count; i++) + { + Point starting = mMap.GetStartingPositionForPlayer(i + 1); + mPlayers[i].Spawn(new Vector2(starting.X, starting.Y)); + } + */ + } public long CurrentFrameNumber { - get { return 0; } + get { return state.frameNumber; } } public long CurrentChecksum @@ -122,6 +279,7 @@ namespace CarFire if (!isKeyPressed && !inputs.keysReleased[player].Contains(key)) inputs.keysReleased[player].Add(key); + } public void ApplyMouseLocationInput(object playerIdentifier, int x, int y) @@ -144,10 +302,14 @@ namespace CarFire return false; } - public long Update(TimeSpan timespan) + public long Update(TimeSpan elapsedTime) { - mDisplay.Update(timespan); - return CurrentFrameNumber; + state.advanceFrame(inputs, elapsedTime.Milliseconds); // Apply the inputs, advance game state. + mDisplay.Update(elapsedTime, state); + inputs = new NextInputs(); // Start with inputs cleared on the next frame. + //mDisplay.Update(elapsedTime); + return state.frameNumber; + } public long Draw(SpriteBatch spriteBatch) -- 2.44.0