首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用可变的帧大小动态地将精灵工作表切割成单独的位图

使用可变的帧大小动态地将精灵工作表切割成单独的位图
EN

Stack Overflow用户
提问于 2013-11-10 02:43:49
回答 2查看 4.9K关注 0票数 1

我想创建一个cookie-cutter类型的类,它接受一个源矩形,并动态地遍历sprite工作表中的每个帧,直到每个图像都被剪切出来用于动画。我可以做到这一点没有问题,当每个帧大小是相同的精灵工作表,但它几乎不可能找到任何复杂的动画,具有相同的帧大小。例如:

就像我想要的那样得到剪切和动画,但是:

由于它的帧大小可变,所以被剪切得很滑稽(因为我的程序目前假设所有帧的大小都相同)。在某种程度上,有没有办法检测精灵工作表中每个单独帧的帧大小,或者这是一个失败的原因?

创建"cookie cutter“源帧的当前代码:

代码语言:javascript
复制
// Indirect Variable Sets (Sprite Animation and Sprite Sheet Cuts)
    framesPerRow = frameCount/spriteSheetRows;
    spriteWidth = bmp.getWidth() / framesPerRow;    // cut the sheet into pieces based on 
                                                    // sprite width: frames/row ratio
    spriteHeight = bmp.getHeight()/spriteSheetRows; // cut the sheet horizontally into pieces based on
                                                    // total height : total rows ratio

    setSourceRect(new Rect(0, 0, spriteWidth, spriteHeight));
    setFramePeriod(1000 / fps);                     // set the framePeriod based on desired fps

然后在我的update方法中使用它:

代码语言:javascript
复制
public void update(long gameTimeInMillis){
    // If the game time has been longer than the frame period...
    // the reason that we need frameTicker is so that we can use our variable (frameTicker)
    // to keep track of the last time that the frame was updated (relative to our game)
    if (gameTimeInMillis > frameTicker + framePeriod){
        frameTicker = gameTimeInMillis;             // set last update time (current time)
        // increment the animation frame
        currentFrame++;

        // Get current column in sprite sheet:
        // this works like this, imagine we are at frame 20, and we have 5 frames per row
        // 20%5 = 0 so we are at the end of the row, if we are at frame 22, 22%5 = 2, etc.
        frameColumn = currentFrame%framesPerRow;

        // if we are at our max frame count (note, we start at 0) then reset our animation
        if(currentFrame >= frameCount){ 
            currentFrame = 0;                   
        }

        // increment the sprite sheet row if we are at the end of the row
        if(frameColumn == 0){
            currentRow++;
        }

        // if we are at our max rows (note, we start at 0) then reset our animation rows
        if(currentRow >= spriteSheetRows){
            currentRow = 0;
        }

        // define the "cookie cutter" sourceRectangle for our sprite sheet
        this.sourceRect.left = frameColumn * spriteWidth;
        this.sourceRect.right = this.sourceRect.left + spriteWidth;
        this.sourceRect.top = currentRow * spriteHeight;
        this.sourceRect.bottom = this.sourceRect.top + spriteHeight;
        Log.d(TAG, "Top coordinates = " + currentRow);
    }
}

因为我不是艺术家,所以我的目标是使用预先渲染的精灵工作表,这样我就可以在2D动画环境中提高我的技能。问题是,我发现的大多数精灵工作表似乎都有可变的边框,这使得它们对我来说相当无用,除非我能找到一种方法来更精确地剪切它们(或者是另一种剪切方法,有没有我遗漏的API工具?)

EN

Stack Overflow用户

发布于 2014-02-16 10:37:57

您可以在sprite工作表中添加一些元数据,以定义工作表中每个帧的像素位置和宽度/高度。这比拥有一个完美的网格需要更多的工作,但它将使您能够按原样使用更多种类的精灵表单。例如(不缩放)如果你去抓取第1帧,你会发现它是从像素位置128开始的16x32,你可以根据整个页面的宽度/高度来计算纹理坐标。这听起来很混乱,但是一旦你让它工作,它应该会给你更多的灵活性,并且可以在各种精灵工作表上重用。

否则,您可以使用Gimp将单个帧剪切并粘贴到网格上。或者,将帧剪切成具有相同宽度/高度的单独图像,然后使用类似ImageMagick的东西将这些单独图像组装成一个精灵工作表。我不记得实际的命令,但我从命令行使用ImageMagick将一些Reiner's Tileset组装成精灵工作表。ImageMagick将连接一个目录中的所有图像,你甚至可以告诉它为你调整它们的大小,这样你就可以从更高分辨率的图像开始,如果需要的话,强制它们成为2的幂。

票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19881635

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档