X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=CarFire%2FCarFire%2FCarFire%2FGame.cs;h=b1b723866dd838003522da855f9121f688c20eb0;hb=f5b00f187579c137436bb023c5f4c71dbeb02847;hp=38d86b8eb111e1f100f4f03934a6031575290f96;hpb=c5daf1d9adca0c3a826dfa2ac7b6d4f8a64c84a3;p=chaz%2Fcarfire diff --git a/CarFire/CarFire/CarFire/Game.cs b/CarFire/CarFire/CarFire/Game.cs index 38d86b8..b1b7238 100644 --- a/CarFire/CarFire/CarFire/Game.cs +++ b/CarFire/CarFire/CarFire/Game.cs @@ -9,18 +9,206 @@ 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 + { + public List[] keysPressed; + public List[] keysReleased; + public int[] mouseLocationX; + public int[] mouseLocationY; + public bool[] mouseLocationChanged; + public bool[] mousePressed; + public bool[] mousePressedChanged; + + public NextInputs() + { + keysPressed = new List[4]; + keysReleased = new List[4]; + mouseLocationX = new int[4]; + mouseLocationY = new int[4]; + mouseLocationChanged = new bool[4]; + mousePressed = new bool[4]; + mousePressedChanged = new bool[4]; + for (int i = 0; i < 4; i++) + keysPressed[i] = new List(); + for (int i = 0; i < 4; i++) + keysReleased[i] = new List(); + } + + } + public class Game : IDeterministicGame { #region IDeterministicGame Members + List mPlayers; + NextInputs inputs; + Object[] playerIdentifiers; + 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) { + //Texture2D everything = contentManager.Load("default"); + mDisplay.LoadContent(contentManager); + int currentCenterX = 5; //Creates a map like the one in Display + int currentCenterY = 5; + mMap = contentManager.Load("Maps/stable"); + Map.DefaultTile = contentManager.Load("default"); + mMap.CenterCell = new Vector2(currentCenterX, currentCenterY); + } public void UnloadContent() { } + private int idPlayer(Object playerIdentifier) + { + for (int i = 0; i < playerIdentifiers.Length; i++) + if (playerIdentifiers[i] == playerIdentifier) + return i; + throw new Exception("Illegal player identifier" + playerIdentifier); + } + public Vector2 PreferredScreenSize { get { return new Vector2(800, 600); } @@ -36,13 +224,44 @@ namespace CarFire get { return 4; } } - public void ResetGame(object[] playerIdentifiers, object thisPlayer) + public void ResetGame(object[] PlayerIdentifiers, object thisPlayer) { + // 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++) + { + 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 @@ -52,33 +271,50 @@ namespace CarFire public void ApplyKeyInput(object playerIdentifier, Keys key, bool isKeyPressed) { + //code from Prof Jensen's TestHarness + int player = idPlayer(playerIdentifier); + + if (isKeyPressed && !inputs.keysPressed[player].Contains(key)) + inputs.keysPressed[player].Add(key); + + if (!isKeyPressed && !inputs.keysReleased[player].Contains(key)) + inputs.keysReleased[player].Add(key); + } public void ApplyMouseLocationInput(object playerIdentifier, int x, int y) { + } public void ApplyMouseButtonInput(object playerIdentifier, bool isButtonPressed) { + } public bool IsGameOver(object playerIdentifier) { - return true; + return false; } public bool IsTerminated(object playerIdentifier) { - return true; + return false; } - public long Update(TimeSpan timespan) + public long Update(TimeSpan elapsedTime) { - 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) { + mDisplay.Draw(spriteBatch); return CurrentFrameNumber; }