//-----------------------------------------------------------------------------
// ShatterEffectGame.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace ShatterEffect
{
///
/// This is the main type for your game
///
public class ShatterEffectGame : Game
{
GraphicsDeviceManager graphics;
Vector3 lightPosition = Vector3.UnitY;
Vector4 ambientColor = Color.DarkGray.ToVector4();
Vector4 diffuseColor = Color.White.ToVector4();
Vector4 specularColor = Color.White.ToVector4();
float specularPower = 50;
float time;
const float translationRate = 50;
const float rotationRate = MathHelper.Pi * 3;
const float duration = 2.0f;
Model model;
SpriteFont font;
SpriteBatch spriteBatch;
Matrix view;
Matrix projection;
Vector3 cameraPosition = new Vector3(-696, 429, 835);
Vector3 targetPosition = new Vector3(0, 60, 0);
int shatterEffectIndex = 0; // 0 for default shatter, 1 for explosion
bool autoShatter = false;
bool autoShatterReversing = false;
float autoShatterSpeed = 0.5f; // Slow-motion multiplier for auto-shatter
float autoShatterPauseDuration = 1.0f; // Pause duration in seconds before changing direction
float autoShatterPauseTimer = 0.0f; // Timer to track pause duration
KeyboardState previousKeyboardState;
public ShatterEffectGame()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
///
/// Load your graphics content.
///
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(this.graphics.GraphicsDevice);
font = Content.Load("font");
model = Content.Load("model/ship1");
// Calculate View/Projection Matrices.
view = Matrix.CreateLookAt(cameraPosition, targetPosition, Vector3.Up);
projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f), GraphicsDevice.Viewport.AspectRatio, 1.0f, 10000.0f);
}
///
/// 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)
{
// Handle input
float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
KeyboardState keyboardState = Keyboard.GetState();
GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
// Toggle between shatter effects with Tab (on key release)
if (keyboardState.IsKeyUp(Keys.Tab) && previousKeyboardState.IsKeyDown(Keys.Tab))
{
shatterEffectIndex = (shatterEffectIndex + 1) % 2; // Toggle between 0 and 1
}
// Toggle auto-shatter with Enter (on key release)
if (keyboardState.IsKeyUp(Keys.Enter) && previousKeyboardState.IsKeyDown(Keys.Enter))
{
autoShatter = !autoShatter;
autoShatterReversing = false; // Reset reversing state
}
if (autoShatter)
{
float adjustedElapsedTime = elapsedTime * autoShatterSpeed; // Apply slow-motion multiplier
if (autoShatterPauseTimer > 0.0f)
{
autoShatterPauseTimer -= elapsedTime; // Decrease pause timer
}
else if (!autoShatterReversing)
{
time += adjustedElapsedTime;
if (time >= duration)
{
time = duration;
autoShatterReversing = true;
autoShatterPauseTimer = autoShatterPauseDuration; // Start pause timer
}
}
else
{
time -= adjustedElapsedTime;
if (time <= 0.0f)
{
time = 0.0f;
autoShatterReversing = false;
autoShatterPauseTimer = autoShatterPauseDuration; // Start pause timer
}
}
}
else
{
// Manual control for shatter effects
if (keyboardState.IsKeyDown(Keys.Up) || gamePadState.Buttons.A == ButtonState.Pressed)
{
time = Math.Min(duration, time + elapsedTime);
}
if (keyboardState.IsKeyDown(Keys.Down) || gamePadState.Buttons.B == ButtonState.Pressed)
{
time = Math.Max(0.0f, time - elapsedTime);
}
}
previousKeyboardState = keyboardState; // Update previous keyboard state
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.MonoGameOrange);
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.RasterizerState = RasterizerState.CullNone;
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (ModelMeshPart part in mesh.MeshParts)
{
SetupEffect(transforms, mesh, part);
}
mesh.Draw();
}
// Draw the UI
spriteBatch.Begin();
spriteBatch.DrawString(font, "Shatter Effect Demo", new Vector2(10, 10), Color.White);
spriteBatch.DrawString(font, "Press Tab to toggle shatter effects", new Vector2(10, 30), Color.White);
spriteBatch.DrawString(font, "Press Enter to toggle auto-shatter", new Vector2(10, 50), Color.White);
spriteBatch.DrawString(font, "Use Up/Down arrows or GamePad A/B to control shatter amount", new Vector2(10, 70), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
void SetupEffect(Matrix[] transforms, ModelMesh mesh, ModelMeshPart part)
{
Effect effect = part.Effect;
if (shatterEffectIndex == 0) // Default shatter effect
{
effect.Parameters["TranslationAmount"].SetValue(translationRate * time);
effect.Parameters["RotationAmount"].SetValue(rotationRate * time);
}
else if (shatterEffectIndex == 1) // Explosion effect
{
effect.Parameters["TranslationAmount"].SetValue(translationRate * time * 2); // Expand outward
effect.Parameters["RotationAmount"].SetValue(0); // No rotation for explosion
}
effect.Parameters["time"].SetValue(time);
effect.Parameters["WorldViewProjection"].SetValue(
transforms[mesh.ParentBone.Index] * view * projection);
effect.Parameters["World"].SetValue(transforms[mesh.ParentBone.Index]);
effect.Parameters["eyePosition"].SetValue(cameraPosition);
effect.Parameters["lightPosition"].SetValue(lightPosition);
effect.Parameters["ambientColor"].SetValue(ambientColor);
effect.Parameters["diffuseColor"].SetValue(diffuseColor);
effect.Parameters["specularColor"].SetValue(specularColor);
effect.Parameters["specularPower"].SetValue(specularPower);
}
}
}