X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=CarFire%2FCarFire%2FCarFire%2FGame.cs;h=8b9b0759e9bacb46f6756aef25afe6e3075d41c9;hb=f41d1413bdee1a69450ca6c2bca9932a4c61a6d9;hp=1271138bf47bd287a9512acebfa8a17fb56f2718;hpb=fd4232e02811ea2a8a69f10ffaed584062c914cd;p=chaz%2Fcarfire
diff --git a/CarFire/CarFire/CarFire/Game.cs b/CarFire/CarFire/CarFire/Game.cs
index 1271138..8b9b075 100644
--- a/CarFire/CarFire/CarFire/Game.cs
+++ b/CarFire/CarFire/CarFire/Game.cs
@@ -9,27 +9,301 @@ using Microsoft.Xna.Framework.Input;
namespace CarFire
{
+ ///
+ /// Container class for the whole state of the game.
+ ///
+ public class GameState
+ {
+ #region Public Properties
+ private const int hitMonsterScore = 20;
+ private const int killMonsterScore = 100;
+ public int HitMonsterScore { get { return hitMonsterScore; } }
+ public int KillMonsterScore { get { return killMonsterScore; } }
+
+ public long FrameNumber { get { return mFrameNumber; } }
+
+ public long Checksum { get { return mChecksum; } }
+
+ public int NumberOfPlayers { get { return mNumberOfPlayers; } }
+
+ public Map Map;
+ public List Entities = new List();
+ public List mProjectiles = new List();
+ public Player[] mCharacters;
+ public Display mDisplay;
+ public AI AIData;
+ #endregion
+
+
+ #region Public Methods
+
+ ///
+ /// Construct a game state container with the number of players.
+ ///
+ /// Number of players.
+ public GameState(int numPlayers)
+ {
+ mNumberOfPlayers = numPlayers;
+ mFrameNumber = 0;
+
+ mCharacters = new Player[numPlayers];
+
+ mIsGameOver = new bool[numPlayers];
+ mIsTerminated = new bool[numPlayers];
+
+ mMouseLocation = new Point[numPlayers];
+ mMouseButton = new bool[numPlayers];
+ mKeysDown = new List[numPlayers];
+ for (int i = 0; i < numPlayers; i++) mKeysDown[i] = new List();
+
+ mKeypressCount = new int[numPlayers];
+ mElapsedTime = 0;
+ mChecksum = 0;
+ }
+
+
+ ///
+ /// Should be called by the Game class to advance the state
+ /// to the next frame.
+ ///
+ /// The inputs that occurred to be
+ /// applied this coming frame.
+ /// Milliseconds; used for the checksum.
+ public void AdvanceFrame(NextInputs inputs, long milliseconds)
+ {
+ mFrameNumber++;
+ mElapsedTime += milliseconds;
+
+ for (int player = 0; player < NumberOfPlayers; player++)
+ {
+ if (inputs.IsMousePressedChanged[player])
+ {
+ mMouseButton[player] = inputs.MousePressed[player];
+ }
+
+ if (inputs.IsMouseLocationChanged[player])
+ {
+ mMouseLocation[player] = inputs.MouseLocation[player];
+ }
+
+ foreach (Keys k in inputs.KeysPressed[player])
+ {
+ if (!mKeysDown[player].Contains(k))
+ {
+ mKeysDown[player].Add(k);
+ mKeypressCount[player]++;
+ }
+ }
+
+ foreach (Keys k in inputs.KeysReleased[player]) mKeysDown[player].Remove(k);
+ }
+
+ ComputeChecksum();
+ }
+
+
+ ///
+ /// Get the mouse location for a player.
+ ///
+ /// Player Number.
+ /// Mouse location.
+ public Point GetMouseLocation(int playerNum)
+ {
+ return mMouseLocation[playerNum];
+ }
+
+ ///
+ /// Get the mouse button state for a player.
+ ///
+ /// Player number.
+ /// Mouse button state..
+ public bool GetMouseButton(int playerNum)
+ {
+ return mMouseButton[playerNum];
+ }
+
+ ///
+ /// Get the keyboard state for a player.
+ ///
+ /// Player number.
+ /// Keyboard state.
+ public List GetKeysDown(int playerNum)
+ {
+ return mKeysDown[playerNum];
+ }
+
+ #endregion
+
+
+ #region Private Methods
+
+ // Calculates a checksum for debugging network synchronization issues.
+ long ComputeChecksum()
+ {
+ mChecksum += FrameNumber;
+ for (int i = 0; i < NumberOfPlayers; i++)
+ {
+ mChecksum = mChecksum + mKeypressCount[i];
+ mChecksum = mChecksum * 3 + (mIsGameOver[i] ? 1 : 2);
+ mChecksum = mChecksum * 3 + (mIsTerminated[i] ? 1 : 2);
+ foreach (Keys k in mKeysDown[i])
+ mChecksum = mChecksum * 257 + (int)k;
+ mChecksum = mChecksum * 25789 + mMouseLocation[i].X * 259 + mMouseLocation[i].Y + 375;
+ mChecksum = mChecksum * 3 + (mMouseButton[i] ? 1 : 2);
+
+ }
+ mChecksum += mElapsedTime;
+
+ return mChecksum;
+ }
+
+ #endregion
+
+
+ #region Private Variables
+
+ int mNumberOfPlayers;
+ public Point[] mMouseLocation;
+ public bool[] mMouseButton;
+ public List[] mKeysDown;
+
+ long mFrameNumber;
+
+ bool[] mIsGameOver;
+ bool[] mIsTerminated;
+
+ int[] mKeypressCount;
+ long mElapsedTime;
+ long mChecksum;
+
+ #endregion
+ }
+
+ ///
+ /// Container class for all the inputs for a single frame.
+ ///
+ public class NextInputs
+ {
+ public List[] KeysPressed;
+ public List[] KeysReleased;
+ public Point[] MouseLocation;
+ public bool[] IsMouseLocationChanged;
+ public bool[] MousePressed;
+ public bool[] IsMousePressedChanged;
+
+ public NextInputs(int numPlayers)
+ {
+ KeysPressed = new List[numPlayers];
+ KeysReleased = new List[numPlayers];
+ IsMouseLocationChanged = new bool[numPlayers];
+ MousePressed = new bool[numPlayers];
+ IsMousePressedChanged = new bool[numPlayers];
+ for (int i = 0; i < numPlayers; i++) KeysPressed[i] = new List();
+ for (int i = 0; i < numPlayers; i++) KeysReleased[i] = new List();
+ }
+ }
+
+
+ ///
+ /// The big kahuna.
+ ///
public class Game : IDeterministicGame
{
- #region IDeterministicGame Members
- List mPlayers;
- Display mDisplay;
- Map mMap;
+ #region Public Properties
+
+ ///
+ /// Get the content manager associated with this game.
+ ///
+ public ContentManager ContentManager { get { return mContentManager; } }
+
+ ///
+ /// Get the state.
+ ///
+ public GameState State;
+
+ public bool[,] Grid
+ {
+ get
+ {
+ bool[,] grid = State.Map.Grid;
+ foreach (IEntity entity in State.Entities)
+ {
+ Point coordinates = entity.Coordinates;
+ if (State.Map.IsCellOpen(coordinates)) grid[coordinates.X, coordinates.Y] = false;
+ }
+ return grid;
+ }
+ }
+
+ #endregion
+
+
+ #region Public Methods
+
+ public IEntity GetEntityAtCoordinates(Point point)
+ {
+ foreach (IEntity entity in State.Entities)
+ {
+ if (entity.Coordinates == point) return entity;
+ }
+ return null;
+ }
+
+ public Player GetPlayerAtCoordinates(Point point)
+ {
+ foreach (Player player in State.mCharacters)
+ {
+ if (player != null && player.Coordinates == point) return player;
+ }
+ return null;
+ }
+
+ public bool IsCellOpen(Point point)
+ {
+ if (!State.Map.IsCellOpen(point)) return false;
+ if (GetEntityAtCoordinates(point) != null) return false;
+ return true;
+ }
public Game()
{
- mDisplay = new Display();
+
+ }
+ ///
+ /// This method should be called whenever the players want to move to a new map.
+ /// Not implemented yet. Need some way to get next map.
+ ///
+ public void startNewMap()
+ {
+ //TODO somehow get next map
+ State.Entities.Clear();
+ //State.Map = State.Map.getNextMap();
+ for (int i = 0; i < State.mCharacters.Length; i++)
+ {
+ State.mCharacters[i].Coordinates = State.Map.GetStartingPositionForPlayer(i + 1);
+ }
+ State.Entities = State.Map.GetAllEntities(this);
}
public void LoadContent(ContentManager contentManager)
{
- //Texture2D everything = contentManager.Load("default");
- mDisplay.LoadContent(contentManager);
+ mContentManager = contentManager;
+ menu = mContentManager.Load("menuFont");
+
}
public void UnloadContent()
{
}
+ private int GetPlayerNumber(Object playerIdentifier)
+ {
+ for (int i = 0; i < mPlayerIdentifiers.Length; i++)
+ {
+ if (mPlayerIdentifiers[i] == playerIdentifier) return i;
+ }
+ throw new Exception("Illegal player identifier" + playerIdentifier);
+ }
+
public Vector2 PreferredScreenSize
{
get { return new Vector2(800, 600); }
@@ -47,11 +321,82 @@ namespace CarFire
public void ResetGame(object[] playerIdentifiers, object thisPlayer)
{
+ int numPlayers = playerIdentifiers.Count();
+
+ mPlayerIdentifiers = new object[numPlayers];
+ for (int i = 0; i < numPlayers; i++) mPlayerIdentifiers[i] = playerIdentifiers[i];
+
+ mThisPlayerID = GetPlayerNumber(thisPlayer);
+
+ State = new GameState(numPlayers);
+ mInputs = new NextInputs(numPlayers);
+ State.mDisplay = new Display(this);
+ State.mDisplay.LoadContent(mContentManager);
+
+ Texture2D mapTiles = mContentManager.Load("graphics/wallAndFloorTilesNoEdgeScale");
+ Tilemap tilemap = new Tilemap(mapTiles, 10, 7);
+ tilemap.SetTile(' ', new Point(4, 5));
+ tilemap.SetTile('`', new Point(0, 1));
+ tilemap.SetTile('~', new Point(1, 1));
+ tilemap.SetTile('!', new Point(3, 1));
+ tilemap.SetTile('@', new Point(4, 1));
+ tilemap.SetTile('#', new Point(5, 1));
+ tilemap.SetTile('$', new Point(6, 1));
+ tilemap.SetTile('%', new Point(8, 1));
+ tilemap.SetTile('^', new Point(9, 1));
+ tilemap.SetTile('&', new Point(0, 2));
+ tilemap.SetTile('=', new Point(1, 2));
+ tilemap.SetTile('*', new Point(2, 2));
+ tilemap.SetTile('(', new Point(4, 2));
+ tilemap.SetTile(')', new Point(0, 3));
+ tilemap.SetTile('_', new Point(2, 3));
+ tilemap.SetTile('-', new Point(9, 3));
+ tilemap.SetTile(',', new Point(1, 4));
+ tilemap.SetTile('+', new Point(2, 4));
+ tilemap.SetTile('[', new Point(3, 4));
+ tilemap.SetTile(']', new Point(4, 4));
+ tilemap.SetTile('{', new Point(5, 4));
+ tilemap.SetTile('}', new Point(6, 4));
+ tilemap.SetTile('\\', new Point(8, 4));
+ tilemap.SetTile('|', new Point(9, 4));
+ tilemap.SetTile(';', new Point(0, 5));
+ tilemap.SetTile(':', new Point(1, 5));
+ tilemap.SetTile('\'', new Point(2, 5));
+ tilemap.SetTile('"', new Point(3, 5));
+ tilemap.SetTile('.', new Point(5, 5));
+ tilemap.SetTile('<', new Point(6, 5));
+ tilemap.SetTile('>', new Point(7, 5));
+ tilemap.SetTile('/', new Point(8, 5));
+ tilemap.SetTile('?', new Point(9, 5));
+
+ State.Map = mContentManager.Load