如何创建精灵图像

本文关键字:精灵 图像 创建 何创建 | 更新日期: 2023-09-27 18:33:17

我正在尝试创建一个非常基本的精灵图像。

首先,我有一个现有的图像(宽度= 100px,高度= 100px(。

我将循环浏览此图像 10 到 100 次,每次都将其放在前一个图像旁边的角色上。

角色的宽度限制为 3000 像素。

将图像

彼此相邻放置很好,因为我可以用一个简单的方法将它们组合在一起,但是,我需要将组合图像的宽度限制为 3000px,然后从新行开始。

如何创建精灵图像

以下 MSDN 文章中提供了有关 2D 精灵的大量信息:渲染 2D 精灵

这些例子基于Microsoft的XNA,这是一个可以在Visual Studio中用于开发Windows,Windows Phone和XBOX 360游戏的平台。

例如,若要绘制精灵,可以使用以下 C# 代码(示例取自 MSDN 文章,删除了 XBOX 360 特定代码(:

private Texture2D SpriteTexture;
private Rectangle TitleSafe;
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
        SpriteTexture = Content.Load<Texture2D>("ship");
        TitleSafe = GetTitleSafeArea(.8f);
    }
    protected Rectangle GetTitleSafeArea(float percent)
    {
        Rectangle retval = new Rectangle(
            graphics.GraphicsDevice.Viewport.X,
            graphics.GraphicsDevice.Viewport.Y,
            graphics.GraphicsDevice.Viewport.Width,
            graphics.GraphicsDevice.Viewport.Height);
        return retval;
    }
    protected override void Draw(GameTime gameTime)
    {
        graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        Vector2 pos = new Vector2(TitleSafe.Left, TitleSafe.Top);
        spriteBatch.Draw(SpriteTexture, pos, Color.White);
        spriteBatch.End();
        base.Draw(gameTime);
    }

您需要调用LoadContent()来初始化它,然后您需要调用GetTitleSafeArea(100)以获取安全绘制区域(在本例中为 100%(,最后您可以使用 Draw 方法。它接受包含 GameTime 类实例的参数,该实例是游戏计时状态的快照,以可变步长(实时(或固定步长(游戏时间(游戏可以使用的值表示。

如果对您有帮助,请告诉我。

让我尝试一些伪代码:

Bitmap originalImage; //  that is your image of 100x100 pixels
Bitmap bigImage;      //  this is your 3000x3000 canvas
int xPut = 0;
int yPut = 0;
int maxHeight = 0;
while (someExitCondition) 
{
    Bitmap imagePiece = GetImagePieceAccordingToSomeParameters(originalImage);
    if (xPut + imagePiece.Width > 3000)
    {
        xPut = 0;
        yPut += maxHeight;
        maxHeight = 0;
    }
    DrawPieceToCanvas(bigImage, xPut, yPut, imagePiece);
    xPut += imagePiece.Width;
    if (imagePiece.Height > maxHeight) maxHeight = imagePiece.Height;
    //  iterate until done
}

3000 处声明一个变量,如果您放入宽度为 250 的图片,请将其从变量中取出,继续这样做,这也允许您通过查看剩余的数字是否大于下一张图片的宽度来确定该行上是否有足够的空间用于您的下一张图片。 每次从新行开始时,将变量设置回 3K 并重新开始。 已解决

一种可行的方法是允许将精灵的帧放置在位图中的任何位置(这样你可以使它们更紧凑(,并在每个位图上附带一个(n xml(文件,该文件描述了每个帧的位置,大小和原点,并列出了所有动画。像这样:

<SpriteSheet>
    <Frames>
        <Frame id="0" location="20,40" size="64,64" origin="32,32" />
        <Frame id="1" location="100,40" size="64,64" origin="32,32" />
        <Frame id="2" location="164,40" size="64,64" origin="0,0" />
        <Frame id="3" location="20,120" size="64,64" origin="32,32" />
    </Frames>
    <Animations>
        <Animation name="walk left" >
            <Keyframes>
                <Keyframe frameId="0" duration="0:0:0.5" offset="-5,0" />
                <Keyframe frameId="1" duration="0:0:0.5" offset="-5,0" />
                <Keyframe frameId="2" duration="0:0:0.4" offset="-2,0" />
                <Keyframe frameId="1" duration="0:0:0.5" offset="-5,0" />
            </Keyframes>
        </Animation>
        <Animation name="walk right" >
            <Keyframes>
                <Keyframe frameId="5" duration="0:0:0.5" offset="5,0" />
                <Keyframe frameId="6" duration="0:0:0.5" offset="5,0" />
                <Keyframe frameId="2" duration="0:0:0.4" offset="2,0" />
                <Keyframe frameId="6" duration="0:0:0.5" offset="5,0" />
            </Keyframes>
        </Animation>
    </Animations>
</SpriteSheet>

通过这种方式,您可以跨动画重用帧(从而进一步优化位图大小(,并通过简单地编辑 XML 文件来自定义动画。

您所要做的就是读取XML文件,读取位图,并在启动动画时:启动一个定期滴答作响的计时器。当它滴答作响时,您可以通过逐个添加关键帧的持续时间并在总和大于刻度时间时停止来计算动画中的正确关键帧;应使用当前关键帧。

上面的XML文件中,我添加了诸如偏移之类的内容,该偏移允许您在动画过程中修改精灵的位置(您甚至可以插入它,使其平滑移动(

剩下的就是从位图中抓取正确的帧。作为优化,您可以在加载 XML 文件时通过抓取帧、将其保留为小位图并丢弃大位图来预处理位图。当位图很大且未完全被帧覆盖时,这可能会优化内存。

在其他情况下,您不会进行预处理,而只是将帧块传输。

对于较大的应用程序(更多位图/动画/帧(,我建议创建一个应用程序来创建和编辑XML文件。另一种选择可能是为您最喜欢的绘画程序创建一个插件(如果可能的话(