title: Animacja poklatkowa - Flip-book
Animacja poklatkowa (ang. flip-book animation) składa się z serii obrazów (klatek animacji), które są pokazywane jeden za drugim, więc patrząc na nie sprawiają wrażenie ruchu. Technika ta jest bardzo podobna do tradycyjnej animacji używanej w kinematografii https://pl.wikipedia.org/wiki/Animacja i oferuje nieograniczoną kontrolę, ponieważ każda klatka może być modyfikowana indywidualnie. Jednakże pamięć zajmowana przez wszystkie obrazy składające się na taką animację może być duża w zależności od ilości klatek i ich wielkości. Płynność animacji zależy od liczby klatek pokazywanych w każdej sekundzie (FPS z ang. frames per second), co wymaga oczywiście większej ilości pracy. Animacje typu flip-book w Defoldzie są przechowywane albo jako indywidualne obrazy umieszczone w galerii zwanej Atlas, albo jako obrazy umieszczone w bezpośrednim sąsiedztwie, w poziomej sekwencji jak kafelki w tzw. Źródle Kafelków - Tile Source.
Sprite'y i węzły GUI mogą odtwarzać animacje poklatkowe i masz nad tym całkowitą kontrolę w trakcie działania programu.
Sprite'y
: Aby odtworzyć animację w trakcie działania programu używa się funkcji sprite.play_flipbook(). Poniżej przykład.
Węzły GUI
: Aby odtworzyć animację w trakcie działania programu używa się funkcji gui.play_flipbook(). Poniżej przykład.
::: sidenote Tryb odtwarzania (playback mode) "once ping-pong" odtworzy animację klatka po klatce do samego końca, a następnie odtworzy ją jeszcze raz w odwrotnej kolejności, od tyłu, ale do drugiej klatki animacji, a nie do pierwszej. Jest to zabieg służący łatwemu wiązaniu animacji w serie. :::
Załóżmy, że Twoja gra posiada możliwość "uniku", która pozwala graczom nacisnąć klawisz, aby wykonać unik. Masz przygotowane 4 animacje, żeby w pełni pokazać unik:
"idle" : Zapętlona animacja stojącej postaci będącej w bezczynności.
"dodge_idle" : Zapętlona animacja postaci pochylonej, będącej w trakcie trwania uniku.
"start_dodge" : Jednokrtotnie odtwarzana animacja postaci w momencie przejścia animacji z pozycji stojącej do pochylonej w celu wykonania uniku.
"stop_dodge" : Jednokrtotnie odtwarzana animacja postaci w momencie przejścia animacji z pozycji uniku z powrotem do pozycji stojącej.
Skrypt poniżej przedstawia potrzebną logikę:
local function play_idle_animation(self)
if self.dodge then
sprite.play_flipbook("#sprite", hash("dodge_idle"))
else
sprite.play_flipbook("#sprite", hash("idle"))
end
end
function on_input(self, action_id, action)
-- "dodge" to nasza akcja zbindowana z inputem
if action_id == hash("dodge") then
if action.pressed then
sprite.play_flipbook("#sprite", hash("start_dodge"), play_idle_animation)
-- zapamiętaj, że wykonujemy unik
self.dodge = true
elseif action.released then
sprite.play_flipbook("#sprite", hash("stop_dodge"), play_idle_animation)
-- zapamiętaj, że skończyliśmy unik
self.dodge = false
end
end
end
Przy wyborze obrazu i animacji dla węzła graficznego interfejsu użytkownika (ang. GUI), np. "box" albo "pie" tak naprawdę właśnie przypisujesz źródło obrazów (atlas lub tile source) i domyślną animację, tak samo jak w przypadku sprite'ów. Takie źródło grafiki jest statycznie przypisane do węzła, ale animacja może być zmieniona w trakcie trwania programu. Nieruchome obrazki są traktowane jako jednoklatkowa animacja, więc zamiana obrazu jest jednoznaczna z odtworzeniem innej animacji poklatkowej na węźle:
function init(self)
local character_node = gui.get_node("character")
-- To wymaga, żeby węzły miały domyślne animacje w tym samym atlasie lub źródłe kafelków
-- co nowa animacja, którą odtwarzamy
gui.play_flipbook(character_node, "jump_left")
end
Funckje sprite.play_flipbook() i gui.play_flipbook() przyjmują jako ostatni argument opcjonalną funkcję, która jest wywoływana w momencie zakończenia animacji, tzw. callback. Będzie ona wywołana po skończeniu animacji, więc tylko dla takich, które nie są zapętlone, czyli w trybach odtwarzania: PLAYBACK_ONCE_* i nie będzie wywołana w przypadku ręcznego anulowania animacji za pomocą go.cancel_animations(). Można użyć takiej funkcjonalności w celu wywołania specjalnych wydarzeń po skończonej animacji (np. procesu zadania obrażeń po skończonej animacji ataku) lub do połączenia różnych animacji w serie, jedna za drugą. Przykłady:
local function flipbook_done(self)
msg.post("#", "jump_completed")
end
function init(self)
sprite.play_flipbook("#character", "jump_left", flipbook_done)
end
local function flipbook_done(self)
msg.post("#", "jump_completed")
end
function init(self)
gui.play_flipbook(gui.get_node("character"), "jump_left", flipbook_done)
end
Animacje można odtwarzać raz lub w pętli. Sposób odtwarzania animacji jest określany przez tryb odtwarzania (ang. Playback mode):