Oyun karesinde kare animasyonu diskte minimum düzeye nasıl sıkıştırılır


19

Age of empire (haritada binalar) gibi bir oyun geliştiriyorum ve her bina için animasyonu için bir sprite sayfam var. Binayı canlandırmak için kare kare animasyon kullanıyorum (yine de başka bir yöntemin farkında değilim). İçine koyduğum görüntüler nedeniyle kaynaklar klasörümün aşırı derecede genişlediğini fark ediyorum.

CoC ve Age of Empires gibi oyunlar apk boyutlarını 50 Mg'nin altında nasıl tutar? Oyun geliştirme söz konusu olduğunda burada bir şey mi eksik?

teşekkür ederim

EDIT: Karşılaştığım soruna ilişkin daha fazla bilgi

Animasyonlar çizilebilir nesneleri bir sürü var. Bu yolu seçtim çünkü en hızlı ve istediğim sonuçları elde ediyordum. Temelde her bina, xml dosyasının 8 çekilebilir (8 resim = 8 dosya) olduğu bir çizilebilir animasyondur. Hepsi saydamlık nedeniyle PNG'dir. 200'den fazla resimim olduğu için, apk boyutu 120 MB (Ve henüz dosyaların yarısını kopyalamıyorum). İşte bu kadar çabuk, bunu çözmenin bir yolu olmalı. Lütfen diğer bir geliştiriciye yardımcı olun


Görüntüleri sıkıştırmak veya oyun içeriğini apk'den ayırmak aradığınız şey olabilir.
János Turánszki

Genişletme dosyaları mı demek istiyorsun? Genişletme dosyalarının farklı yoğunlukta çekilebilir klasörlere sahip olmaması sorunu. Oyunların yaptığı bu mu? Kare kare animasyon (tam bina görüntüsü) yapıyorum. Yoksa ben tamamen yanlış yolda mıyım
Snake

Her ihtimale karşı, yardım etmeye çalıştım ve resimleriniz için yer tasarrufu ile ilgili bir cevap verdim. Ancak, sorunuz kafa karıştırıcı: "CoC ve Age of Empires gibi oyunlar apk boyutlarını 50 Mg'nin altında nasıl tutuyor?" ya da sadece daha az disk alanı aç animasyon yolu olup olmadığını kontrol etmek istiyorsanız (başlığınızın önerdiği gibi). Lütfen açıklığa kavuşturun, böylece durum buysa cevabımı silebilirim ve böylece daha doğru yanıtlar alabilirsiniz.
MAnd

@Sonraki sorunu daha da derinlemesine düşünmek için cevabımı düzenledim
Snake

2
Age of Empires için muhtemelen düşük çözünürlüklü (640x480 için tasarlanan IIRC) ve indekslenmiş görüntülerin (tam RGB değil) birleşimidir.
user253751

Yanıtlar:


24

Büyük miktarda ağır görüntü / kaynak dosyası olsa bile (sorunun gövdesinde olan şey) bile oyunların disk alanından tasarruf etmesine izin veren teknikleri bilmek istiyorsanız ya da sadece binalarınız için animasyon yapmanın daha az disk alanı aç yolu vardır (sorunuzun başlığıyla ima edilen budur).

Bu yüzden, bu cevabı buraya çok fazla görüntünüz olduğunda yer tasarrufu konusunda yardımcı olmaya çalışacağım. Yalnızca disk alanından tasarruf etmenizi sağlayacak animasyon teknikleri hakkında bilgi edinmek istiyorsanız, lütfen bana bildirin, ardından cevabı silebilirim.


Benzer bir durumda, diskte yer tasarrufu açısından gördüğüm (ve bir kez kullandığım) iki çözüm şöyle dedi:

1) görüntüleri tek bir görüntü içinde birleştirmek. Bazen yardımcı olabilir. Bu nedenle, aşağıdaki renkli karelerin her biri için 4 ayrı dosya kaydetmek yerine, hepsini aynı görüntüde yan yana kaydediyorum (ve yalnızca oyun kodu ile bölerim):

resim açıklamasını buraya girin

Bu örnekte, her birini 4 farklı PNG dosyasında kaydetmek 1255 bayta karşılık gelirken, hepsi birleştirilen tek dosya 451 bayttır. Tabii ki, ne kadar yardımcı olabileceği duruma göre değişir ve resimlerinize bağlı olarak bunun size yardımcı olup olamayacağını test etmelisiniz.

2) Kaynaklar klasörünü sıkıştırmak. Bu genellikle disk alanından tasarruf etmek için çok yararlı olabilir. Daha sonra oyun çalışırken, kullandığınız sıkıştırma formatına bağlı olarak sıkıştırılmış dosyadan istediğiniz görüntüyü açar veya açarsınız. Bu sitenin bir wiki'si haline gelen bu geçmiş yanıtı görün: /gamedev//a/37649/72423

Ancak , kullandığınız görüntü dosyası türüne bağlı olarak her sıkıştırma türünün az ya da çok avantajlı olabileceğini unutmayın : Kaynakların iki kez sıkıştırılmasından kaçının

Sıkıştırma hakkında daha fazla bilgi için: Görüntü sıkıştırmada son teknoloji mi?


Son olarak, her durum için hangi görüntü türlerini kullanacağınızı düşünmek de ilginizi çekebilir: Hangi görüntü formatı bellekte daha verimlidir: PNG, JPEG veya GIF?


Bilgi için teşekkürler. Bir dosyaya bir şeyler koyarak dosya boyutunu yarıya indirebilmeniz garip. Günün sonunda, aynı piksel sayısı ve kullanılan alan olduğunu düşündüm. Daha iyi cevap için sorumu düzenledim
Snake

@Snake Yani, yaptığınız düzenlemeye göre, cevabım gerçekten yardımcı olabilir. Görüntüleri birleştirme + sıkıştırma, klasör boyutunuzu büyük miktarda azaltabilir. Her iki teknik de bazı oyun türlerinde düzenli olarak kullanılmaktadır. Birleştirme hakkında, bu her zaman şaşırtıcı bir numaradır. Kendiniz deneyin: Bir animasyon dizinizdeki görüntüleri yan yana koyun ve son boyutu tek tek görüntülerin toplamıyla karşılaştırın. O zaman bunun davanıza yardımcı olup olmadığını görebilirsiniz. Sıkıştırma gelince,
PNG'ler

@Yılan bir gözlem olsa da: birleştirmek bazen son boyutu biraz arttırmaz veya hatta arttırmaz. Ancak çoğu zaman arzu edilen bir azalma sağlayabilir. Her şey görüntülerinize bağlı
21'de

Her iki tekniği de denediğimi hatırlıyorum ve azalma% 10'dan azdı. Sıkıştırma PNG ile önemli değil biliyorum ama birleştirme çalışacağız. Bu yüzden diğer oyunların nasıl yaptıklarını sordum çünkü açıkçası benimkinden daha fazla grafik var
Snake

Görüntülerle dolu bir klasörü sıkıştıramamanız gerekir. Görüntüler zaten sıkıştırılmış olmalı ve tekrarlanabilir çok fazla diziye sahip olmamalıdır. Eğer
öyleyse

9

TexturePacker'ı denemenizi öneririm

  • tüm resimlerinizi sürükleyip bırakabilir ve paketleyebilirsiniz
  • farklı sıkıştırma uygulayabilirsiniz (örneğin, daha az bellek tüketen dizine alınmış PNG'ler kullanın - standart bir PNG dosyasına kıyasla% 70'e kadar daha az)
  • binalarınızın her birinin adını + konumunu içeren bir dosya veri dosyaları oluşturabilirsiniz
  • ücretsiz sürüm sizin için sprite sayfalarını oluşturmak için zaten yeterli olabilir

AndEngine, Cocos2d-x veya LibGdx gibi bir oyun geliştirme çerçevesi kullanıyor musunuz? => Yok

Tüm resimlerinizin aynı anda yüklenmesine mi ihtiyacınız var? Hedef cihazlarda büyük RAM sorunlarıyla karşılaşacağınız anlaşılıyor.


Güncelleme: Snake bana bazı görüntüler gönderdi. Söz verildiği gibi onları burada halka açmayacak, bu yüzden bellek kullanımını nasıl azaltacağımı göstermek için kendim bir sanat yarattım.

Orijinal görüntüde görüntünün yalnızca bir kısmı hareket ediyordu. Bunu göstermek için bir eve bir kuş yerleştirdim:

resim açıklamasını buraya girin

Temel olarak tüm animasyonu bir kağıda paketlemek büyük bir hafıza kaybıdır. Statik ve hareketli parçaları bölmelisiniz:

Statik:

resim açıklamasını buraya girin

Anim01:

resim açıklamasını buraya girin

Anim02:

resim açıklamasını buraya girin

Görüntülerdeki kuşun orijinal konumunu koruyun . Bu yüzden yukarıda mich boş alanı var. Animasyonu hizalamak için buna ihtiyacınız var.

Şimdi görüntüleri TexturePacker'a sürükleyin ve aşağıdaki parametreleri seçin

  • Veri biçimi: JSON karması (veya isterseniz XML)
  • TrimMode: Trim (bu dikdörtgenler oluşturur)
  • Piksel biçimi: INDEXED 8bit - 8 bit PNG'ler oluşturmak için (yaklaşık% 70 daha az bellek)
  • Döndürmeye İzin Ver: yanlış
  • Veriler için bir dosya adı girin

ImagesPacker görüntüleri paketleme

Sonuçta artık 2 dosya elde edersiniz: hareketli grafik sayfası ve bir JSON açıklama dosyası.

"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}
},

Önemli parçalar frame ve spriteSourceSize'dir .

Çerçeve size sprite sayfasında orijinal sprite yerini verir.

spriteSourceSize görüntüyü çizmek için ofseti verir - görüntünün kırpma nedeniyle dışarıda bırakılan parçaları:

Basit bir sözde kod çizim rutini şuna benzer:

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

Ofset hesaplamasını, grafik sisteminizdeki pivot noktasına / orijinine bağlı olarak ayarlamanız gerekebilir. Yukarıdaki rutin, menşei sol üstte olan bir koordinat sistemini varsayar.

Sonra evi 2 geçişte çizin:

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

Ofsetleri önemsemeniz gerekmez - görüntüler zaten hizalanmış.


Diğer kullanıcıların görmezden geldiği RAM kullanımı ile ilgili gözlem için +1
Dan Hulme

@Andreas bunu kontrol edeceğim. Teşekkür ederim. Bana gülme ama motor kullanmıyorum. Çoğunlukla animasyon ve çekmecelerle yapılır ve bir cazibe gibi çalışır. Hafızadaki tüm görüntüleri yüklemiyorum, başka hiçbir şey çökmeyecek. Sadece şu anda görüntülenmesi için gerekli görüntüleri yüklüyor .. Yukarıdaki önerinin standart Android SDK ile çalışacağını düşünüyor musunuz?
Yılan

1
Evet olacak. TexturePacker, spriteları düzeltmek için 2 moda sahiptir: Dikdörtgenler ve çokgenler. İzometrik görüntüler kullanırsanız, ambalajlama açısından çokgen kafeslerden büyük bir avantaj elde edebilirsiniz. Soru, dokulu üçgenler veya maske ile dikdörtgen çizip çizemeyeceğinizdir. Eğer durum böyle değilse, yine de dikdörtgenleri kullanabilirsiniz. Dropbox kullanmak ve codeandweb'de -> support'a bir bağlantı göndermek isterseniz bana bazı resimlerinizi gönderebilirsiniz. com.tr Onları paylaşmayacağım - sadece ambalajı geliştirmek için neler yapabileceğimizi görmekle ilgileniyorum.
Andreas Löw

@ AndreasLöw Çok üzgünüm, yorumunuz hakkında bildirim alamadım. Az önce gördüm. Yardımı çok takdir edeceğim. Sana bir şey göndereceğim ve belki de neye ihtiyacım olduğuna ışık tutabilirsin. ..kinda içinde ufak bir tecrübem var ve belki de ışık tutabilirsin. Yakında sizinle iletişime geçeceğim
Yılan

7

İşte kullanabileceğiniz birkaç işaretçi

  1. Tüm Arka Plan ve saydam olmayan resimlerinizin PNG biçiminde olmadığından emin olun
  2. Tüm animasyon döngülerini elde etmeye çalışın, yani animasyon 1,2,3,4,5,6 ise, bu sayıların animasyonun kare sayısı olduğu 1,2,3,4,3,2,1 gibi yapmaya çalışın, çok yardımcı olur
  3. Birçok görüntü aynı ve sadece renk farklıysa (genellikle UI düğmeleri, m parçacık animasyonları, oyun paraları) bir Beyaz görüntü çekmeye ve rengini dinamik olarak değiştirmeye çalışın
  4. .Apk'nizi yalnızca son derece önemli olan görüntülerle yapmaya çalışın ve ardından her şeyi bir sunucudan yükleyin ve telefon belleğinde tutun

Umarım bu işaretçiler yardımcı olur

PS Bu işaretçiler yararlı değilse tam oyun içeriğinizin ve özürünüzün farkında olmadığım için sadece genel bir fikir veriyorum


Ayrıca şunları da yapabilirsiniz: 1) tüm resimlerinizi sıkıştırın 2) mümkün olduğunca sık fayans kullanın 3) daha büyük bir resme birleştirerek görüntüleri birleştirin ve bunu tekstüre için uv haritası olarak kullanın
Anthony Raimondo

Bunlar harika öneriler. Teşekkür ederim. Bence en önemli nokta 4'tür. Ancak bu durumda nasıl farklı çekilebilir klasörlere koyabilir ve R.drawable.image1 gibi onlara nasıl başvurabilirim? İşte kafam karıştı
Yılan

4

Birçok oyun grafik varlıklarını .apk içinde tutmaz; yalnızca kullanıcı arayüzü grafikleri ve oyun kodu gibi "temel bilgileri" içerir ve oyun yüklendikten sonra öğelerin geri kalanını indirir. Bu özellikle .apk'nin hem düşük çözünürlüklü hem de yüksek çözünürlüklü varlıkları içermesi için ekranınızın çözünürlüğüne bağlı olarak farklı grafik kaynakları kullanan oyunlar için geçerlidir.

Hem diğer cevap verenler tarafından sağlanan optimizasyon seçeneklerine hem de oyununuzun grafiklerini .apk'ın kendisinden ayrı olarak sunmanız gerekip gerekmediğine bakmalısınız.


Ben sunucu (veya hatta genişleme dosyaları) grafik alma sorunları var, ama nasıl R.drawable.x onları referans böylece onları çekilebilir klasöre koymak nasıl benim (çok) xmls çoğu R kullanarak atıfta .drawable
Yılan

AFAIK, yapamazsın. Çözümlerden biri, kaynak kimliklerine bağlı bir karma kaynak dosya adları tablosu tutmak ve AssetManager'ı kullanarak bu kimliklere dayalı dosyaları almaktır, ancak bu rotaya giderseniz .xml dosyalarınızı yeniden işlemeniz gerekebilir.
Sandalfoot

4

Bu siteye benzer bir soru aramaya geldim ve gerçekten hem sorunun yanıtı hem de diğer sorulara işaret eden birkaç iyi kaynak var.

Muhtemelen 2D animasyona bir göz atmalısınız : Animasyonlu 3D modeller veya animasyon kareli spritelar? farklı animasyon türleri hakkında bazı tartışmalar için. Oyunumu optimize etmeme yardımcı oldu. Ayrıca, hangi API'yı kullandığınızı veya hangi Motoru kullandığınızı söylemezsiniz. Tek başına bu oldukça fark yaratabilir: Android kare kare animasyon

Bunun yanı sıra, sıkıştırma yoluna giderseniz, sıkıştırma yönteminiz arasında önemli farklılıklar olabileceğini unutmayın. Özellikle, sıkıştırma türleri arasında oldukça az fark vardır ve mobil cihazlar için en uygun yolun ne olduğu konusunda bazı özel tartışmalar vardır. Özellikle mobil cihazlar için RAM kullanımının ve yükleme için CPU atıklarının da çok önemli olduğunu dikkate alırsanız. Bkz. Http://www.gamasutra.com/blogs/AlexandruVoica/20130419/190833/Why_efficiency_is_key_in_texture_compression_standards_for_mobile_graphics.php?print=1


Teşekkürler Bennton, aslında oyun geliştirmede yeniyim. Araç / üretkenlik tabanlı birçok uygulama geliştirdim. Ama oyunlarda hiçbiri. İlk oyunumu yapıyorum ve motor kullanmıyorum. Sadece AnimationDrawables kullanıyorum ve işler harika çalışıyor. Bu sadece apk boyutu kontrolden çıkıyor
Snake

Bennton, önerdiğiniz son bağlantı özellikle ilginç. Bunu paylaştığın için çok teşekkürler! Farklı dosya türleri için farklı sıkıştırma sorununa da değinen cevabımın sonuncusuna baktığınızdan emin olun. Aslında, PNG gibi sıkıştırılmış görüntü türleriyle daha iyi çalışan veya sıkıştırılmamış görüntü türleriyle daha iyi çalışan sıkıştırma türleri var gibi görünüyor. Her durum için deneme yapmak, her durum için neyin en iyi olduğunu kontrol etmenin her zaman en iyi yoludur.
mand
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.