#region File Description
//-----------------------------------------------------------------------------
// WaypointSample.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Media;
#endregion
namespace Waypoint
{
///
/// This sample shows how an AI can navigate from point to point using
/// several different behaviors
///
public class WaypointSample : Game
{
#region Constants
///
/// Screen width in pixels
///
const int screenWidth = 640;
///
/// Screen height in pixels
///
const int screenHeight = 480;
///
/// Cursor move speed in pixels per second
///
const float cursorMoveSpeed = 250.0f;
#endregion
#region Fields
// Graphics data
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
// Cursor data
Texture2D cursorTexture;
Vector2 cursorCenter;
Vector2 cursorLocation;
// HUD data
SpriteFont hudFont;
// Where the HUD draws on the screen
Vector2 hudLocation;
// Input data
KeyboardState previousKeyboardState;
GamePadState previousGamePadState;
MouseState previousMouseState;
KeyboardState currentKeyboardState;
GamePadState currentGamePadState;
MouseState currentMouseState;
TouchCollection currentTouchCollection;
// The waypoint-following tank
Tank tank;
#endregion
#region Initialization
///
/// Construct a WaypointSample object
///
public WaypointSample()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = screenWidth;
graphics.PreferredBackBufferHeight = screenHeight;
tank = new Tank(this);
Components.Add(tank);
}
///
/// 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 and
/// non-graphic related content. Calling base.Initialize will enumerate
/// through any components and initialize them as well.
///
protected override void Initialize()
{
// This places the HUD near the upper left corner of the screen
hudLocation = new Vector2(
(float)Math.Floor(screenWidth * .1f),
(float)Math.Floor(screenHeight * .1f));
// places the cursor in the center of the screen
cursorLocation =
new Vector2((float)screenWidth / 2, (float)screenHeight / 2);
// places the tank halfway between the center of the screen and the
// upper left corner
tank.Reset(
new Vector2((float)screenWidth / 4, (float)screenHeight / 4));
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);
cursorTexture = Content.Load("cursor");
cursorCenter =
new Vector2(cursorTexture.Width / 2, cursorTexture.Height / 2);
hudFont = Content.Load("HUDFont");
}
#endregion
#region Update and Draw
///
/// 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)
{
float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
HandleInput(elapsedTime);
base.Update(gameTime);
}
///
/// This is called when the game should draw itself.
///
/// Provides a snapshot of timing values.
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
string HudString = "Behavior : " + tank.BehaviorType.ToString();
spriteBatch.Begin();
// Draw the cursor
spriteBatch.Draw(cursorTexture, cursorLocation, null, Color.White, 0f,
cursorCenter, 1f, SpriteEffects.None, 0f);
// Draw the string for current behavior
spriteBatch.DrawString(hudFont, HudString, hudLocation, Color.White);
spriteBatch.End();
}
#endregion
#region Handle Input
///
/// Read keyboard and gamepad input
///
private void HandleInput(float elapsedTime)
{
previousGamePadState = currentGamePadState;
previousKeyboardState = currentKeyboardState;
previousMouseState = currentMouseState;
currentGamePadState = GamePad.GetState(PlayerIndex.One);
currentKeyboardState = Keyboard.GetState();
currentMouseState = Mouse.GetState();
currentTouchCollection = TouchPanel.GetState();
//bool touched = false;
int touchCount = 0;
// tap the screen to select
foreach (TouchLocation location in currentTouchCollection)
{
switch (location.State)
{
case TouchLocationState.Pressed:
//touched = true;
touchCount++;
cursorLocation = location.Position;
break;
case TouchLocationState.Moved:
break;
case TouchLocationState.Released:
break;
}
}
if ( currentMouseState.LeftButton == ButtonState.Released && previousMouseState.LeftButton == ButtonState.Pressed)
{
cursorLocation.X = currentMouseState.X;
cursorLocation.Y = currentMouseState.Y;
touchCount = 1;
}
if (currentMouseState.MiddleButton == ButtonState.Released && previousMouseState.MiddleButton == ButtonState.Pressed) {
touchCount = 2;
}
if (currentMouseState.RightButton == ButtonState.Released && previousMouseState.RightButton == ButtonState.Pressed) {
touchCount = 3;
}
// Allows the game to exit
if (currentGamePadState.Buttons.Back == ButtonState.Pressed ||
currentKeyboardState.IsKeyDown(Keys.Escape))
this.Exit();
// Update the cursor location by listening for left thumbstick input on
// the GamePad and direction key input on the Keyboard, making sure to
// keep the cursor inside the screen boundary
cursorLocation.X +=
currentGamePadState.ThumbSticks.Left.X * cursorMoveSpeed * elapsedTime;
cursorLocation.Y -=
currentGamePadState.ThumbSticks.Left.Y * cursorMoveSpeed * elapsedTime;
if (currentKeyboardState.IsKeyDown(Keys.Up))
{
cursorLocation.Y -= elapsedTime * cursorMoveSpeed;
}
if (currentKeyboardState.IsKeyDown(Keys.Down))
{
cursorLocation.Y += elapsedTime * cursorMoveSpeed;
}
if (currentKeyboardState.IsKeyDown(Keys.Left))
{
cursorLocation.X -= elapsedTime * cursorMoveSpeed;
}
if (currentKeyboardState.IsKeyDown(Keys.Right))
{
cursorLocation.X += elapsedTime * cursorMoveSpeed;
}
cursorLocation.X = MathHelper.Clamp(cursorLocation.X, 0f, screenWidth);
cursorLocation.Y = MathHelper.Clamp(cursorLocation.Y, 0f, screenHeight);
// Change the tank move behavior if the user pressed B on
// the GamePad or on the Keyboard.
if ((previousGamePadState.Buttons.B == ButtonState.Released &&
currentGamePadState.Buttons.B == ButtonState.Pressed) ||
(previousKeyboardState.IsKeyUp(Keys.B) &&
currentKeyboardState.IsKeyDown(Keys.B)) || ( touchCount == 2 ))
{
tank.CycleBehaviorType();
}
// Add the cursor's location to the WaypointList if the user pressed A on
// the GamePad or on the Keyboard.
if ((previousGamePadState.Buttons.A == ButtonState.Released &&
currentGamePadState.Buttons.A == ButtonState.Pressed) ||
(previousKeyboardState.IsKeyUp(Keys.A) &&
currentKeyboardState.IsKeyDown(Keys.A)) || ( touchCount == 1 ))
{
tank.Waypoints.Enqueue(cursorLocation);
}
// Delete all the current waypoints and reset the tanks’ location if
// the user pressed X on the GamePad or on the Keyboard.
if ((previousGamePadState.Buttons.X == ButtonState.Released &&
currentGamePadState.Buttons.X == ButtonState.Pressed) ||
(previousKeyboardState.IsKeyUp(Keys.X) &&
currentKeyboardState.IsKeyDown(Keys.X)) || ( touchCount == 3 ))
{
tank.Reset(
new Vector2((float)screenWidth / 4, (float)screenHeight / 4));
}
}
#endregion
}
}