Jak skompresować grę klatka po klatce do minimum na dysku

19

Opracowuję grę, taką jak Age of Empire (budynki na mapie), a do każdego budynku mam arkusz duszka do jego animacji. Korzystam z animacji klatka po klatce, aby animować budynek (i tak nie znam żadnej innej metody). Zauważam, że mój folder zasobów staje się bardzo duży z powodu umieszczanych w nim obrazów.

W jaki sposób gry takie jak CoC i Age of Empires utrzymują rozmiar apk poniżej 50 Mg? Czy coś mi brakuje, jeśli chodzi o tworzenie gier?

Dziękuję Ci

EDYCJA: Więcej informacji na temat problemu, przed którym stoję

Mam dużo animowanych obiektów rysowanych. Wybrałem tę drogę, ponieważ była najszybsza i przynosiła oczekiwane rezultaty. Zasadniczo każdy budynek jest rysunkiem animacji, w którym jego plik xml odnosi się do 8 rysunków (8 obrazów = 8 plików). Wszystkie z nich są PNG ze względu na przejrzystość. Ponieważ mam ponad 200 obrazów, rozmiar pliku apk wynosi 120 MB (i nie skończyłem jeszcze kopiować połowy plików). Właśnie dlatego musi istnieć sposób na rozwiązanie tego problemu. Pomóż innym programistom

Wąż
źródło
Kompresowanie obrazów lub oddzielanie zawartości gry od aplikacji może być tym, czego szukasz.
János Turánszki
Masz na myśli pliki rozszerzeń? Problem polegający na tym, że pliki rozszerzeń nie mają folderów wysuwalnych o różnej gęstości. Czy to właśnie robią gry? Robię animację klatka po klatce (pełny obraz budynku). Czy też jestem całkowicie na złej drodze
Snake,
Na wszelki wypadek starałem się pomóc i udzielić odpowiedzi związanej z oszczędzaniem miejsca na zdjęcia. Jednak twoje pytanie jest mylące: nie jest jasne, czy naprawdę chcesz znać techniki takie jak „w jaki sposób gry takie jak CoC i Age of Empires utrzymują swój rozmiar pakietu poniżej 50 Mg?” lub jeśli chcesz po prostu sprawdzić, czy jest mniej sposobów na animację wymagających miejsca na dysku (jak sugeruje Twój tytuł). Wyjaśnij, abym mógł usunąć swoją odpowiedź, jeśli tak jest, a także aby uzyskać dokładniejsze odpowiedzi.
MA
@ I zredagowałem swoją odpowiedź, aby bardziej zastanowić się nad problemem
Snake,
2
W Age of Empires jest to prawdopodobnie połączenie niskiej rozdzielczości (IIRC zostało zaprojektowane dla 640x480) i obrazów indeksowanych (nie pełne RGB).
user253751,

Odpowiedzi:

24

Pytanie nie jest jasne, czy naprawdę chcesz znać techniki, które pozwalają grom zaoszczędzić miejsce na dysku, nawet jeśli masz duże ilości ciężkich plików graficznych / zasobów (to jest sedno pytania), czy też po prostu chcesz wiedzieć, czy istnieje mniej sposobów na animację budynków, które wymagają dużej ilości miejsca na dysku (tak sugeruje tytuł pytania).

Dlatego umieszczę tę odpowiedź tutaj, starając się pomóc w oszczędzaniu miejsca, gdy masz dużo zdjęć. Jeśli interesuje Cię tylko wiedza na temat technik animacji, które mogą pozwolić Ci zaoszczędzić miejsce na dysku, daj mi znać, a następnie mogę usunąć odpowiedź.


To powiedziawszy, w podobnej sytuacji dwa rozwiązania, które widziałem (i użyłem raz) pod względem oszczędzania miejsca na dysku, to:

1) w celu połączenia poszczególnych obrazów w ramach tego samego obrazu. Czasami może być pomocna. Zamiast zapisywać 4 oddzielne pliki dla każdego z następujących kolorowych kwadratów, zapisuję je wszystkie obok siebie na tym samym obrazie (i dzielę je tylko za pomocą kodu gry):

wprowadź opis zdjęcia tutaj

W tym przykładzie zapisanie każdego z 4 różnych plików PNG wynosi 1255 bajtów, a pojedynczy plik ze wszystkimi połączonymi plikami to 451 bajtów. Oczywiście, ile może to pomóc, zależy od przypadku i powinieneś przetestować, czy może ci to pomóc w zależności od twoich zdjęć.

2) aby skompresować folder zasobów. Często może to być bardzo pomocne w celu zaoszczędzenia miejsca na dysku. Następnie, gdy gra jest uruchomiona, dekompresujesz lub pobierasz żądany obraz ze skompresowanego pliku - w zależności od używanego formatu kompresji. Zobacz poprzednią odpowiedź, która stała się wiki tej witryny: /gamedev//a/37649/72423

Pamiętaj jednak, że każdy rodzaj kompresji może być mniej lub bardziej korzystny w zależności od używanego typu pliku obrazu : Unikaj podwójnej kompresji zasobów

Więcej informacji na temat kompresji: najnowocześniejsza kompresja obrazu?


Na koniec możesz również zastanowić się, jakiego rodzaju obrazu użyć w każdej sytuacji: Który format obrazu jest bardziej wydajny pod względem pamięci: PNG, JPEG lub GIF?

MAnd
źródło
Dziękuję za informację. Dziwne, że udało ci się zmniejszyć rozmiar pliku na pół, umieszczając rzeczy w jednym pliku. Pomyślałem, że pod koniec dnia jest taka sama liczba pikseli i wykorzystana przestrzeń. Zredagowałem moje pytanie, aby uzyskać lepszą odpowiedź
Snake,
@ Snake Więc, według dokonanej przez ciebie edycji, myślę, że moja odpowiedź może być naprawdę pomocna. Łączenie obrazów i kompresowanie może znacznie zmniejszyć rozmiar folderu. Obie techniki są regularnie stosowane w niektórych rodzajach gier. Jeśli chodzi o konkatenację, to zawsze zaskakująca sztuczka. Wypróbuj sam: umieść obrazy z sekwencji jednej z twoich animacji obok siebie i porównaj ostateczny rozmiar z sumą poszczególnych zdjęć. Następnie możesz sprawdzić, czy to pomaga w twoim przypadku. Jeśli chodzi o kompresję, w przypadku plików PNG jest to zwykle mniej skuteczne, ale nadal warte wysiłku, aby zmniejszyć rozmiar ostatecznego folderu
MA
@ Pamiętaj jednak o jednym spostrzeżeniu: łączenie czasami nie jest warte, a nawet nieznacznie zwiększa ostateczny rozmiar. Ale często może zapewnić pożądaną redukcję. Wszystko zależy od twoich zdjęć
2015
Pamiętam, że wypróbowałem obie techniki, a redukcja była mniejsza niż 10%. Zdecydowanie wiem, że kompresja nie ma znaczenia w przypadku PNG, ale spróbuję konkatenacji. Właśnie dlatego zapytałem, jak robią to inne gry, ponieważ oczywiście mają znacznie więcej grafiki niż moja
Snake,
Kompresja folderu pełnego obrazów nie powinna być możliwa. Obrazy powinny być już skompresowane i nie powinny zawierać zbyt wielu powtarzalnych sekwencji. Gdyby tak było, ta dodatkowa warstwa kompresji byłaby częścią kodeka obrazu ...
corsiKa
9

Proponuję wypróbowanie TexturePacker

  • możesz po prostu przeciągnąć i upuścić wszystkie swoje obrazy i spakować je
  • możesz zastosować inną kompresję - np. użyć zindeksowanych plików PNG, które zużywają znacznie mniej pamięci - do 70% mniej w porównaniu ze standardowym plikiem PNG
  • możesz utworzyć plik danych, który zawiera nazwę + pozycję każdego z twoich budynków
  • darmowa wersja może już wystarczyć, aby utworzyć arkusze sprite dla Ciebie

Czy korzystasz ze środowiska programowania gier, takiego jak AndEngine, Cocos2d-x lub LibGdx? => Brak

Czy potrzebujesz wszystkich zdjęć ładowanych jednocześnie? Wygląda na to, że napotkasz ogromne problemy z pamięcią RAM na urządzeniach docelowych.


Aktualizacja: Snake przesłał mi kilka zdjęć. Jak obiecałem, nie opublikuję ich tutaj, więc sam stworzyłem sztukę, aby zademonstrować, jak zmniejszyć zużycie pamięci.

Na oryginalnym obrazie poruszała się tylko jedna część obrazu. Umieściłem ptaka w domu, aby to zademonstrować:

wprowadź opis zdjęcia tutaj

Zasadniczo upakowanie całej animacji na arkuszu jest dużym marnotrawstwem pamięci. Powinieneś podzielić części statyczne i ruchome:

Statyczny:

wprowadź opis zdjęcia tutaj

Anim01:

wprowadź opis zdjęcia tutaj

Anim02:

wprowadź opis zdjęcia tutaj

Zachowaj pierwotną pozycję ptaka na zdjęciach . Właśnie dlatego jest tak pusta przestrzeń powyżej. Potrzebujesz tego do wyrównania animacji.

Teraz przeciągnij obrazy na TexturePacker i wybierz następujące parametry

  • Format danych: skrót JSON (lub XML, jeśli wolisz)
  • TrimMode: Trim (tworzy prostokąty)
  • Format pikseli: INDEKSOWANY 8-bitowy - do tworzenia 8-bitowych plików PNG (około 70% mniej pamięci)
  • Allow Rotation: false
  • Wprowadź nazwę pliku dla danych

TexturePacker pakuje obrazy

W rezultacie otrzymujesz teraz 2 pliki: arkusz sprite i plik opisu 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}
},

Ważnymi częściami są rama i spriteSourceSize .

Rama daje lokalizację oryginalnego ikonki w arkuszu ikonki.

spriteSourceSize daje przesunięcie do rysowania obrazu - części obrazu, które zostały pominięte z powodu przycinania:

Prosta procedura rysowania pseudokodu wygląda następująco:

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

Może być konieczne dostosowanie obliczenia przesunięcia w zależności od punktu obrotu / początku w systemie graficznym. Powyższa procedura zakłada układ współrzędnych, którego początek znajduje się w lewym górnym rogu.

Następnie po prostu narysuj dom w 2 przejściach:

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

Nie musisz przejmować się przesunięciami - ponieważ obrazy są już wyrównane.

Andreas Löw
źródło
+1 za spostrzeżenie dotyczące użycia pamięci RAM, które inni ignorują
Dan Hulme,
@Andreas sprawdzę to. Dziękuję Ci. Nie śmiej się ze mnie, ale nie używam silnika. Najczęściej odbywa się to za pomocą animacji i rysunków i działa jak urok. Nie ładuję wszystkich obrazów do pamięci, inaczej zawiesi się. W tej chwili ładuje tylko obrazy wymagane do wyświetlenia. Czy uważasz, że powyższa sugestia będzie działać ze standardowym zestawem SDK systemu Android?
Snake,
1
Tak, to będzie. TexturePacker ma 2 tryby przycinania duszków: prostokąty i wielokąty. Jeśli używasz obrazów izometrycznych, możesz uzyskać dużą przewagę dzięki siatkom wielokątów pod względem upakowania. Pytanie brzmi, czy można narysować teksturowane trójkąty - lub prostokąty z maską. Jeśli tak nie jest, nadal możesz używać prostokątów. Możesz wysłać mi kilka swoich zdjęć, jeśli chcesz skorzystać z Dropbox i wysłać link do -> obsługa w codeandweb. com. Nie podzielę się nimi - chcę tylko zobaczyć, co możemy zrobić, aby poprawić pakowanie.
Andreas Löw,
@ AndreasLöw Bardzo mi przykro, nie otrzymałem powiadomienia o twoim komentarzu. Właśnie to widziałem. Będę bardzo wdzięczny za pomoc. Wyślę ci coś, a może rzucisz światło na to, co powinienem. .. trochę utknąłem z czymś, w czym mam mało doświadczenia i może możesz rzucić światło. Skontaktuję się z tobą wkrótce
Snake
7

Oto kilka wskaźników, których możesz użyć

  1. Upewnij się, że wszystkie obrazy tła i nieprzezroczyste nie są w formacie PNG
  2. Staraj się, aby wszystkie animacje były w stanie zapętlić, tzn. Jeśli animacja wynosi 1,2,3,4,5,6, spróbuj zrobić to tak, jakby 1,2,3,4,3,2,1, gdzie te liczby są liczbą klatek animacji, bardzo pomaga
  3. jeśli wiele obrazów jest takich samych i różni się tylko kolor (ogólnie przyciski interfejsu użytkownika, animacje cząstek m, monety gry), spróbuj zrobić jeden biały obraz i dynamicznie zmieniać jego kolor
  4. Spróbuj zrobić .apk tylko tymi obrazami, które są niezwykle ważne, a następnie załaduj wszystko z serwera i zachowaj w pamięci telefonu

Mam nadzieję, że te wskazówki pomogą

PS Daję ogólny pomysł, ponieważ nie jestem świadomy twojej dokładnej zawartości gry i przepraszam, jeśli te wskazówki nie są przydatne

Kumar Saurabh
źródło
Możesz również: 1) skompresować wszystkie obrazy 2) używać kafelków tak często, jak to możliwe 3) łączyć obrazy razem w większy obraz i używać go jako mapy UV do teksturowania
Anthony Raimondo
To są świetne sugestie. Dziękuję Ci. Myślę, że najważniejszą kwestią jest 4. Jednak jeśli tak jest, to w jaki sposób umieścić je w różnych folderach rysunkowych i odwoływać się do nich jak R.drawable.image1? Właśnie tam jestem zdezorientowany
Snake
4

Wiele gier nie utrzymuje swoich zasobów graficznych w .apk; obejmują one tylko „podstawy”, takie jak grafika interfejsu użytkownika i kod gry, a resztę zasobów można pobrać po zainstalowaniu gry. Jest to szczególnie prawdziwe w przypadku gier, które używają różnych zasobów graficznych w zależności od rozdzielczości ekranu, aby plik .apk nie musiał zawierać zasobów o niskiej i wysokiej rozdzielczości.

Powinieneś przyjrzeć się obu opcjom optymalizacji dostarczonym przez innych użytkowników, a także temu, czy ostatecznie będziesz musiał obsługiwać grafikę swojej gry osobno od samego .apk.

Sandalfoot
źródło
Nie mam żadnych problemów z pobieraniem grafiki z serwera (a nawet plików rozszerzeń), ale jak umieścić je w folderze z możliwością rysowania, aby móc odwoływać się do nich przez R.drawable.x Ponieważ większość moich (wielu) plików XML odwołuje się do nich przy użyciu R . Drawable
Snake
AFAIK, nie możesz. Jednym obejściem jest utrzymywanie tabeli skrótów nazw plików zasobów połączonych z identyfikatorami zasobów i używanie AssetManager do przechwytywania plików na podstawie tych identyfikatorów, ale może być konieczne przerobienie plików .xml, jeśli wybierzesz tę trasę.
Sandalfoot,
4

Przyszedłem na tę stronę w poszukiwaniu podobnego pytania i rzeczywiście istnieje kilka dobrych zasobów wskazanych zarówno w odpowiedziach na twoje pytanie, jak i na inne pytania.

Prawdopodobnie powinieneś rzucić okiem na animację 2D: Animowane modele 3D lub duszki z ramkami animacji? na jakąś debatę na temat różnych rodzajów animacji. Pomogło mi to zoptymalizować grę. Ponadto nie informujesz nas, którego interfejsu API używasz ani jakiego silnika używasz. Samo to może zrobić różnicę: Android klatka po klatce animacja PNG

Poza tym pamiętaj, że jeśli pójdziesz drogą kompresji, mogą istnieć istotne różnice między sposobem kompresji. W szczególności istnieje wiele różnic między rodzajami kompresji i toczy się specjalistyczna debata na temat najbardziej odpowiedniej trasy dla urządzeń mobilnych. Zwłaszcza jeśli weźmiesz pod uwagę, że w przypadku urządzeń mobilnych najważniejsze jest użycie pamięci RAM i marnowanie procesora podczas ładowania. Zobacz: http://www.gamasutra.com/blogs/AlexandruVoica/20130419/190833/Why_efficiency_is_key_in_texture_compression_standards_for_mobile_graphics.php?print=1

Bennton
źródło
Dziękuję Bennton, właściwie jestem nowy w tworzeniu gier. Opracowałem wiele aplikacji opartych na narzędziach / wydajności. Ale żaden z grami. Robię swoją pierwszą grę i nie używam silnika. Używam tylko AnimationDrawables i wszystko działa świetnie. To tylko rozmiar apka wymyka się spod kontroli
Snake
Bennton, ostatni sugerowany przez ciebie link jest szczególnie interesujący. Wielkie dzięki za udostępnienie tego! Upewnij się, że spojrzałeś na ostatnią z mojej odpowiedzi, która dotyczy również kwestii różnej kompresji dla różnych typów plików. W rzeczywistości wydaje się, że istnieją typy kompresji, które działają lepiej z już skompresowanymi typami obrazów, takimi jak PNG, lub lepiej z nieskompresowanymi typami obrazów. Eksperymentowanie dla każdego przypadku jest zawsze najlepszym sposobem na sprawdzenie, co działa najlepiej w każdej sytuacji.
MA