如何创建精灵图像

时间:2012-05-04 15:30:07

标签: c# winforms image-processing

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

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

我将循环显示此图像10到100次,每次都将它放在前一个旁边的精灵上。

精灵限制在3000px宽。

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

4 个答案:

答案 0 :(得分:7)

以下MSDN文章中有关于2D精灵的大量信息:Rendering 2D sprites

这些示例基于Microsoft's 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%),最后您可以使用{{1} } 方法。它接受包含Draw类实例的参数,该实例是游戏时间状态的快照,以可由变步(实时)或固定步(游戏时间)游戏使用的值表示。

如果有帮助,请告诉我。

答案 1 :(得分:3)

让我试试一些伪代码

Bitmap originalImage; //  that is your image of 100x100 pixels
Bitmap bigImage; //  this is your 3000x3000 canvas
int xPut = 0;
int xPut = 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
}

答案 2 :(得分:2)

在3000处声明一个变量,如果你输入宽度为250的图片,那么请继续这样做,这也可以让你通过看到你的下一张图片确定是否有足够的空间用于下一张图片如果剩下的数字大于下一张图片的宽度。每次开始新行时,将变量设置回3k并重新开始。解决

答案 3 :(得分:2)

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

<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文件。另一种选择可能是为您喜欢的绘画程序创建一个插件(如果可能的话)