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

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

由于它的帧大小可变,所以被剪切得很滑稽(因为我的程序目前假设所有帧的大小都相同)。在某种程度上,有没有办法检测精灵工作表中每个单独帧的帧大小,或者这是一个失败的原因?
创建"cookie cutter“源帧的当前代码:
// 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方法中使用它:
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工具?)
发布于 2014-02-16 10:37:57
您可以在sprite工作表中添加一些元数据,以定义工作表中每个帧的像素位置和宽度/高度。这比拥有一个完美的网格需要更多的工作,但它将使您能够按原样使用更多种类的精灵表单。例如(不缩放)如果你去抓取第1帧,你会发现它是从像素位置128开始的16x32,你可以根据整个页面的宽度/高度来计算纹理坐标。这听起来很混乱,但是一旦你让它工作,它应该会给你更多的灵活性,并且可以在各种精灵工作表上重用。
否则,您可以使用Gimp将单个帧剪切并粘贴到网格上。或者,将帧剪切成具有相同宽度/高度的单独图像,然后使用类似ImageMagick的东西将这些单独图像组装成一个精灵工作表。我不记得实际的命令,但我从命令行使用ImageMagick将一些Reiner's Tileset组装成精灵工作表。ImageMagick将连接一个目录中的所有图像,你甚至可以告诉它为你调整它们的大小,这样你就可以从更高分辨率的图像开始,如果需要的话,强制它们成为2的幂。
发布于 2016-03-19 05:57:51
您可以将sprites存储为Rect数组。(说真的,您不希望将它们存储在2D数组中。)
Rect[] frames = new Rect[TOTAL_NUMBER_OF_FRAMES];现在,计算机没有办法知道如何裁剪你的床单。最简单的方法可能是创建一个如下所示的文本文件:
x,y,width,height
x,y,width,height
x,y,width,height这将允许您使用具有不同宽度和高度的奇怪的spritesheet。这也意味着你可以在没有精灵的情况下使用图片的部分(比如当你不想使用的每个帧周围有边框的时候)。使用文件IO将它们放入阵列中。(请注意,您可能希望将BitMapFactory选项设置为不缩放位图)。
您可以使用以下命令绘制第n帧:
canvas.drawBitmap(bmp, frames[n],
new RectF(x, y, x + frames[n].width(), y + frames[n].height()),
paint);https://stackoverflow.com/questions/19881635
复制相似问题