在游戏开发中,创建一个简单的2D动画可能需要开发者自己处理很多细节,这在某些情况下是有利的,但对于简单的2D动画来说可能会感到繁琐。本文旨在帮助用户创建一个动画类,以减少通常需要关注的控制问题。
本文不会单独介绍Silverlight和XNA。读者需要了解XNA和Silverlight的基础知识,主要是XNA。主要目的是解释如何创建一个动画类,以帮助进一步的开发。创建XNA应用程序和Windows Phone Silverlight以及XNA应用程序之间存在一些差异。由于Silverlight应用程序基于事件,因此大多数方法参数将是事件参数,但除此之外,主要思想是相同的。
首先,需要创建一个Windows Phone游戏库(4.0)。由于将仅在XNA类中使用它,因此需要使用这种类型的项目。正如提到的,它将在XNA类中使用,因此需要保持XNA方法命名,所以需要三个方法:
public virtual void Draw(SpriteBatch spriteBatch);
public virtual void Load(ContentManager contentManager, GraphicsDevice graphicDevice);
public virtual void Update(double gameTime);
在创建这个类时,需要知道每行和每列的精灵数量,以及精灵的名称。
public Animated2dSpriteBase(int spritesPerWidth, int spritesPerHeight, string spriteName)
{
this.m_spriteName = spriteName;
this.m_framesCountPerHeight = spritesPerHeight;
this.m_framesCountPerWidth = spritesPerWidth;
this.m_totalFramesCount = spritesPerHeight * spritesPerWidth;
this.m_currentFrameNo = 1;
this.IntervalTime = INTERVALTIME;
this.m_timer = 0;
this.X = 0;
this.Y = 0;
this.Animate = true;
}
在加载时,一些参数已经在XNASilverlight应用程序类中声明。内容管理器来自Silverlight应用程序,如(Application.Current as App).Content,以及graphicDevice SharedGraphicsDeviceManager.Current.GraphicsDevice。
public virtual void Load(ContentManager contentManager, GraphicsDevice graphicDevice)
{
m_spriteSheet = contentManager.Load<Texture2D>(m_spriteName);
m_spriteWindowWidth = m_spriteSheet.Width / m_framesCountPerWidth;
m_spriteWindowHeight = m_spriteSheet.Height / m_framesCountPerHeight;
m_spriteOutputRectangle = new Rectangle(0, 0, m_spriteWindowWidth, m_spriteWindowHeight);
}
通过构造函数传递的精灵名称是从参数contentManager中加载的。使用Sprite bach与典型的XNA游戏类相同。每次只绘制正确的帧输出。
public virtual void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(m_spriteSheet, new Rectangle(X, Y, m_spriteWindowWidth, m_spriteWindowHeight), m_spriteOutputRectangle, Color.White);
}
由于SilverlightXNA类只有GameTimerEventArgs,其中只包含TimeSpan类,只能获得传递给Update方法的时间。
public virtual void Update(double gameTime)
{
if (gameTime > m_timer && Animate)
{
m_timer = gameTime + m_intervalSec;
m_currentFrameNo++;
if (m_currentFrameNo > m_totalFramesCount)
m_currentFrameNo = 1;
CalculateOutRectanglePosition();
}
}
如果默认时间(m_timer)已过,并且Animate布尔标志为true,更新当前帧号并重新计算输出矩形位置。Animate标志是属性类型,因此可以随时关闭动画,当前帧将输出到屏幕上。
CalculateOutRectanglePosition的主要目的是使用当前帧号找到输出矩形位置。假设精灵表如下所示,当前帧是5,所以需要找出行号和列号。然后它将是2和2。当这些数字计算出来后,很容易计算输出矩形位置。简单地乘以行号减1,因为起始位置从0开始。