Najlepsze praktyki animacji Sprite

18

Chciałbym lepiej zrozumieć, jak ludzie w prawdziwym świecie radzą sobie z animacją.

Czy ładujesz 1 duży obraz, a następnie rysujesz różne prostokąty na podstawie ramki animacji?

Czy ładujesz pliki obrazów X do tablicy i rysujesz element w tablicy na podstawie ramki animacji?

Jak radzisz sobie z posiadaniem różnych długości animacji dla różnych duszków.

Powiedzmy, że chodzenie postaci zajmuje 4–8 klatek, a fale na plaży - 2–3 klatek. Jak poradziłbyś sobie z tą sytuacją? Zobacz poniżej

Dim Waves(1) as Sprite
Dim Char(5) as Sprite

Sub Animate()
     Frame += 1
     Draw Char(Frame)
     Draw Waves(Frame)
     If Frame = 5 Then Frame = 0
End Sub

Oczywiście Fale zakończyłyby się błędem przekroczenia granicy.

A może duszek martwi się własną animacją i wcale nie dba o ramkę. Czy każdy duszek zna własną pętlę animacji?

jblaske
źródło

Odpowiedzi:

23

W przeszłości robiłem to, oddzielając dane animacji od odtwarzania animacji . Następnie Animationmoże stać się w zasadzie tablicą Framesi kilkoma właściwościami opisującymi, jak powinna zachowywać się animacja (jeśli się zapętla itp.).

Zazwyczaj ładuję jeden obraz i rysuję jego fragmenty.

Każda Frameanimacja jest zasadniczo prostokątem i długim czasem. Pozwala to niektórym ramkom wyświetlać się dłużej niż inne, co może, ale nie musi, być czymś, czego chcesz. Jeśli chcesz, aby wszystkie klatki w animacji były wyświetlane przez ten sam czas, zapisz to w swoim Animationobiekcie.

Wszystko, co wymaga odtworzenia animacji, ma swoją własną, AnimationPlayerktórą można wskazać Animation. Obiekt odtwarzacza zajmuje się odtwarzaniem animacji i udostępnia „bieżącą klatkę”.

Zaletą tego było dla mnie to, że mogłem mieć jedną instancję, na Animationktórą wiele obiektów mogłoby wskazywać i grać jednocześnie różne role. Łatwo było również zmieniać animacje, po prostu wskazując AnimationPlayerinny Animationobiekt i resetując odtwarzanie.

Edycja : Oto dość podstawowa implementacja JavaScript opisanego powyżej systemu . Zrzuciłem to razem w kilka minut jako demonstrację . „Prawdziwy” kod miałby więcej funkcji. Potrzebujesz jednak nowoczesnej przeglądarki, która obsługuje zarówno identyfikator Canvas, jak i identyfikator URI danych.

Zack The Human
źródło
1
Co on powiedział. Ponadto często wygodne jest ustawienie przesunięcia x / y dla każdej klatki w animacji, aby można było mocno spakować obrazy duszka do ich obwiedni, a następnie umieścić je w animacji w dowolnym miejscu. Pozwala także wykonywać podstawowe czynności, takie jak żonglerka, używając tylko jednego obrazu.
hojny
Tak, całkowicie się zgadzam. W rzeczywistości system animacji, którego używam, pozwala na to. Ułatwia to zmianę pozycji dowolnej klatki bez konieczności edytowania danych obrazu.
Zack The Human
Fajny przykład roboczy, WOW Kciuki w górę. Poleciłbym to.
DFectuoso,
Ważnym ograniczeniem rodzaju animacji jest to, że postać nie może być oglądana pod innym kątem - odejście od widza, zbliżenie do widza itp. Czy się mylę?
Majid Fouladpour,
@MajidFouladpour Nie sądzę, że tego rodzaju ograniczenia istnieją przy użyciu tej techniki. Po prostu masz różne obiekty AnimationData dla każdego „kąta widzenia”.
Zack The Human
1

Chciałbym, żeby animacja wiedziała, ile ma klatek. Miejsce i sposób ich przechowywania jest względnie nieistotne, z wyjątkiem problemów z wydajnością (np. Możesz chcieć mieć tę samą teksturę). Nigdy nie dodawałbym 1 do liczby klatek, dodawałbym deltaTime * animSpeed ​​i konwertował tę wartość na liczbę całkowitą podczas wyświetlania. W ten sposób możesz spowolnić lub przyspieszyć animacje i być niezależnym od klatek na sekundę.

Więc duszek miałby animację, która się aktualizuje.

Kaj
źródło
0

Dlaczego nie zapisać liczby klatek dla każdego z twoich obiektów? Osobiście przekazuję liczbę klatek w animacji do moich obiektów w ich konstruktorach, a następnie mam standardową funkcję Animate (), która pobiera liczbę klatek w animacji.

SD021
źródło
0

To zależy od wdrożenia. W moim silniku wykonuję animacje zarówno w Direct3D, jak i DirectDraw.

W DirectDraw tworzę jeden duży obraz. Wszystko i tak jest przechowywane w pamięci systemowej, co ostatecznie sprowadza się do jednowymiarowego bloku danych.

Plusy:

  • Łatwe przenoszenie między ramkami. Zmień wskaźnik początkowy, dodawaj odstęp (całkowitą szerokość obrazu) co y, a będziesz złoty.

Cons:

  • Nie można po prostu skopiować jednej klatki na ekran, musisz to zrobić ręcznie.

  • Olbrzymi blok pamięci. Tłoczenie ramek wiąże się z karą.

W Direct3D używam osobnych tekstur. Jest tak, ponieważ nie mam pojęcia o ograniczeniach tekstury urządzenia, więc nie wiem, czy obsługuje on tekstury o wielkości całego obrazu.

Plusy:

  • Możesz skopiować ramkę bezpośrednio na ekran, ponieważ wszystkie są osobnymi jednostkami.

Cons:

  • Brak wyrównania pamięci.
knight666
źródło
0

W moich grach przekazałem mojej klasie podstawowej Sprite wiedzę o tym, jak się rysować, a wszystkie animowane elementy dziedziczą tę wiedzę: liczba i czas trwania klatek animacji, pozycja na ekranie itp. Główna pętla gry po prostu iteruje przez wszystkie duszków, prosząc każdego o narysowanie się według własnego uznania. Wydaje się, że działa dość dobrze i jest nieco bardziej modułowy do uruchomienia: jeśli dodasz nowego duszka, który ma inną pętlę animacji (lub nawet bardziej skomplikowaną: wiele stanów animacji), nie musisz wracać i przepisywać programu Animate () procedura uwzględniająca dodatkową złożoność:

Dim Waves as Sprite
Dim Char as Sprite

Sub Animate()
     Char.update()
     Waves.update()
End Sub

Za każdym razem, gdy wywoływana jest metoda update () duszka, wie, czy powinna przerysować tę samą klatkę co poprzednio, przejść do następnej klatki w bieżącej animacji, przejść do nowej animacji itp.

Ma to tę dodatkową zaletę, że znacznie ułatwia dostosowanie szybkości klatek w celu dostosowania do różnych prędkości renderowania zegara / platformy, ponieważ jedyną zmianą jest to, jak często wywołujesz Animate ().

Rylee Corradini
źródło