📄 gxanimation.cs
字号:
using System;
using System.IO;
using System.Drawing;
using System.Diagnostics;
namespace GXGraphicsLibrary
{
/// <summary>
/// Summary description for GXAnimation.
/// </summary>
public class GXAnimation : IDisposable
{
/// <summary>
/// Specifies that no one-shot is playing.
/// </summary>
const float kInvalidOneShotIndex = -1.0F;
/// <summary>
/// Width of an individual animation cell.
/// </summary>
public int CellWidth { get { return m_cellWidth; } }
protected int m_cellWidth;
/// <summary>
/// Height of an individual animation cell.
/// </summary>
public int CellHeight { get { return m_cellHeight; } }
protected int m_cellHeight;
/// <summary>
/// Number of cell rows in the bitmap.
/// </summary>
protected int m_numRows;
/// <summary>
/// Number of cell columns in the bitmap.
/// </summary>
protected int m_numCols;
/// <summary>
/// Bitmap to be used for animating.
/// </summary>
public IGXBitmap Image { get { return m_bmp; } }
protected IGXBitmap m_bmp;
/// <summary>
/// Index of the animation cell currently being displayed. This
/// index is specified within the context of the current cycle
/// (between the start and end cells), not the absolute cell within
/// the entire animation image.
/// </summary>
public int CurCell
{
get
{
if (m_curOneShotCell == kInvalidOneShotIndex)
return (int)(m_curCell - m_startCell);
return (int)(m_curOneShotCell - m_oneShotStartCell);
}
set
{
if (m_curOneShotCell == kInvalidOneShotIndex)
m_curCell = (float)value + m_startCell;
else
m_curOneShotCell = (float)value + m_oneShotStartCell;
}
}
protected float m_curCell;
/// <summary>
/// Gets the maximum number of cells in the animation.
/// </summary>
public int NumCells { get { return m_numCols * m_numRows; } }
/// <summary>
/// Gets/Sets the rate of the animation in cells per second.
/// </summary>
public int AnimRate
{
get
{
if (m_curOneShotCell == kInvalidOneShotIndex)
return (int)m_cellsPerSecond;
return (int)m_oneShotCellsPerSecond;
}
set
{
if (m_curOneShotCell == kInvalidOneShotIndex)
m_cellsPerSecond = (float)value;
else
m_oneShotCellsPerSecond = (float)value;
}
}
protected float m_cellsPerSecond;
/// <summary>
/// Cached rectangle representing the drawing bounds of the current cell.
/// </summary>
internal Rectangle Region { get { return m_srcRegion; } }
protected Rectangle m_srcRegion = new Rectangle(0,0,0,0);
/// <summary>
/// Keep track of whether the Bitmap used by this animation was allocated
/// or not.
/// </summary>
protected bool m_allocated = false;
/// <summary>
/// Specifies whether the animation has been properly initialized or
/// not.
/// </summary>
public bool Init { get { return m_initialized; } }
protected bool m_initialized = false;
/// <summary>
/// Index of the first cell in the animation cycle.
/// </summary>
protected float m_startCell;
/// <summary>
/// Index of the last cell in the animation cycle.
/// </summary>
protected float m_endCell;
/// <summary>
/// Index of the first cell in a one-shot animation cycle.
/// After a one-shot is complete, it defaults back to the
/// regular cycle.
/// </summary>
protected float m_oneShotStartCell;
/// <summary>
/// Index of the last cell in a one-shot animation cycle.
/// After a one-shot is complete, it defaults back to the
/// regular cycle.
/// </summary>
protected float m_oneShotEndCell;
/// <summary>
/// Rate of one-shot animation in cells per second.
/// </summary>
protected float m_oneShotCellsPerSecond;
/// <summary>
/// Index of cell currently being played on a one-shot
/// animation. If set to kInvalidOneShotIndex then
/// no one-shot is playing.
/// </summary>
protected float m_curOneShotCell = kInvalidOneShotIndex;
/// <summary>
/// Used to determine if a one-shot has finished.
/// </summary>
public bool Done { get { return m_curOneShotCell == kInvalidOneShotIndex; } }
/// <summary>
/// Create an animation from a Bitmap stream.
/// </summary>
/// <param name="bmpData">Stream representing source bitmap</param>
/// <param name="gx">GXGraphics object, needed for bitmap loading</param>
/// <param name="numRows">Number of rows of cells in the animation</param>
/// <param name="numCols">Number of columns of cells in the animation</param>
/// <param name="startCell">Index from which to start animating</param>
/// <param name="cellWidth">Width of individual animation cells</param>
/// <param name="cellHeight">Height of individual animation cells</param>
/// <param name="cellsPerSecond">Rate of animation in cells per second</param>
/// <param name="curTime_ms">The time that this animation started animating in milliseconds</param>
public GXAnimation(string fileName, IGXGraphics gx, int numRows, int numCols, int startCell, int cellWidth, int cellHeight, int cellsPerSecond)
{
m_initialized = false;
// Initialize the cell information
m_cellWidth = cellWidth;
m_cellHeight = cellHeight;
m_numRows = numRows;
m_numCols = numCols;
m_startCell = 0;
m_endCell = m_numRows * m_numCols - 1;
// Load and initialize the Bitmap object
m_bmp = gx.CreateBitmap(fileName, true);
if (m_bmp == null)
{
m_initialized = false;
return;
}
m_allocated = true;
// Initialize timing information
m_cellsPerSecond = (float)cellsPerSecond;
// Initialize the draw region rectangle
m_srcRegion.Width = m_cellWidth;
m_srcRegion.Height = m_cellHeight;
// Validate information for drawing the first cell
Update(0.0F);
m_initialized = true;
}
/// <summary>
/// Create an animation that shares information from another animation.
/// </summary>
/// <param name="anim">Original GXAnimation object</param>
/// <param name="startCell">Index from which to start animating</param>
/// <param name="cellsPerSecond">Rate of animation in cells per second</param>
/// <param name="curTime_ms">The time that this animation started animating in milliseconds</param>
public GXAnimation(GXAnimation anim, int startCell, int cellsPerSecond)
{
m_initialized = false;
// Initialize the cell information
m_cellWidth = anim.m_cellWidth;
m_cellHeight = anim.m_cellHeight;
m_numRows = anim.m_numRows;
m_numCols = anim.m_numCols;
m_startCell = 0;
m_endCell = m_numRows * m_numCols - 1;
// Copy the reference to the original bitmap
m_bmp = anim.m_bmp;
if (m_bmp == null)
{
m_initialized = false;
return;
}
m_allocated = false;
// Initialize timing information
m_cellsPerSecond = (float)cellsPerSecond;
// Initialize the draw region rectangle
m_srcRegion.Width = m_cellWidth;
m_srcRegion.Height = m_cellHeight;
// Validate information for drawing the first cell
Update(0.0F);
m_initialized = true;
}
/// <summary>
/// Set the start and end cells of the current animation cycle. All
/// cells will be played sequentially within the cycle.
/// </summary>
/// <param name="startCell">Index of starting cell</param>
/// <param name="endCell">Index of ending cell</param>
public void SetCycle(int startCell, int endCell, int animRate)
{
m_curOneShotCell = kInvalidOneShotIndex;
m_startCell = (float)startCell;
m_endCell = (float)endCell;
m_cellsPerSecond = animRate;
m_curCell = m_startCell;
}
/// <summary>
/// Start a one shot animation cycle. This cycle will interrupt the
/// current cycle, then resume the current cycle once finished.
/// </summary>
/// <param name="startCell">Index of start cell in cycle</param>
/// <param name="endCell">Index of end cell in cycle</param>
public void StartOneShot(int startCell, int endCell, int animRate)
{
m_oneShotStartCell = (float)startCell;
m_oneShotEndCell = (float)endCell;
m_oneShotCellsPerSecond = (float)animRate;
m_curOneShotCell = m_oneShotStartCell;
}
/// <summary>
/// Update the animation cell information.
/// </summary>
/// <param name="curTime_ms">Current system time in milliseconds.</param>
public void Update(float deltaTime_s)
{
float deltaFrames = AnimRate * deltaTime_s;
// Animations look bad if frames are skipped even though the frame-
// rate might be too slow so don't allow it
if (deltaFrames > 1.0F)
deltaFrames = 1.0F;
int curCell;
if (kInvalidOneShotIndex != m_curOneShotCell)
{
m_curOneShotCell += deltaFrames;
if (m_curOneShotCell >= m_oneShotEndCell + 1.0F)
{
m_curOneShotCell = kInvalidOneShotIndex;
curCell = (int)m_curCell;
}
else
{
curCell = (int)m_curOneShotCell;
}
}
else
{
m_curCell += deltaFrames;
if (m_curCell >= m_endCell + 1.0F)
m_curCell = m_startCell;
curCell = (int)m_curCell;
}
Debug.Assert(m_numCols > 0,
"GXAnimation.Update: Invalid number of columns specified");
// Set up the draw region rectangle for the current cell
m_srcRegion.X = (int)((curCell % m_numCols) * m_cellWidth);
m_srcRegion.Y = (int)((curCell / m_numCols) * m_cellHeight);
}
/// <summary>
/// Clean up any memory allocated by the bitmap object.
/// </summary>
public void Dispose()
{
if (!m_allocated)
return;
if (m_bmp != null)
m_bmp.Dispose();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -