如何在Windows Mobile 7上实现SpriteSheet(Atlas)?

发布于 2024-11-03 13:37:40 字数 48 浏览 0 评论 0原文

如何在Windows Mobile 7上实现SpriteSheet(Atlas)?

How to implement SpriteSheet (Atlas) with Windows Mobile 7?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

去了角落 2024-11-10 13:37:40

移动设备面临的挑战之一是如何加载许多图像并在应用程序的生命周期内仍然从移动设备获得良好的性能。
以下是有关如何在 Windows Mobile 7 中使用 Sprite Sheet 的简短说明。
什么是 Sprite Sheet 以及为什么我们需要它?

当我们创建应用程序或游戏时,通常需要呈现许多图像。
在代码中单独调用每个图像会在应用程序的生命周期内为我们带来巨大的性能开销。
对于硬件资源有限的移动设备来说,这一点非常重要
有效地使用这些精灵(图像)以获得良好的性能。
那么精灵表如何帮助我们呢?
Sprite Sheet 是包含许多小精灵(图像)的大图像文件,
因此,我们只使用一个图像文件,而不是使用许多图像!
我们的代码调用它一次,因为图像按顺序存储在该图像文件上
它还可以节省不必要的未使用空间,从而在加载时减少内存。
以下是有关如何使用 Windows Mobile 7 进行此操作的说明。
我对 Microsoft 发布的原始 KB 进行了一些修改。

  1. http://create.msdn.com/en-US 下载代码/education/catalog/sample/sprite_sheet
  2. 提取它。
  3. 要在您自己的游戏中重用此代码,请将 SpriteSheetPipeline 和 SpriteSheetRuntime 项目添加到您的解决方案中。

A. 使管道项目可用于构建您的内容

  1. 右键单击​​内容 |您的内容项目中的引用项。
  2. 单击添加参考。
  3. 单击“项目”选项卡,然后选择“SpriteSheetPipeline”项目。

B. 使 SpriteSheet 类可用于您的游戏

  1. 右键单击​​主游戏项目中的 References 项。
  2. 单击添加参考。
  3. 单击“Projects”选项卡,然后选择“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 文件添加到内容文件夹项目(这不是主项目,因此请注意)
现在要实际使用 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);
}

One of the challenges with mobile devices, is how to load many images and still get good performance from the mobile device during the life time of the application.
Here is a short explanation on how to use Sprite Sheet with windows mobile 7.
What is Sprite Sheet and why do we need it?

When we create application or a game usually we need to present many images.
Calling each image separately in the code create for us huge overhead performance during the life time of the application.
When it comes to mobile devices with limited hardware resources it is very important to
use these sprites(images) efficiently to get good performance.
So how the spritesheet help us?
Sprite Sheet is big image file that contain many small sprites (images),
So instead of using many many images we use only one image file only!
Our code call it once, and because the images are stored orderly on that image file
it also save unnecessary unused space resulting less memory when loading it.
Here is the explanation on how to do it with Windows Mobile 7.
I made some modification to the original KB that Microsoft published.

  1. Download the code from http://create.msdn.com/en-US/education/catalog/sample/sprite_sheet
  2. Extract it.
  3. To reuse this code in your own game, add the SpriteSheetPipeline and SpriteSheetRuntime projects to your solution.

A. To make the pipeline project available for building your content

  1. Right-click the Content | References item in your content project.
  2. Click Add Reference.
  3. Click the Projects tab, and then select the SpriteSheetPipeline project.

B. To make the SpriteSheet class available to your game

  1. Right-click the References item in your main game project.
  2. Click Add Reference.
  3. Click the Projects tab, and select the SpriteSheetRuntime project

Now to actually use the Code which we imported we first will create new xml file and put in the content directory, the format of the XML should be like this:

<?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>

As you can see this xml contain the names of the images that we will create SpriteSheet(atlas) from, there is NO need to add these sprites images to your project via visual studio just copy the images to the physical content directory, and of course it is require that you will add the XML file via visual studio to the Content folder Project (This is not the main project so be aware of it)
Now to actually use the XML file you need to do few things.
We need to set the property of the xml file.
Content Importer will be XML Content - XNA Framework
Content Processor will be SpriteSheetProcessor
After we set the proprty we can actually call the file.
First we will tell our code to use the SpriteSheetRuntime

So we will add

using SpriteSheetRuntime;

We will declare new spritebatch and spritesheet object

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;
       }

In the load content we will do the following:

       protected override void LoadContent()
        {
          spriteBatch = new SpriteBatch(GraphicsDevice);
          spriteSheet = Content.Load<SpriteSheet>("SpriteSheet");
        }

The XML file in this case will be SpriteSheet.xml like the exaple above.
Now we need to display the sprites either by animated them or show all of them at once..
So we will use the following spriteBatch.Draw, but before that we will start the spriteBatch

protected override void Draw(GameTime gameTime)
{
    spriteBatch.Begin();

if you will look at the class (SpriteBatch) you will find few options to draw on to the screen, you can choose the most suitable for you:

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);

So eventually we can write something like that:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文