#region File Description
//-----------------------------------------------------------------------------
// DemoGame.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
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.Input.Touch;
using Microsoft.Xna.Framework.Media;
#endregion
namespace Graphics3DSample
{
///
/// This is the main type for your game
///
public class Graphics3DSampleGame : Microsoft.Xna.Framework.Game
{
#region Fields
#region Constants
const int buttonHeight = 70;
const int buttonWidth = 70;
const int buttonMargin = 15;
#endregion
GraphicsDeviceManager graphics;
Spaceship spaceship;
Checkbox[] lightEnablingButtons;
Checkbox perpixelLightingButton;
Checkbox animationButton;
Checkbox backgroundTextureEnablingButton;
float cameraFOV = 45; // Initial camera FOV (serves as a zoom level)
float rotationXAmount = 0.0f;
float rotationYAmount = 0.0f;
float? prevLength;
Texture2D background;
Animation animation;
Vector2 animationPosition;
#region Public accessors
///
/// Provides SporiteBatch to components that draw sprites
///
public SpriteBatch SpriteBatch { get; private set; }
#endregion
#endregion
#region Initialization
///
/// Initialization that does not depend on GraphicsDevice
///
public Graphics3DSampleGame()
{
Content.RootDirectory = "Content";
graphics = new GraphicsDeviceManager(this);
graphics.IsFullScreen = true;
graphics.SupportedOrientations =
DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
graphics.ApplyChanges();
}
///
/// Initialization that depends on GraphicsDevice but does not depend on Content
///
protected override void Initialize()
{
GraphicsDevice.DepthStencilState = new DepthStencilState() { DepthBufferEnable = true };
SpriteBatch = new SpriteBatch(GraphicsDevice);
CreateSpaceship();
CreateLightEnablingButtons();
CreateBackgroundTextureEnablingButton();
CreatePerPixelLightingButton();
CreateAnimationButton();
//Initialize gestures support - Pinch for Zoom and horizontal drag for rotate
TouchPanel.EnabledGestures = GestureType.FreeDrag | GestureType.Pinch | GestureType.PinchComplete;
base.Initialize();
}
///
/// Loads content and creates graphics resources.
///
protected override void LoadContent()
{
background = Content.Load("Textures/spaceBG");
animation = CreateAnimation();
spaceship.Load(this.Content);
base.LoadContent();
}
///
/// Creates animation
///
///
private Animation CreateAnimation()
{
// Load multiple animations form XML definition
System.Xml.Linq.XDocument doc = System.Xml.Linq.XDocument.Load("Content/AnimationDef.xml");
System.Xml.Linq.XName name = System.Xml.Linq.XName.Get("Definition");
var definitions = doc.Document.Descendants(name);
// Get the first (and only in this case) animation from the XML definition
var definition = definitions.First();
Texture2D texture = Content.Load(definition.Attribute("SheetName").Value);
Point frameSize = new Point();
frameSize.X = int.Parse(definition.Attribute("FrameWidth").Value);
frameSize.Y = int.Parse(definition.Attribute("FrameHeight").Value);
Point sheetSize = new Point();
sheetSize.X = int.Parse(definition.Attribute("SheetColumns").Value);
sheetSize.Y = int.Parse(definition.Attribute("SheetRows").Value);
TimeSpan frameInterval = TimeSpan.FromSeconds((float)1 / int.Parse(definition.Attribute("Speed").Value));
//Calculate the animation position (in the middle fot he screen)
animationPosition = new Vector2((graphics.PreferredBackBufferWidth / 2 - frameSize.X),
(graphics.PreferredBackBufferHeight / 2 - frameSize.Y));
return new Animation(texture, frameSize, sheetSize, frameInterval);
}
///
/// Creates spaceship
///
private void CreateSpaceship()
{
spaceship = new Spaceship();
spaceship.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(cameraFOV),
GraphicsDevice.Viewport.AspectRatio, 10, 20000);
}
///
/// Creates light enabling buttons
///
private void CreateLightEnablingButtons()
{
lightEnablingButtons = new Checkbox[3];
for (int n = 0; n < lightEnablingButtons.Length; n++)
{
lightEnablingButtons[n] = new Checkbox(this, "Buttons/lamp_60x60",
new Rectangle(GraphicsDevice.Viewport.Width - (n + 1) * (buttonWidth + buttonMargin),
buttonMargin, buttonWidth, buttonHeight), true);
this.Components.Add(lightEnablingButtons[n]);
}
}
///
/// Creates per-pixel lighting button
///
private void CreatePerPixelLightingButton()
{
perpixelLightingButton = new Checkbox(this, "Buttons/perPixelLight_60x60",
new Rectangle(GraphicsDevice.Viewport.Width - (buttonWidth + buttonMargin),
GraphicsDevice.Viewport.Height - (buttonHeight + buttonMargin),
buttonWidth, buttonHeight), false);
this.Components.Add(perpixelLightingButton);
}
///
/// Creates animation button
///
private void CreateAnimationButton()
{
animationButton = new Checkbox(this, "Buttons/animation_60x60",
new Rectangle(buttonMargin,
GraphicsDevice.Viewport.Height - (buttonHeight + buttonMargin),
buttonWidth, buttonHeight), false);
this.Components.Add(animationButton);
}
///
/// Create texture enabling button
///
private void CreateBackgroundTextureEnablingButton()
{
backgroundTextureEnablingButton = new Checkbox(this, "Buttons/textureOnOff",
new Rectangle(buttonMargin, buttonMargin, buttonWidth, buttonHeight), false);
this.Components.Add(backgroundTextureEnablingButton);
}
#endregion
#region Update
///
/// Updates spaceship rendering properties
///
protected override void Update(GameTime gameTime)
{
// Handle touch input first
HandleInput();
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
spaceship.Rotation = GetRotationMatrix();
spaceship.View = GetViewMatrix();
spaceship.Lights = lightEnablingButtons.Select(e => e.IsChecked).ToArray();
spaceship.IsTextureEnabled = true;
spaceship.IsPerPixelLightingEnabled = perpixelLightingButton.IsChecked;
spaceship.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(cameraFOV),
GraphicsDevice.Viewport.AspectRatio, 10, 20000);
if (animationButton.IsChecked)
{
animation.Update(gameTime);
}
base.Update(gameTime);
}
private void HandleInput()
{
while (TouchPanel.IsGestureAvailable)
{
GestureSample gestureSample = TouchPanel.ReadGesture();
switch (gestureSample.GestureType)
{
case GestureType.FreeDrag:
rotationXAmount += gestureSample.Delta.X;
rotationYAmount -= gestureSample.Delta.Y;
break;
case GestureType.Pinch:
float gestureValue = 0;
float minFOV = 60;
float maxFOV = 30;
float gestureLengthToZoomScale = 10;
Vector2 gestureDiff = gestureSample.Position - gestureSample.Position2;
gestureValue = gestureDiff.Length() / gestureLengthToZoomScale;
if (null != prevLength) // Skip the first pinch event
cameraFOV -= gestureValue - prevLength.Value;
cameraFOV = MathHelper.Clamp(cameraFOV, maxFOV, minFOV);
prevLength = gestureValue;
break;
case GestureType.PinchComplete:
prevLength = null;
break;
default:
break;
}
}
}
///
/// Gets spaceship rotation matrix
///
///
private Matrix GetRotationMatrix()
{
Matrix matrix = Matrix.CreateWorld(new Vector3(0, 250, 0), Vector3.Forward, Vector3.Up) *
Matrix.CreateFromYawPitchRoll((float)Math.PI + MathHelper.PiOver2 + rotationXAmount / 100, rotationYAmount / 100, 0);
return matrix;
}
///
/// Gets spaceship view matrix
///
private Matrix GetViewMatrix()
{
return Matrix.CreateLookAt(
new Vector3(3500, 400, 0) + new Vector3(0, 250, 0),
new Vector3(0, 250, 0),
Vector3.Up);
}
#endregion
#region Draw
///
/// Draws the game
///
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
if (backgroundTextureEnablingButton.IsChecked)
{
SpriteBatch.Begin();
SpriteBatch.Draw(background, Vector2.Zero, Color.White);
SpriteBatch.End();
}
var lights = lightEnablingButtons.Select(e => e.IsChecked).ToArray();
// Set render states.
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
// This draws game components, including the currently active menu screen.
// Draw the spaceship model
spaceship.Draw();
if (animationButton.IsChecked)
{
DrawAnimation();
}
base.Draw(gameTime);
}
///
/// Draws animation
///
private void DrawAnimation()
{
float screenHeight = graphics.PreferredBackBufferHeight;
float scale = (float)(graphics.PreferredBackBufferWidth / 480.0);
SpriteBatch.Begin();
animation.Draw(SpriteBatch, animationPosition, 2.0f, SpriteEffects.None);
SpriteBatch.End();
}
#endregion
}
}