using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using CS_3505_Project_06.CS_3505;
namespace CS_3505_Project_06
{
///
/// A game outline for testing network communications
///
public class Game06 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont font;
IDeterministicGame deterministicGame;
TimeSpan targetTimeSpan;
Object[] playerIdentifiers = { "One", "Two", "Three", "Four" }; // Any objects will do, strings are easy to debug.
// For debugging
List lastPressedKeys;
bool lastButtonPressed;
Object activePlayer;
bool paused;
long lastAutoPause;
// Constructor
public Game06()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
// Make the game object. The game is currently called 'testHarness'.
deterministicGame = new TestHarness();
// Debugging setup
lastPressedKeys = new List();
activePlayer = playerIdentifiers[0];
paused = false;
}
///
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
///
protected override void Initialize()
{
// Set a fixed time span of 1/60th of a second.
targetTimeSpan = new TimeSpan(166666); // In 100 nanosecond units = 16 666 600 nanoseconds
IsFixedTimeStep = true;
TargetElapsedTime = targetTimeSpan;
// Reset the game - indicate that player #1 (player 0) owns this instance of the game.
deterministicGame.ResetGame(playerIdentifiers, playerIdentifiers[0]);
// For debugging - reset the mouse position to the center of the window.
Mouse.SetPosition(400, 300);
// Allow the base class to initialize.
base.Initialize();
}
///
/// LoadContent will be called once per game and is the place to load
/// all of your content.
///
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// Let the game load its content.
font = Content.Load("InstructionFont");
deterministicGame.LoadContent(Content);
}
///
/// UnloadContent will be called once per game and is the place to unload
/// all content.
///
protected override void UnloadContent()
{
deterministicGame.UnloadContent();
}
///
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
///
/// Provides a snapshot of timing values.
protected override void Update(GameTime gameTime)
{
// Get user's input state.
KeyboardState keyState = Keyboard.GetState();
MouseState mouseState = Mouse.GetState();
// Make a list of the keys pressed or released this frame.
List pressedKeys = new List();
List releasedKeys = new List();
Keys[] pressedKeysArray = keyState.GetPressedKeys();
foreach (Keys k in pressedKeysArray)
if (!lastPressedKeys.Contains(k))
pressedKeys.Add(k);
else
lastPressedKeys.Remove(k);
releasedKeys = lastPressedKeys;
lastPressedKeys = new List(pressedKeysArray);
// Get mouse button state.
bool buttonPressed = mouseState.LeftButton == ButtonState.Pressed;
/***** Begining of game logic. *****/
// Debug - allow user to exit.
if (pressedKeys.Contains(Keys.Escape))
this.Exit();
// Debug - allow user on this machine to direct input to any player's state in the game.
if (pressedKeys.Contains(Keys.F1)) activePlayer = playerIdentifiers[0];
if (pressedKeys.Contains(Keys.F2)) activePlayer = playerIdentifiers[1];
if (pressedKeys.Contains(Keys.F3)) activePlayer = playerIdentifiers[2];
if (pressedKeys.Contains(Keys.F4)) activePlayer = playerIdentifiers[3];
// Debug - allow user on this machine to pause/resume game state advances.
if (pressedKeys.Contains(Keys.F12) ||
pressedKeys.Contains(Keys.P) && (keyState.IsKeyDown(Keys.LeftControl) || keyState.IsKeyDown(Keys.RightControl)))
{
paused = !paused;
return; // Don't update on pause start or stop
}
// Debug - automatically pause every 1000 frames.
if (deterministicGame.CurrentFrameNumber % 1000 == 0 && deterministicGame.CurrentFrameNumber != lastAutoPause)
{
paused = true;
lastAutoPause = deterministicGame.CurrentFrameNumber;
}
// Game update
// Direct inputs to the game engine - only report changes.
foreach (Keys k in pressedKeys)
deterministicGame.ApplyKeyInput(activePlayer, k, true);
foreach (Keys k in releasedKeys)
deterministicGame.ApplyKeyInput(activePlayer, k, false);
deterministicGame.ApplyMouseLocationInput(activePlayer, mouseState.X, mouseState.Y);
if (lastButtonPressed != buttonPressed)
deterministicGame.ApplyMouseButtonInput(activePlayer, buttonPressed);
lastButtonPressed = buttonPressed;
if (!paused)
{
// Advance the game engine.
deterministicGame.Update(targetTimeSpan);
}
/***** End of game logic. *****/
// Allow the superclass to do any needed updates (unknown purpose).
base.Update(gameTime);
}
///
/// This is called when the game should draw itself.
///
/// Provides a snapshot of timing values.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(new Color(16, 16, 16, 255)); // Needed by the test harness, should be removed for the real game.
spriteBatch.Begin();
// Draw a few instructions.
if (paused && gameTime.TotalRealTime.Milliseconds < 500)
spriteBatch.DrawString(font, "-=> Paused <=-", new Vector2(10, 130), Color.White);
spriteBatch.DrawString(font, "Press [F1]...[F4] to simulate input for each player. Click X's to end game or terminate player.", new Vector2(10, 540), Color.White);
spriteBatch.DrawString(font, "Press [ESC] to exit and [F12] to pause/unpause. Game auto-pauses every 1000 frames.", new Vector2(10, 570), Color.White);
// Let the game draw itself.
deterministicGame.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}