#region Using Statements using System; using System.Collections; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; #endregion // Tutorials in plain English by Dillinger - http://musicalglass.spaces.live.com
/// <summary> This is the main squeeze for your game </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
static GraphicsDeviceManager graphics;
static public ContentManager content;
static SpriteBatch spriteBatch; static ArrayList SpriteManager = new ArrayList(); static public Viewport viewport; static Vector2 mousePosition; static public int spritesAcross = 3; public Game1()
{
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
} /// <summary> Allows the game to perform any pre-game initialization. </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
} /// <summary> Load your graphics content. </summary>
/// <param name="loadAllContent"> Specify which type of content to load.</param>
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
IsMouseVisible = true; // Show the mouse cursor ( default is false ) spriteBatch = new SpriteBatch(graphics.GraphicsDevice); viewport = graphics.GraphicsDevice.Viewport; // we use a For Loop to cycle through the SpriteManager ArrayList and Add the specified number of Sprites
for (int counter = 0; counter < spritesAcross; counter++)
SpriteManager.Add(new SpriteSheet(@"FolderName\SpriteSheetTexture", 0, 3, 3, 1, 1)); // Use a For Loop to make changes to each Sprite in the Array.
for (int counter = 0; counter < spritesAcross; counter++)
{
SpriteSheet tempSprite = new SpriteSheet(@"FolderName\SpriteSheetTexture", 0, 3, 3, 1, 1); // "Stunt Double!!"
tempSprite.Position = new Vector2(((counter + 1) * (viewport.Width / 4)), viewport.Height / 2); // Position the Stuntman
tempSprite.OriginCentered = true;
tempSprite.CurrentFrame = counter;
SpriteManager[counter] = tempSprite; // Jettison Stuntman
} } // TODO: Load any ResourceManagementMode.Manual content
} /// <summary> Unload your graphics content. </summary>
/// <param name="unloadAllContent"> Specify which type of content to unload.</param>
protected override void UnloadGraphicsContent(bool unloadAllContent)
{
if (unloadAllContent)
{
foreach (SpriteSheet Dude in SpriteManager)
Dude.Dispose(); spriteBatch.Dispose(); content.Unload();
}
} /// <summary> Update Game Logic </summary>
/// <param name="gameTime"> Update only when the game engine says so. </param>
protected override void Update(GameTime gameTime)
{
// Allows the default game to exit on Xbox 360 or Windows if the Back Button or
// the Escape key has been pressed
if ((GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) ||
(Keyboard.GetState().IsKeyDown(Keys.Escape)))
this.Exit(); UpdateMouse(); foreach (SpriteSheet Dude in SpriteManager)
{
Dude.MouseOver(mousePosition);
Dude.Update(gameTime);
} base.Update(gameTime);
} /// <summary> Clear Screen & Draw Game </summary>
/// <param name="gameTime"> "We will update no game, before it's time." Will Wright </param>
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.Black); spriteBatch.Begin(); foreach (SpriteSheet Dude in SpriteManager)
{
Dude.DrawFrame(spriteBatch);
} spriteBatch.End(); base.Draw(gameTime);
} /// <summary> Get Mouse Data and store X and Y coords as Vector2 </summary>
protected void UpdateMouse()
{
MouseState mouseState = Mouse.GetState(); // MouseState has a lot of different properties. All we need is the Position for now. // The mouse X and Y positions are set relative to the Top, Left of the game window.
mousePosition.X = mouseState.X; // Get current Mouse Coordinates and store in Vector2 mousePosition.
mousePosition.Y = mouseState.Y; } // end UpdateMouse Method } /// <summary> SpriteSheet Class
/// Play Animation Sequence using multiple images from a single Texture file </summary>
class SpriteSheet
{
#region SpriteSheet Properties & Fields - Public && Private private Texture2D texture;
public Texture2D MyTexture
{
get { return texture; }
set { texture = value; }
} private Vector2 position;
public Vector2 Position
{
get { return position; }
set { position = value; }
} private Rectangle textureSegment;
public Rectangle TextureSegment
{
get { return textureSegment; }
set { textureSegment = value; }
} private Color color;
public Color Color
{
get { return color; }
set { color = value; }
} private float rotation;
public float Rotation
{
get { return rotation; }
set { rotation = value; }
} private float rotationSpeed;
public float RotationSpeed
{
get { return rotationSpeed; }
set { rotationSpeed = value; }
} private float scale;
public float Scale
{
get { return scale; }
set { scale = value; }
} private Vector2 origin;
public Vector2 Origin
{
get { return origin; }
set { origin = value; }
} private bool centered;
public bool OriginCentered
{
get { return centered; }
set { centered = value; }
} private bool centerOfScreen;
public bool CenterOfScreen
{
get { return centerOfScreen; }
set { centerOfScreen = value; }
} private SpriteEffects spriteEffects;
public SpriteEffects SpriteEffects
{
get { return spriteEffects; }
set { spriteEffects = value; }
} private float layerDepth;
public float LayerDepth
{
get { return layerDepth; }
set { layerDepth = value; }
} private int currentFrame;
public int CurrentFrame
{
get { return currentFrame; }
set { currentFrame = value; }
} private int startFrame;
public int StartFrame
{
get { return startFrame; }
set { startFrame = value; }
} private int endFrame;
public int EndFrame
{
get { return endFrame; }
set { endFrame = value; }
} private double frameDuration;
public double FrameDuration
{
get { return frameDuration; }
set { frameDuration = value; }
} private bool paused;
public bool Paused
{
get { return paused; }
set { paused = value; }
} private bool looped;
public bool Looped
{
get { return looped; }
set { looped = value; }
} private bool finishedPlaying;
public bool FinishedPlaying
{
get { return finishedPlaying; }
set { finishedPlaying = value; }
} private bool isClicked;
public bool IsClicked
{
get { return isClicked; }
set { isClicked = value; }
} public void Reset()
{
currentFrame = startFrame;
finishedPlaying = false;
frameTimer = 0f;
}
public void Stop()
{
Pause();
Reset();
}
public void Play()
{
paused = false;
if (finishedPlaying)
Reset();
}
public void Pause()
{
currentFrame--;
paused = true;
} private int framesAcross;
private int framesDown;
private Vector2 frameDimensions;
private double frameTimer; #endregion /// <summary> Load SpriteSheet default settings
/// </summary>
/// <param name="Texture"></param> <param name="StartFrame"></param> <param name="EndFrame"></param>
/// <param name="FramesAcross"></param> <param name="FramesDown"></param> <param name="FramesPerSecond"></param>
public SpriteSheet(string Texture, int StartFrame, int EndFrame, int FramesAcross, int FramesDown, double FramesPerSecond)
{
texture = Game1.content.Load<Texture2D>(Texture);
color = Color.White;
startFrame = StartFrame;
endFrame = EndFrame;
framesAcross = FramesAcross;
framesDown = FramesDown;
frameDuration = 1 / FramesPerSecond;
currentFrame = StartFrame;
frameDimensions = new Vector2(texture.Width / framesAcross, texture.Height / framesDown);
scale = 1.0f;
rotation = 0.0f;
rotationSpeed = 0.0f;
spriteEffects = SpriteEffects.None;
layerDepth = 0.5f;
looped = true;
} /// <summary> Update Current Frame </summary>
/// <param name="gameTime"> Update only when the Game Engine says it's OK </param>
public void Update(GameTime gameTime)
{
if (centerOfScreen)
position = new Vector2(Game1.viewport.Width / 2, Game1.viewport.Height / 2); // If true, Position Sprite in Center of Screen if (centered)
origin = frameDimensions / 2; // Set the Sprite's Center relative to the Texture Segment UpdateFrame(gameTime); // rotation += rotationSpeed; // Update rotation if rotationSpeed is greater than 0.0
} /// <summary> Autonomous Sprite Checks to see if Mouse has been clicked on it and
/// if Yes, Changes it's own Color :) </summary>
/// <param name="mousePosition"> Current Mouse Position must be passed in from outside because it's not part of the Sprite Class </param>
public void MouseOver(Vector2 mousePosition)
{
if (Mouse.GetState().LeftButton == ButtonState.Pressed) // Don't bother doing anything unless the Mouse has been clicked.
{
if (MouseOverSprite(mousePosition) == true) // First we do a simple collision check to see if we're within bounds of the Sprite.
{ // If yes, we get all anal and check each Pixel to see if it's Alpha ( visible ) or not.
if (GnatsAssPixelCheck(mousePosition) == true) // If the Pixel the Mouse is over is Visible....
isClicked = true; // do something.
}
}
else
{
isClicked = false; // If not, set it back the way it was.
} if (isClicked)
{
paused = true; }
else
paused = false; } /// <summary> Update SpriteSheet Index </summary>
/// <param name="gameTime"> When the Game Engine says jump, the Sprites say "how high?" </param>
public void UpdateFrame(GameTime gameTime)
{
if (paused)
return; frameTimer += gameTime.ElapsedGameTime.TotalSeconds; // Add a tick to the Frame Duration Timer.
if (frameTimer > frameDuration) // If frame has finished...
{
currentFrame++; // Increment to Next Frame.
// Play the SpriteSheet Animation from startFrame to endFrame
if ((currentFrame >= endFrame) || (currentFrame < startFrame)) // Ensure that the index stays inside the SpriteSheet
if (looped)
{
currentFrame = startFrame;
}
else
{
finishedPlaying = true;
Pause();
} frameTimer -= frameDuration; // Reset Frame Duration Timer
}
} public void DrawFrame(SpriteBatch spriteBatch)
{
// If the number of total frames is more than the number of frames across the texture, the texture has more than one row of frames.
// Calculate how many rows needed to wrap total number of frames in Index.
// Store Division result as Int, which drops any decimals. Telling us how many full rows there are.
int indexY = currentFrame / framesAcross;
// Subtract number of complete rows * number of frames across texture, from total index.
// The remainder tells us how many frames are left in incomplete row. Giving us the X coordinate of the current frame :)
int indexX = currentFrame - (indexY * framesAcross); textureSegment = new Rectangle(
indexX * (int)frameDimensions.X,
indexY * (int)frameDimensions.Y,
(int)frameDimensions.X,
(int)frameDimensions.Y
); spriteBatch.Draw(texture, position, textureSegment, color, rotation, origin, scale, spriteEffects, layerDepth);
} public void Dispose()
{
texture.Dispose();
} /// <summary> Check to see if the Mouse is within the specified Sprite's Texture Coords. </summary>
/// <param name="sprite2Check"> Simply pass in the name of the Sprite Class instance you would like to check :) </param>
/// <returns> Boolean Value - true if Mouse is over Sprite. </returns>
bool MouseOverSprite(Vector2 mousePosition)
{
if (mousePosition.X >= (position.X - origin.X) && mousePosition.X < (position.X + (textureSegment.Width) - origin.X) &&
mousePosition.Y >= (position.Y - origin.Y) && mousePosition.Y < (position.Y + (textureSegment.Height) - origin.Y))
return true;
else return false;
} // end MouseOverSprite Method bool GnatsAssPixelCheck(Vector2 mousePosition)
{
// Get Mouse position relative to top left of SpriteSheet Texture. ( This wuz a brain fry folks! )
Vector2 pixelPosition = mousePosition - position - origin + (frameDimensions)+ new Vector2(textureSegment.X, textureSegment.Y); uint[] PixelData = new uint[1]; // Declare an Array of 1 space just to store data for one pixel. // Get the Texture Data within the specified Rectangle coords, in this case a 1 X 1 rectangle.
// Store the data in pixelData Array.
texture.GetData<uint>(0, new Rectangle((int)pixelPosition.X, (int)pixelPosition.Y, (1), (1)), PixelData, 0, 1); // Check if pixel in Array is non Alpha ( plus a fudge factor of 20 )
if (((PixelData[0] & 0xFF000000) >> 24) > 20)
return true;
else return false;
} // end GnatsAssPixelCheck Method }
|