// Project: XnaGraphicEngineVs2005, File: SpriteHelper.cs // Namespace: XnaGraphicEngine.Graphics, Class: SpriteHelper // Path: C:\code\XnaBook\XnaGraphicEngine\Graphics, Author: Abi // Code lines: 368, Size of file: 11,31 KB // Creation date: 27.11.2006 04:51 // Last modified: 27.11.2006 05:07 // Generated with Commenter by abi.exDream.com #region Using directives using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using System.Text; using Texture = XnaGraphicEngine.Graphics.Texture; using XnaGraphicEngine.Game; #endregion namespace XnaGraphicEngine.Graphics { /// <summary> /// Sprite helper class to manage and render sprites. /// </summary> internal class SpriteHelper { #region SpriteToRender helper class /// <summary> /// Sprite to render /// </summary> class SpriteToRender { #region Variables /// <summary> /// Texture /// </summary> public Texture texture; /// <summary> /// Rectangle /// </summary> public Rectangle rect; /// <summary> /// Source pixel rectangle /// </summary> public Rectangle pixelRect; /// <summary> /// Color /// </summary> public Color color; /// <summary> /// Rotation /// </summary> public float rotation = 0; /// <summary> /// Rotation point for rotated sprites. /// </summary> public Vector2 rotationPoint = Vector2.Zero; /// <summary> /// Blend mode, defaults to SpriteBlendMode.AlphaBlend /// </summary> public SpriteBlendMode blendMode = SpriteBlendMode.AlphaBlend; #endregion #region Constructor /// <summary> /// Create sprite to render /// </summary> /// <param name="setTexture">Set texture</param> /// <param name="setRect">Set rectangle</param> /// <param name="setPixelRect">Set source rectangle</param> /// <param name="setColor">Set color</param> public SpriteToRender(Texture setTexture, Rectangle setRect, Rectangle setPixelRect, Color setColor) { texture = setTexture; rect = setRect; pixelRect = setPixelRect; color = setColor; } // SpriteToRender(setTexture, setRect, setSourceRect) /// <summary> /// Create sprite to render /// </summary> /// <param name="setTex">Set tex</param> /// <param name="setRect">Set rectangle</param> /// <param name="setPixelRect">Set pixel rectangle</param> /// <param name="setColor">Set color</param> /// <param name="alphaMode">Alpha mode</param> public SpriteToRender(Texture setTex, Rectangle setRect, Rectangle setPixelRect, Color setColor, SpriteBlendMode setBlendMode) { texture = setTex; rect = setRect; pixelRect = setPixelRect; color = setColor; blendMode = setBlendMode; } // SpriteToRender(setTex, setRect, setPixelRect) /// <summary> /// Create sprite to render /// </summary> /// <param name="setTex">Set tex</param> /// <param name="setRect">Set rectangle</param> /// <param name="setPixelRect">Set pixel rectangle</param> /// <param name="setRotation">Set rotation</param> /// <param name="setRotationPoint">Set rotation point</param> public SpriteToRender(Texture setTex, Rectangle setRect, Rectangle setPixelRect, float setRotation, Vector2 setRotationPoint) { texture = setTex; rect = setRect; pixelRect = setPixelRect; rotation = setRotation; rotationPoint = setRotationPoint; } // SpriteToRender(setTex, setRect, setPixelRect) #endregion #region Render /// <summary> /// Render /// </summary> /// <param name="uiSprites">User interface sprites</param> public void Render(SpriteBatch uiSprites) { // Don't render if texture is null (else XNA throws an exception!) if (texture == null || texture.XnaTexture == null || color.A == 0) return; if (rotation == 0) uiSprites.Draw(texture.XnaTexture, rect, pixelRect, color); else uiSprites.Draw(texture.XnaTexture, rect, pixelRect, color, rotation, //new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), rotationPoint, SpriteEffects.None, 0); } // Render(uiSprites) #endregion } // class SpriteToRender #endregion #region Variables /// <summary> /// Keep a list of all sprites we have to render this frame. /// </summary> static List<SpriteToRender> sprites = new List<SpriteToRender>(); /// <summary> /// Sprite batch for rendering /// </summary> static SpriteBatch spriteBatch = null; #endregion #region Dispose /// <summary> /// Dispose the static spriteBatch and sprites helpers in case /// the device gets lost. /// </summary> public static void Dispose() { sprites.Clear(); if (spriteBatch != null) spriteBatch.Dispose(); spriteBatch = null; } // Dispose() #endregion #region Private constructor /// <summary> /// Create sprite helper, private. Instantiation is not allowed. /// </summary> private SpriteHelper() { } // SpriteHelper() #endregion #region Add sprite to render /// <summary> /// Add sprite to render /// </summary> /// <param name="texture">Texture</param> /// <param name="rect">Rectangle</param> /// <param name="gfxRect">Gfx rectangle</param> /// <param name="color">Color</param> public static void AddSpriteToRender( Texture texture, Rectangle rect, Rectangle gfxRect, Color color) { sprites.Add(new SpriteToRender(texture, rect, gfxRect, color)); } // AddSpriteToRender(texture, rect, gfxRect) /// <summary> /// Add sprite to render /// </summary> /// <param name="texture">Texture</param> /// <param name="rect">Rectangle</param> /// <param name="gfxRect">Gfx rectangle</param> public static void AddSpriteToRender( Texture texture, Rectangle rect, Rectangle gfxRect) { sprites.Add(new SpriteToRender(texture, rect, gfxRect, Color.White)); } // AddSpriteToRender(texture, rect, gfxRect) /// <summary> /// Add sprite to render /// </summary> /// <param name="texture">Texture</param> /// <param name="rect">Rectangle</param> /// <param name="gfxRect">Gfx rectangle</param> public static void AddSpriteToRender( Texture texture, Rectangle rect, Rectangle gfxRect, Color color, SpriteBlendMode blendMode) { sprites.Add( new SpriteToRender(texture, rect, gfxRect, color, blendMode)); } // AddSpriteToRender(texture, rect, gfxRect) /// <summary> /// Add sprite to render /// </summary> /// <param name="texture">Texture</param> /// <param name="rect">Rectangle</param> public static void AddSpriteToRender( Texture texture, Rectangle rect, Color color) { AddSpriteToRender(texture, rect, texture.GfxRectangle, color); } // AddSpriteToRender(texture, rect, color) /// <summary> /// Add sprite to render /// </summary> /// <param name="texture">Texture</param> /// <param name="rect">Rectangle</param> public static void AddSpriteToRender( Texture texture, Rectangle rect) { AddSpriteToRender(texture, rect, texture.GfxRectangle, Color.White); } // AddSpriteToRender(texture, rect) /// <summary> /// Add sprite to render /// </summary> /// <param name="texture">Texture</param> /// <param name="x">X</param> /// <param name="y">Y</param> public static void AddSpriteToRender( Texture texture, int x, int y, Color color) { AddSpriteToRender(texture, new Rectangle(x, y, texture.GfxRectangle.Width, texture.GfxRectangle.Height), color); } // AddSpriteToRender(texture, x, y) /// <summary> /// Add sprite to render /// </summary> /// <param name="texture">Texture</param> public static void AddSpriteToRender( Texture texture, int x, int y) { AddSpriteToRender(texture, new Rectangle(x, y, texture.GfxRectangle.Width, texture.GfxRectangle.Height)); } // AddSpriteToRender(texture, x, y) /// <summary> /// Add sprite to render /// </summary> /// <param name="texture">Texture</param> public static void AddSpriteToRender( Texture texture) { AddSpriteToRender(texture, new Rectangle(0, 0, 1024, 768)); } // AddSpriteToRender(texture) /// <summary> /// Add sprite to render /// </summary> /// <param name="tex">Tex</param> /// <param name="rect">Rectangle</param> /// <param name="pixelRect">Pixel rectangle</param> /// <param name="rotation">Rotation</param> public static void AddSpriteToRender(Texture tex, Rectangle rect, Rectangle pixelRect, float rotation, Vector2 rotationPoint) { sprites.Add(new SpriteToRender( tex, rect, pixelRect, rotation, rotationPoint)); } // AddSpriteToRender(tex, rect, pixelRect) /// <summary> /// Add sprite to render centered /// </summary> /// <param name="texture">Texture</param> /// <param name="x">X</param> /// <param name="y">Y</param> /// <param name="scale">Scale</param> public static void AddSpriteToRenderCentered( Texture texture, float x, float y, float scale) { AddSpriteToRender(texture, new Rectangle( (int)(x * 1024 - scale * texture.GfxRectangle.Width/2), (int)(y * 768 - scale * texture.GfxRectangle.Height/2), (int)(scale * texture.GfxRectangle.Width), (int)(scale * texture.GfxRectangle.Height))); } // AddSpriteToRenderCentered(texture, x, y) /// <summary> /// Add sprite to render centered /// </summary> /// <param name="texture">Texture</param> /// <param name="pos">Position</param> public static void AddSpriteToRenderCentered( Texture texture, float x, float y) { AddSpriteToRenderCentered(texture, x, y, 1); } // AddSpriteToRenderCentered(texture, x, y) /// <summary> /// Add sprite to render centered /// </summary> /// <param name="texture">Texture</param> /// <param name="pos">Position</param> public static void AddSpriteToRenderCentered( Texture texture, Vector2 pos) { AddSpriteToRenderCentered(texture, pos.X, pos.Y); } // AddSpriteToRenderCentered(texture, pos) #endregion #region DrawSprites /// <summary> /// Draw sprites /// </summary> /// <param name="width">Width</param> /// <param name="height">Height</param> public static void DrawSprites(int width, int height) { // No need to render if we got no sprites this frame if (sprites.Count == 0) return; // Create sprite batch if we have not done it yet. // Use device from texture to create the sprite batch. if (spriteBatch == null) spriteBatch = new SpriteBatch(BaseGame.Device); // Render all textures on our ui sprite batch if (sprites.Count > 0) { // We can improve a little performance by rendering // the additive stuff at first end! bool startedAdditiveSpriteMode = false; for (int spriteNum = 0; spriteNum < sprites.Count; spriteNum++) { SpriteToRender sprite = sprites[spriteNum]; if (sprite.blendMode == SpriteBlendMode.Additive) { if (startedAdditiveSpriteMode == false) { startedAdditiveSpriteMode = true; spriteBatch.Begin( SpriteBlendMode.Additive, SpriteSortMode.BackToFront, SaveStateMode.None); } // if (startedAdditiveSpriteMode) sprite.Render(spriteBatch); } // if (sprite.blendMode) } // for (spriteNum) if (startedAdditiveSpriteMode) spriteBatch.End(); // Handle all remembered sprites for (int spriteNum = 0; spriteNum < sprites.Count; spriteNum++) { SpriteToRender sprite = sprites[spriteNum]; if (sprite.blendMode != SpriteBlendMode.Additive) { spriteBatch.Begin( //SpriteBlendMode.Additive,//.AlphaBlend, sprite.blendMode, SpriteSortMode.BackToFront, SaveStateMode.None); sprite.Render(spriteBatch); // Dunno why, but for some reason we have start a new sprite // for each texture change we have. Else stuff is not rendered // in the correct order on top of each other. spriteBatch.End(); } // if (sprite.blendMode) } // for (spriteNum) // Kill list of remembered sprites sprites.Clear(); } // if (sprites.Count) } // DrawSprites(width, height) #endregion } // class SpriteHelper } // namespace XnaGraphicEngine.Graphics