如何将游戏的逐帧动画压缩到磁盘上的最少数量


19

我开发了一个类似帝国时代(地图上的建筑物)的游戏,对于每座建筑物,我都有一个动画精灵表。我正在使用逐帧动画为建筑物设置动画(无论如何都不知道任何其他方法)。我注意到由于放入其中的图像,资源文件夹变得非常大。

CoC和《帝国时代》等游戏如何将apk大小保持在50 Mg以下?我是否在游戏开发方面缺少一些东西?

谢谢

编辑:更多信息到我面临的问题

我有很多动画可绘制对象。我之所以选择这种方式,是因为它是最快的,并且正在产生我想要的结果。基本上,每个建筑物都是一个动画可绘制对象,其中的xml文件引用了8个可绘制对象(8个图像= 8个文件)。由于透明性,所有这些都是PNG。由于我有200多个图像,因此apk大小为120 MB(并且还没有完成一半文件的复制)。这就是提示,必须有一种解决方法。请协助其他开发人员


您可能正在寻找压缩图像或将游戏内容与APK分离的方法。
亚诺什Turánszki

你是说扩展文件?扩展文件没有不同密度可绘制文件夹的问题。这是游戏吗?我正在做逐帧动画(完整的建筑物图像)。还是我完全走错路了?
Snake

为了以防万一,我试图提供帮助,并提出一个与节省图像空间有关的答案。但是,您的问题令人困惑:尚不清楚您是否真的想知道与“ CoC和Age of Empires之类的游戏如何将apk大小保持在50 Mg以下”相关的技术。或者,如果您只是想检查是否有较少的磁盘空间饥饿动画(如您的标题所示)。请澄清,这样的话,我可以删除答案,这样您就可以获得更准确的答案。
MAnd

@MAnd我编辑了答案以进一步思考问题
Snake

2
对于《帝国时代》,这可能是低分辨率(IIRC设计为640x480)和索引图像(不是全RGB)的组合。
user253751

Answers:


24

您的问题尚不清楚,您是否真的想知道即使有大量沉重的图像/资源文件时游戏也可以节省磁盘空间的技术(这就是问题的实质),还是您只是想知道是否为建筑物制作动画的磁盘空间不足的方式更少(这就是问题标题所隐含的含义)。

因此,我将把这个答案放在这里,以在您有大量图像时为节省空间提供帮助。如果您只想了解可以节省磁盘空间的动画技术,请告诉我,然后我可能会删除答案。


也就是说,在类似的情况下,就节省磁盘空间而言,我已经看到(并且曾经使用过)两个解决方案:

1)将单个图像连接到一个图像中。有时可能会有帮助。因此,我没有为以下每个彩色正方形保存4个单独的文件,而是将所有它们并排保存在同一张图片中(并且只会通过游戏代码拆分它们):

在此处输入图片说明

在此示例中,将每个文件保存在4个不同的PNG文件中总计为1255字节,而所有串联的单个文件为451字节。当然,它的帮助程度视具体情况而定,您应该进行测试以查看它是否对您有所帮助,具体取决于您的图像。

2)压缩资源文件夹。这通常对节省磁盘空间很有帮助。然后,当游戏运行时,您可以从压缩文件中解压缩或提取所需的图像-取决于您使用的压缩格式。请参阅过去的答案,该答案成为该网站的Wiki:https : //gamedev.stackexchange.com/a/37649/72423

但也要记住,根据您使用的图像文件类型每种压缩类型或多或少都有优势避免资源的双重压缩

有关压缩的更多详细信息:图像压缩的最新技术?


最后,您可能还想考虑在每种情况下使用哪种类型的图像:哪种图像格式的存储效率更高:PNG,JPEG或GIF?


感谢您的信息。奇怪的是,您能够通过将内容放到一个文件中来将文件大小减小一半。我以为最终,像素数量和所用空间相同。我修改了问题以获得更好的答案
Snake

@Snake因此,根据您所做的编辑,我认为我的回答确实很有帮助。串联图像+压缩可能会大大减小文件夹的大小。两种技术通常在某些类型的游戏中使用。关于串联,这始终是一个令人惊讶的技巧。自己尝试:将您的一个动画序列中的图像并排放置,并将最终大小与单个图像的总和进行比较。然后,您可以查看是否对您有帮助。至于压缩,对于PNG来说效果似乎不太好,但是仍然值得努力减少最终文件夹的大小
MAndy

@蛇,但:有时连接不值得甚至增加一点点最终大小。但通常它可以实现理想的减少效果。这一切都取决于您的图片
MAnd

我记得尝试过两种技术,减少量不到10%。我当然知道压缩与PNG无关紧要,但是我将尝试串联。这就是为什么我问其他游戏怎么做的原因,因为显然他们拥有比我更多的图形
Snake 2015年

您应该无法压缩包含图像的文件夹。图像应该已经被压缩,并且应该没有太多可重复的序列。如果他们这样做,那么额外的压缩层将成为图像编解码器的一部分...
corsiKa 2015年

9

我建议您尝试TexturePacker

  • 您只需拖放所有图像并将其打包
  • 您可以应用不同的压缩方式-例如,使用索引PNG消耗更少的内存-与标准PNG文件相比,最多减少70%
  • 您可以创建一个文件数据文件,其中包含每个建筑物的名称和位置
  • 免费版本可能已经足够为您创建精灵表了

您是否使用AndEngine,Cocos2d-x或LibGdx之类的游戏开发框架?=>无

您是否需要同时加载所有图像?听起来您会在目标设备上遇到大量RAM问题。


更新:Snake给我发送了一些图像。正如承诺的那样,它们不会在这里公开,因此我自己创建了一些艺术作品来演示如何减少内存使用。

在原始图像中,只有一部分图像在移动。我在房子上放了一只鸟来证明这一点:

在此处输入图片说明

基本上将整个动画打包到一张纸中会浪费大量内存。您应该拆分静态和动态部分:

静态的:

在此处输入图片说明

Anim01:

在此处输入图片说明

Anim02:

在此处输入图片说明

保持鸟类在图像中的原始位置。这就是为什么上面如此空旷的空间。您需要此来对齐动画。

现在将图像拖到TexturePacker上并选择以下参数

  • 数据格式:JSON哈希(如果需要,则为XML)
  • TrimMode:Trim(创建矩形)
  • 像素格式:INDEXED 8bit-创建8bit PNG(内存减少约70%)
  • 允许旋转:假
  • 输入数据的文件名

打包图像的TexturePacker

结果是您现在得到2个文件:Sprite表和JSON描述文件。

"house_anim_01.png":
{
    "frame": {"x":351,"y":246,"w":110,"h":79},
    "rotated": false,
    "trimmed": true,
    "spriteSourceSize": {"x":67,"y":8,"w":110,"h":79},
    "sourceSize": {"w":400,"h":400},
    "pivot": {"x":0.5,"y":0.5}
},

重要的部分是framespriteSourceSize

框架可让您在Sprite工作表中找到原始Sprite的位置。

spriteSourceSize为您提供绘制图像的偏移量-由于修整而遗漏的图像部分:

一个简单的伪代码绘制例程如下所示:

drawImage(spritename, posX, posX)
{
    data    = sheetData[spritename]
    offsetX = data.spriteSourceSize.x
    offsetY = data.spriteSourceSize.y
    frameX  = data.frame.x
    frameY  = data.frame.y
    width   = data.frame.w
    height  = data.frame.h
    screen.draw(sheetImage, posX+offsetX, posY+offsetY, width, height)
}

您可能必须根据图形系统中的枢轴点/原点调整偏移量计算。上面的例程假设一个坐标系的原点位于左上方。

然后只需两步绘制房子:

draw("background", 100, 100);
draw("anim_01", 100, 100);

您不必担心偏移量-因为图像已经对齐。


+1被其他人忽略的关于RAM使用的观察
Dan Hulme

@Andreas我会检查一下。谢谢。不要嘲笑我,但我没有使用引擎。它主要是通过动画和可绘制对象完成的,并且就像一种魅力一样工作。我不会将所有图像加载到内存中,否则它将崩溃。它只是加载当前需要显示的图像。.您认为以上建议适用于标准Android SDK吗?

1
是的,它会。TexturePacker有2种修剪精灵的模式:矩形和多边形。如果使用等轴测图,则在填充方面,多边形网格可能会带来很大的优势。问题是您是否能够绘制带纹理的三角形-或带有蒙版的矩形。如果不是这种情况,您仍然可以使用矩形。如果想使用Dropbox,可以向我发送一些图像,并在codeandweb上发送指向-> support的链接。com。我不会分享它们-只想看看我们可以做些什么来改善包装。
AndreasLöw,2015年

@AndreasLöw对不起,我没有收到您评论的通知。我刚刚看到了 我将非常感谢您的帮助。我会寄给您一些东西,也许您可​​以阐明我该怎么做。..kinda陷入我经验不多的事情中,也许您可​​以了解一下。我会尽快与您联系
Snake 2015年

7

这是您可以使用的一些指针

  1. 尝试确保您所有的背景图像和非透明图像都不为PNG格式
  2. 尝试使所有动画都可以循环播放,即,如果动画为1,2,3,4,5,6,请尝试使其像1,2,3,4,3,2,1,其中这些数字是动画的帧数,这很有帮助
  3. 如果许多图像相同并且只有颜色不同(通常是UI按钮,m粒子动画,游戏币),则尝试拍摄一张白色图像并动态更改其颜色
  4. 尝试仅使用非常重要的图像制作.apk,然后从服务器加载所有内容并保存在手机内存中

我希望这些指针对您有所帮助

PS:我只是给出笼统的想法,因为如果这些指针没有用,我不知道您的确切游戏内容和歉意


您还可以:1)压缩所有图像2)尽可能频繁地使用图块3)将图像混合起来以获得更大的图像,并将其用作用于纹理化的uv图
Anthony Raimondo

这些都是很棒的建议。谢谢。我认为最重要的一点是4。但是,如果那样的话,我该如何将它们放在不同的drawable文件夹中并像R.drawable.image1一样引用它们?那就是我感到困惑的地方
Snake

4

许多游戏都不会将其图形资源保留在.apk中;它们仅包含UI图形和游戏代码之类的“基础知识”,并在安装游戏后下载其余资产。对于根据显示分辨率使用不同图形资源的游戏来说,尤其如此,以防止.apk必须同时包含低分辨率和高分辨率资源。

您应该查看其他回答者提供的优化选项,以及最终是否必须与.apk本身分开提供游戏图形。


我从服务器(甚至扩展文件)获取图形没有问题,但是如何将它们放在drawable文件夹中,这样我就可以通过R.drawable.x来引用它们了,因为我的大多数(很多)xml都是使用R来引用它们的.drawable
Snake,

AFAIK,您不能。一种解决方法是保留链接到资源ID的资源文件名的哈希表,并使用AssetManager基于这些ID捕获文件,但是如果采用这种方法,则可能必须重新处理.xml文件。
Sandalfoot

4

我来到此网站时正在寻找类似的问题,确实在您的问题的答案和其他问题中都有一些不错的资源。

您可能应该看一下2D动画:带有动画帧的动画3D模型或精灵?对于不同类型的动画进行一些辩论。它帮助我优化了游戏。另外,您不会告诉我们您使用的是哪个API或使用的是哪个引擎。仅此一项就可以带来很大的改变:Android逐帧PNG动画

除此之外,请记住,如果您要进行压缩,压缩方式之间可能会有重要的区别。具体而言,压缩类型之间有很多差异,并且对于什么是最适合移动设备的路由存在一些专门的争论。特别是,如果考虑到移动设备,则RAM的使用和CPU浪费的加载也至关重要。参见:http : //www.gamasutra.com/blogs/AlexandruVoica/20130419/190833/Why_efficiency_is_key_in_texture_compression_standards_for_mobile_graphics.php?print=1


谢谢Bennton,我实际上是游戏开发的新手。我开发了许多基于工具/生产力的应用程序。但是没有游戏。所以我正在做我的第一场比赛,而我没有使用引擎。我只使用AnimationDrawables,所以效果很好。这只是apk的大小已失控
Snake 2015年

本顿,您建议的最后一个链接特别有趣。非常感谢分享!确保您看了我回答中的最后一个,它也涉及到不同文件类型的不同压缩问题。实际上,似乎有些压缩类型与已压缩的图像类型(例如PNG)或更有效地与未压缩的图像类型一起工作。针对每种情况进行实验始终是检查哪种情况最适合每种情况的最佳方法。
MAnd
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.