ゲームのフレームごとのアニメーションをディスク上で最小限に圧縮する方法


19

Age of empire(地図上の建物)のようなゲームを開発しています。すべての建物には、アニメーション用のスプライトシートがあります。私はフレームごとのアニメーションを使用して建物をアニメーション化します(とにかく他の方法は認識していません)。私が入れている画像のために、リソースフォルダーが非常に大きくなっていることに気付きました。

CoCやAge of Empiresなどのゲームは、apkサイズを50 Mg未満にどのように維持しますか?ゲーム開発に関して、ここで何かが欠けていますか

ありがとうございました

編集:私が直面している問題の詳細情報

たくさんのアニメーションドロウアブルオブジェクトがあります。私がこの方法を選んだのは、それが最も速く、希望する結果が得られたからです。基本的に、すべての建物は、そのxmlファイルが8つのドローアブルを参照するアニメーションドローアブルです(8つの画像= 8つのファイル)。透明性のため、それらはすべてPNGです。200を超える画像があるため、apkサイズは120 MBです(そして、ファイルの半分をまだコピーしていません)。それがプロンプトです。それを解決する方法が必要です。仲間の開発者を支援してください


画像の圧縮やapkからのゲームコンテンツの分離は、あなたが探しているものかもしれません。
ヤノストゥランシキ

拡張ファイルのことですか?拡張ファイルに異なる密度のドロアブルフォルダーがないという問題。これはゲームの機能ですか?私はフレームごとのアニメーション(建物全体の画像)をやっています。または、私は完全に間違った道
スネーク

念のため、画像のスペースを節約するために役立つ情報を提供しようとしました。ただし、あなたの質問は紛らわしいです。「CoCやAge of Empiresのようなゲームはどのようにapkサイズを50 Mg未満に保つのか」などのテクニックを本当に知りたいかどうかは明らかではありません。または、ディスクスペースに飢えたアニメーションの方法が少ないかどうかだけを確認したい場合(タイトルが示唆するように)。明確にしてください。そうであれば、答えを削除できます。また、より正確な答えを得ることができます。
マンド

私はさらに問題に反映させるために私の答えを編集した@MAnd
スネーク

2
Age of Empiresの場合、おそらく低解像度(640x480用に設計されたIIRC)とインデックス付き画像(フルRGBではない)の組み合わせです。
user253751

回答:


24

重い画像/リソースファイルが大量にある場合でもゲームがディスクスペースを節約できる技術を知りたいのか(質問の本文にあるのか)、または単に建物のアニメーションを実行するためのディスクスペースを空ける方法が少なくなります(これが質問のタイトルで暗示されています)。

したがって、多くの画像がある場合にスペースを節約することに関連して、この答えをここに入れます。あなたがディスクスペースを節約できるアニメーション技術について知りたいだけなら、私に知らせてください、そして、私は答えを削除するかもしれません。


とはいえ、同様の状況で、ディスク内のスペースを節約するという観点で私が見た(そして一度使った)2つのソリューションは次のとおりです。

1)同じ画像内の個々の画像を連結する。助けになることもあります。したがって、次の色付きの正方形ごとに4つの個別のファイルを保存する代わりに、同じ画像内にすべてを並べて保存します(ゲームコードを介してのみ分割します)。

ここに画像の説明を入力してください

この例では、4つの異なるPNGファイルにそれぞれを保存すると1255バイトになりますが、すべてを連結した単一のファイルは451バイトになります。もちろん、どれだけ役立つかはケースバイケースで異なりますので、画像によってはそれが役立つかどうかをテストする必要があります。

2)リソースフォルダーを圧縮します。多くの場合、これはディスク容量を節約するのに非常に役立ちます。次に、ゲームの実行中に、使用する圧縮形式に応じて、圧縮ファイルから目的のイメージを解凍またはプルします。このサイトのウィキとなった過去の回答をご覧くださいhttps : //gamedev.stackexchange.com/a/37649/72423

しかし、またことに注意して圧縮の各タイプが使用するイメージファイルの種類に応じて、多かれ少なかれ有利であり得るリソースのを避け、二重圧縮

圧縮の詳細について:画像圧縮の最新技術?


最後に、各状況で使用する画像の種類を考えることに興味があるかもしれません:どの画像形式がよりメモリ効率が良いか:PNG、JPEG、またはGIF?


情報ありがとうございました。1つのファイルに入れることでファイルサイズを半分にカットできたのは奇妙です。結局のところ、それは同じピクセル数と使用されているスペースだと思いました。私はより良い答えを私の質問を編集しました

@Snakeだから、あなたが行った編集ごとに、私は私の答えが実際に役立つと思います。画像を連結して圧縮すると、フォルダーのサイズが大幅に縮小する場合があります。両方の手法は、一部の種類のゲームで定期的に使用されています。連結については、常に驚くべきトリックです。自分で試してみてください:あなたの一連のアニメーションの画像を並べて配置し、最終的なサイズを個々の画像の合計と比較します。次に、それがあなたのケースに役立つかどうかを確認できます。圧縮については、PNG画像のためにはあまり効果的で、まだ最終的なフォルダのカットサイズに努力する価値である傾向がある
MAND

しかし、@ Snake 1つの観察:連結することは、時には最終的なサイズをわずかに増やす価値がなく、さらには増加させることさえあります。しかし、多くの場合、望ましい削減を実現できます。それはすべてあなたの画像に依存します
MAnd

両方のテクニックを試してみましたが、削減率は10%未満でした。PNGでは圧縮が問題にならないことは間違いありませんが、連結を試みます。明らかに、彼らは私より道より多くのグラフィックスを持っているので、私は他のゲームでそれを行う方法を尋ねた理由だという
スネーク

画像でいっぱいのフォルダーを圧縮することはできません。画像はすでに圧縮されている必要があり、繰り返し可能なシーケンスは多くないはずです。彼らがした場合は、圧縮の余分な層が...画像コーデックの一部である
corsiKa

9

TexturePackerを試すことを提案します

  • すべての画像をドラッグアンドドロップして、それらをパックすることができます
  • 異なる圧縮を適用することができます-例えば、より少ないメモリを消費するインデックス付きPNGを使用-標準のPNGファイルと比較して最大70%削減
  • 各建物の名前と位置を含むファイルデータファイルを作成できます。
  • 無料版は既にスプライトシートを作成するのに十分かもしれません

AndEngine、Cocos2d-x、LibGdxなどのゲーム開発フレームワークを使用していますか?=>なし

すべての画像を同時に読み込む必要がありますか?ターゲットデバイスで大規模なRAMの問題が発生するようです。


更新:Snakeから画像が送られてきました。約束されたようにここでは公開しませんので、メモリ使用量を削減する方法を示すために自分でアートを作成しました。

元の画像では、画像の一部のみが動いていました。これを実証するために家に鳥を置いた。

ここに画像の説明を入力してください

基本的に、アニメーション全体をシートにパックすることは、メモリの大きな浪費です。静的部分と可動部分を分割する必要があります。

静的:

ここに画像の説明を入力してください

Anim01:

ここに画像の説明を入力してください

Anim02:

ここに画像の説明を入力してください

画像内の鳥の元の位置を保持します。これが、上記のように空のスペースがある理由です。これは、アニメーションの位置合わせに必要です。

TexturePackerで画像をドラッグし、次のパラメーターを選択します

  • データ形式:JSONハッシュ(または必要に応じてXML)
  • TrimMode:トリム(これにより四角形が作成されます)
  • ピクセル形式:8ビットのINDEXED-8ビットのPNGを作成する(約70%少ないメモリ)
  • 回転を許可:false
  • データのファイル名を入力してください

TexturePackerによる画像のパッキング

結果として、スプライトシートとJSON記述ファイルの2つのファイルが得られます。

"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です。

フレームは、あなたのスプライトシートの元のスプライトの位置を示します。

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)
}

グラフィックシステムのピボットポイント/原点に応じて、オフセット計算を調整する必要がある場合があります。上記のルーチンは、原点が左上にある座標系を想定しています。

その後、単純に2つのパスで家を描きます。

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

画像はすでに整列されているため、オフセットを気にする必要はありません。


他の人が無視しているRAMの使用についての観察のための1
ダン・ハルム

@Andreas私はそれをチェックします。ありがとうございました。私を笑わないでください、しかし、私はエンジンを使用していません。ほとんどはアニメーションとドロウアブルで行われ、魅力のように機能します。メモリ内のすべての画像をロードするわけではありません。他の方法ではクラッシュしません。現時点で表示に必要な画像をロードするだけです。上記の提案は標準のAndroid SDKで機能すると思いますか?
スネーク

1
はい、そうです。TexturePackerには、スプライトをトリミングするための2つのモードがあります。長方形とポリゴンです。等尺性画像を使用する場合、パッキングに関してポリゴンメッシュから大きな利点を得ることができます。問題は、テクスチャ付きの三角形、またはマスク付きの長方形を描画できるかどうかです。そうでない場合でも、長方形を使用できます。dropboxを使用し、codeandwebで-> supportへのリンクを送信する場合は、いくつかの画像を送ってください。com。私はそれらを共有しません-梱包を改善するために何ができるかを見て興味があります。
アンドレアスレー

@AndreasLöwごめんなさい、コメントの通知が届きませんでした。見たばかりです。私は助けに非常に感謝します。私はあなたに何かを送ります。多分あなたは私がすべきことを明らかにすることができます。..ちょっと私がちょっとした経験で何かにこだわると、おそらくあなたは光を当てることができます。すぐにご連絡いたします
Snake

7

使用できるポインターはいくつかあります

  1. すべての背景画像と非透明画像がPNG形式ではないことを確認してください
  2. すべてのアニメーションをループ可能にするようにします。つまり、アニメーションが1,2,3,4,5,6の場合、これらの数字がアニメーションのフレーム番号である1,2,3,4,3,2,1のようにします。それは大いに役立ちます
  3. 多くの画像が同じで、色のみが異なる場合(通常はUIボタン、mパーティクルアニメーション、ゲームコイン)、1つの白い画像を取得し、その色を動的に変更しようとします
  4. 非常に重要な画像のみで.apkを作成し、サーバーからすべてをロードして電話のメモリに保存してください

これらのポインタが役立つことを願っています

PSこれらのポインターが役に立たない場合、私はあなたの正確なゲーム内容と謝罪を知らないので、一般化されたアイデアを与えるだけです


あなたはまた、次のことができます。テクスチャのためのUVマップとして拡大表示し、使用にtogetterしばしば3できるだけ1)圧縮、すべての画像2)使用タイル)をconcatinate画像その
アンソニー・ライモンド

これらは素晴らしい提案です。ありがとうございました。最も重要なポイントは4だと思います。しかし、その場合、それらを異なる描画可能フォルダーに入れてR.drawable.image1のように参照するにはどうすればよいですか?私は混乱していところです
スネーク

4

多くのゲームは、グラフィック資産を.apkに保持しません。UIグラフィックスやゲームコードなどの「基本」のみが含まれ、ゲームがインストールされると残りのアセットがダウンロードされます。これは、ディスプレイの解像度に応じて異なるグラフィックリソースを使用して、.apkに低解像度と高解像度の両方のアセットを含める必要がないようにするゲームに特に当てはまります。

他の回答者が提供する最適化オプションと、最終的に.apk自体とは別にゲームのグラフィックスを提供する必要があるかどうかを確認する必要があります。


サーバー(または拡張ファイル)からグラフィックを取得するのに問題はありませんが、R.drawable.xで参照できるように、それらを描画可能なフォルダーに配置するにはどうすればよいですか(ほとんどの) .drawable
Snake

知りません、できません。回避策の1つは、リソースIDにリンクされたリソースファイル名のハッシュテーブルを保持し、AssetManagerを使用してそれらのIDに基づいてファイルを取得することですが、この方法を使用する場合は.xmlファイルを再作成する必要があります。
サンダルフット

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


ありがとう、ベントン、私は実際にゲーム開発の初心者です。ツール/生産性ベースのアプリをたくさん開発しました。しかし、ゲームにはありません。だから私は最初のゲームをやっていて、エンジンを使っていません。私はAnimationDrawablesだけを使用していますが、うまく機能しています。それはAPKのサイズだけでは手に負えなくなっている

Bennton、あなたが提案した最後のリンクは特に興味深いです。それを共有してくれてありがとう!私の答えの最後の1つを必ず確認してください。これは、さまざまなファイルタイプのさまざまな圧縮の問題にも触れています。実際には、PNGのような既に圧縮された画像タイプで、または非圧縮の画像タイプでより良く機能する圧縮タイプがあるようです。それぞれのケースで実験することは、常に各状況に最適なものをチェックするための最良の方法です。
マンド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.