移动设备面临的挑战之一是如何在应用程序的生命周期内加载许多图像并仍能从移动设备获得良好的性能。
这是关于如何在 windows mobile 7 中使用 Sprite Sheet 的简短说明。
什么是 Sprite Sheet,我们为什么需要它?
当我们创建应用程序或游戏时,通常我们需要呈现许多图像。
在代码中分别调用每个图像会在应用程序的生命周期内为我们带来巨大的开销性能。
当涉及到硬件资源有限的移动设备时,
有效地使用这些精灵(图像)以获得良好的性能。
那么 spritesheet 如何帮助我们呢?
Sprite Sheet 是包含许多小精灵(图像)的大图像文件,
因此,我们只使用一个图像文件,而不是使用许多图像!
我们的代码调用它一次,因为图像有序地存储在该图像文件中
它还可以节省不必要的未使用空间,从而在加载时减少内存。
这是有关如何使用 Windows Mobile 7 执行此操作的说明。
我对微软发布的原始 KB 做了一些修改。
- 从http://create.msdn.com/en-US/education/catalog/sample/sprite_sheet下载代码
- 解压。
- 要在您自己的游戏中重用此代码,请将 SpriteSheetPipeline 和 SpriteSheetRuntime 项目添加到您的解决方案中。
A.使管道项目可用于构建您的内容
- 右键单击内容 |内容项目中的参考项目。
- 点击添加参考。
- 单击“项目”选项卡,然后选择 SpriteSheetPipeline 项目。
B.使 SpriteSheet 类可用于您的游戏
- 右键单击主游戏项目中的 References 项。
- 点击添加参考。
- 单击“项目”选项卡,然后选择 SpriteSheetRuntime 项目
现在要实际使用我们首先导入的代码,我们将创建一个新的xml文件并放在内容目录中,xml的格式应该是这样的:
<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
<Asset Type ="System.String[]">
<Item>L01_480_0.png</Item>
<Item>L01_480_1.png</Item>
<Item>L01_480_2.png</Item>
<Item>L01_480_3.png</Item>
<Item>L01_480_4.png</Item>
<Item>L01_480_5.png</Item>
<Item>L01_480_6.png</Item>
<Item>L01_480_7.png</Item>
<Item>L01_480_8.png</Item>
<Item>L01_480_9.png</Item>
<Item>L01_480_10.png</Item>
<Item>L01_480_11.png</Item>
<Item>L01_480_12.png</Item>
</Asset>
</XnaContent>
你可以看到这个 xml 包含我们将创建 SpriteSheet(atlas) 的图像的名称,没有需要通过 Visual Studio 将这些精灵图像添加到您的项目中,只需复制图像到物理内容目录,当然需要您通过 Visual Studio 将 XML 文件添加到 Content 文件夹项目(这不是主要项目,所以要注意它)
现在要实际使用 XML 文件,您需要做一些事情。
我们需要设置xml文件的属性。
内容导入器将是 XML 内容 - XNA 框架
内容处理器将是 SpriteSheetProcessor
设置好属性后,我们就可以真正调用文件了。
首先我们将告诉我们的代码使用 SpriteSheetRuntime
所以我们将添加
using SpriteSheetRuntime;
我们将声明新的 spritebatch 和 spritesheet 对象
namespace SpriteSheetGame
{
/// This is the main type for your game
public class Game: Microsoft.Xna.Framework.Game
{
/* Handles the configuration and management of the graphics device.*/
GraphicsDeviceManager graphics;
/* Enables a group of sprites to be
drawn using the same settings */
SpriteBatch spriteBatch;
/* A sprite sheet contains many individual sprite images, packed into different
areas of a single larger texture, along with information describing where in
that texture each sprite is located */
SpriteSheet spriteSheet;
}
在加载内容中我们会做以下事情:
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
spriteSheet = Content.Load<SpriteSheet>("SpriteSheet");
}
在这种情况下,XML 文件将是 SpriteSheet.xml,就像上面的例子一样。
现在我们需要通过动画或一次显示所有精灵来显示精灵。
所以我们将使用下面的 spriteBatch.Draw,但在此之前我们将启动 spriteBatch
protected override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
如果你看一下类 (SpriteBatch),你会发现在屏幕上绘制的选项很少,你可以选择最适合你的:
public void Draw(Texture2D texture, Vector2 position, Color color);
public void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, Color color);
public void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color);
public void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth);
public void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth);
public void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
所以最终我们可以这样写:
protected override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
// Draw an animating effect, by rapidly cycling
// through 13 slightly different sprite images.
const int animationFramesPerSecond = 2;
const int animationFrameCount = 13;
// Look up the index of the first sprite.
int index = spriteSheet.GetIndex("L01_480_0");
// Modify the index to select the current frame of the animation.
index += (int)(time * animationFramesPerSecond) % animationFrameCount;
// Draw the current sprite.
spriteBatch.Draw(spriteSheet.Texture, new Rectangle(0, 0, 100, 100),
spriteSheet.SourceRectangle(index), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}