Witaj Wesnothańczyku
Nawigacja
-> Poradniki dla graczy
-> Poradniki dla twórców
-> Zrzuty ekranu
-> Komendy do BfW
-> Ladder of Wesnoth
-> JAK NIE DOSTAĆ BANA?
-> Kodeks strony
-> Kanały IRC
-> Darczyńcy
-> Galeria
-> Kontakt
-> Szukaj

-> Władcy Taktyk
-> Polski Ranking Graczy

-> Era Magii
-> Eastern Europe at War
-> Forgotten Legends
-> Nowy Porządek
-> Ku Nieznanym Krainom
 
Aktualnie online
-> Gości online: 2

-> Użytkowników online: 0

-> Łącznie użytkowników: 2,099
-> Najnowszy użytkownik: Gaara
 
Linki

















Polecane portale

Sygnaturki i buttony wesnoth.com.pl


 
9. Animacje
Programowanie animacji

W tym tutorialu dowiesz się co należy napisać w pliku jednostki, aby mogła ona wykorzystać narysowane przez Ciebie animacje.

Bloki animacji

Jednostki w BfW posiadają mnóstwo najróżniejszych animacji począwszy od animacji ataku/obrony, przez animacje bezczynności, aż po animacje specjalne.
Każda animacja to sekwencja klatek, pojedynczych obrazków wyświetlanych jeden po drugim. Cała taka pojedyncza sekwencja nazywa się blokiem. Blok mieści się pomiędzy tagami, których nazwy określają jaka to animacja, np. dla animacji ataku będzie to:
[attack_anim]
...
(animacja)
...
[/attack_anim]

a dla animacji bezczynności:
[idle_anim]
...
(animacja)
...
[/idle_anim]

Wszystkie tagi określające bloki animacji zostaną omówione w dalszej części.

Klatki

Klatki animacji (ang. frames) to pojedyncze obrazki, które ułożone w odpowiedniej kolejności tworzą animację. W pliku jednostki pojedyncza klatka opisana jest tagiem [frame]. Tam umieszcza się ścieżkę do obrazka, ustawia czas wyświetlania klatki oraz wiele innych atrybutów.
[attack_anim]
...
[frame]
image="(ścieżka)"
duration=100 (czas wyświetlania klatki na ekranie liczony w milisekundach)
[/frame]
...
[/attack_anim]

Można mieć kilka klatek wyświetlanych w tym samym czasie. Przykładem tego jest animacja strzelania z łuku. Mamy tam dwa zestawy klatek - jednostkę i strzałę, które animowane są w tej samej chwili niezależnie od siebie (cały czas jest to jedna animacja ataku). Jest to możliwe dzięki zastosowaniu różnych nazw dla zestawów klatek.
Trochę skomplikowanie to brzmi, ale w rzeczywistości tak nie jest. Akurat w tym przykładzie z łukiem mamy dwa zestawy klatek: [frame][/frame] dla jednostki i [missile_frame][/missile_frame] dla strzały. Takie zestawy możemy nazywać po swojemu, ale trzeba pamiętać żeby wyglądało to według schematu [xxx_frame], gdzie xxx to nasza własna nazwa zestawu.

Timing, czyli sterowanie długością animacji

Ogromną rolę w animacji odgrywa czas. W grze animacje liczone są w ms (milisekundach) - 1000 ms = 1 sekunda. Każda klatka widnieje na ekranie określoną liczbę milisekund po czym jest zastępowana przez następną i tak aż do zakończenia odtwarzania całej animacji (odpowiada za to parametr duration - czas trwania). Blok animacji zaś dysponuje tzw. czasem startowym start_time, który informuje grę, kiedy odtwarzać animację. Dla prostych animacji będzie on wynosił zero, ale dla animacji ataku i obrony już nie.
W animacjach ataku/obrony wszystko liczone jest względem zera, które odpowiada momentowi zadania ciosu. Wszystko przed tym (wartości ujemne) odnosić się będzie animacji, kiedy to jednostka podchodzi do drugiej aby się zamachnąć na nią mieczem, a wszystko po tym (wartości dodatnie) odpowiada tej części aniamcji, kiedy jednostka powraca na miejsce po ataku.
oś czasu

Na tej osi czasu pokazana jest cała animacja ataku Łucznika. Na dole mamy czas liczony przez silnik gry. Animacja zaczyna się wyświetlać 275 milisekund przed zadaniem ciosu (start_time=-275). Po wykonaniu ataku jendostka powraca na swoją pozycję i zajmuje jej to dokładnie 225 ms. Cała animacja trwa 275+225=500ms czyli pół sekundy.
Czas podany pomiędzy obrazkami to duration - czas wyświetlania konkretnej klatki. I tak w naszym przykładzie pierwsza klatka wyświetlana jest przez 50ms, druga przez 100ms, tak samo trzecia, czwarta i piąta, 50ms trwa szósta, a siódma to normalny obrazek jednostki i nie liczy się do animacji (dałem go tylko dla pokazania całego procesu).

Tak wygląda kod tej animacji (im więcej klatek, tym bardziej skomplikowana animacja):
[attack_anim]

[filter_attack]
name=short sword (animacja wyświetla się przy użyciu tylko tego ataku)
[/filter_attack]

start_time=-275 (czas startowy)

[frame]
duration=50
image="units/human-loyalists/bowman.png"
[/frame]
[frame]
duration=100
image="units/human-loyalists/bowman-melee-attack-1.png"
[/frame]
[frame]
duration=100
image="units/human-loyalists/bowman-melee-attack-2.png"
[/frame]

(tutaj pojawia się warunek odnośnie trafienia, aby dobrze dobrać dźwięk)

[if]
hits=yes (jednostka trafia przeciwnika)
[frame]
duration=100
image="units/human-loyalists/bowman-melee-attack-3.png"
sound={SOUND_LIST:SWORD_SWISH} (odgłos miecza)
[/frame]
[/if]
[else]
hits=no (jednostka nie trafiła)
[frame]
duration=100
image="units/human-loyalists/bowman-melee-attack-3.png"
sound={SOUND_LIST:MISS} (odgłos chybienia)
[/frame]
[/else]

(koniec warunku, ciąg dalszy animacji)

[frame]
duration=100
image="units/human-loyalists/bowman-melee-attack-4.png"
[/frame]
[frame]
duration=50
image="units/human-loyalists/bowman-melee-defend-1.png"
[/frame]

[/attack_anim]

Parametry klatki

Omówię teraz jakie najważniejsze właściwości pojedynczej klatki [frame] możemy ustawiać:

duration=
(czas wyświetlania klatki w ms)
image= (ścieżka do obrazka)
image_diagonal= (ścieżka do obrazka, który ma być wyświetlany przy ataku po skosie (kierunki sw,se,nw,ne)
sound= (ścieżka do pliku dźwiękowego, jaki ma być odegrany przy tej klatce)
halo= (ścieżka do obrazka, najczęściej magicznej aury i innych efektów specjalnych, wyświetlanych nad wszystkimi innymi obrazkami)
offset= (przesunięcie, przydatne przy strzałach. Dzięki temu parametrowi można decydować o pozycji obrazka w trakcie animacji. Przyjmuje on wartość od -1.0 do 1.0, gdzie 0.0 to środek własnego heksa, 1.0 środek heksa przeciwnika, a -1.0 środek heksa za nami. Za pomocą znaku tylda ~ można rozkazać grze, aby podczas danej klatki obrazek przemieścił się na określoną pozycję, np. z 0.0 do -1.0 będzie to offset=0.0~-1.0)
alpha= (przezroczystość obrazka, przyjmuje wartości od 0.0 do 1.0 i tu też można wykorzystać tyldę)

(drobna uwaga odnośnie tyldy: znak ten znajduje się na klawiaturze pod klawiszem Esc w lewym górnym rogu. Aby go napisać, trzeba mieć wciśnięty Shift i wtedy nacisnąć tyldę. Znak ten pojawić się może dopiero po zrobieniu spacji lub wciśnięciu innego klawisza, tak więc nie panikuj jak na początku nie ujrzysz go na ekranie).


Najlepiej uczyć się programowania animacji na przykładach. Weźmy więc jednostkę Chłopa i przyjrzyjmy mu się uważnie:

Nie będę wklejał całego kodu jednostki, bo jest długi. Będę omawiał tylko fragmenty związane z animacją.

Pierwszy blok animacji jaki możemy spotkać u Chłopa to animacja bezczynności [idle_anim]:
peasant-idle
Od strony WML wygląda tak (trochę uprościłem, bo oryginał zawierał przestarzały kod i inne śmieci):
[idle_anim]
start_time=0
[frame]
duration=100
image="units/human-peasants/peasant-idle-1.png"
[/frame]
[frame]
duration=100
image="units/human-peasants/peasant-idle-2.png"
[/frame]
[frame]
duration=100
image="units/human-peasants/peasant-idle-3.png"
[/frame]
[frame]
duration=100
image="units/human-peasants/peasant-idle-4.png"
[/frame]
[frame]
duration=100
image="units/human-peasants/peasant-idle-5.png"
[/frame]
[frame]
duration=100
image="units/human-peasants/peasant-idle-6.png"
[/frame]
[frame]
duration=100
image="units/human-peasants/peasant-idle-7.png"
[/frame]
[frame]
duration=100
image="units/human-peasants/peasant-idle-4.png"
[/frame]
[frame]
duration=100
image="units/human-peasants/peasant-idle-2.png"
[/frame]
[frame]
duration=100
image="units/human-peasants/peasant-idle-1.png"
[/frame]
[/idle_anim]

Animacja zaczyna się w punkcie zero (czyli normalnie, bo to nie jest animacja ataku/obrony). Dlatego też start_time wynosi 0. Równie dobrze możemy to pominąć, wtedy gra automatycznie założy, że animacja rozpoczyna się w punkcie 0.

Kolejną animacją jest animacja ataku na odległość a dokładniej rzutu widłami.

[attack_anim]

[filter_attack]
name=pitchfork
range=ranged
[/filter_attack]

start_time=-200
missile_start_time=-150

[missile_frame]
duration=150
image="projectiles/pitchfork-n.png"
image_diagonal="projectiles/pitchfork-ne.png"
[/missile_frame]

[frame]
duration=100
image="units/human-peasants/peasant-attack2.png"
sound={SOUND_LIST:THROW}
[/frame]

[if]
hits=yes
[frame]
duration=50
image="units/human-peasants/peasant-ranged.png"
sound=spear.ogg
[/frame]
[/if]
[else]
hits=no
[frame]
duration=50
image="units/human-peasants/peasant-ranged.png"
[/frame]
[/else]

[/attack_anim]

Tu już jest bardziej skomplikowana sprawa, bo mamy 2 zestawy klatek - jeden dla jednostki, a drugi dla lecących w powietrzu wideł :P Ale po kolei:

[filter_attack]
name=pitchfork
range=ranged
[/filter_attack]


To filtr animacji. Mówi on grze, że ta animacja ataku zostanie wyświetlona tylko wtedy, gdy jednostka użyje ataku o nazwie pitchfork (name=pitchfork) i będzie to atak na odległość.

start_time=-200
missile_start_time=-150


Te dwie linijki określają czas rozpoczęcia wyświetlania animacji dla poszczególnych zestawów klatek - zwykłego i missile, czyli naszego pocisku (u nas wideł). Z missile_start_time możemy szybko wywnioskować jak długo widły będą leciały w powietrzu. W naszym przypadku 150 milisekund.

[missile_frame]
duration=150
image="projectiles/pitchfork-n.png"
image_diagonal="projectiles/pitchfork-ne.png"
[/missile_frame]


To nasz pierwszy zestaw, odpowiadający animacji wideł. Jest to bardzo prosta animacja składająca się tylko z jednej klatki, która trwa 150ms i posiada dwa warianty obrazka - widły w wariancie północ-południe i widły po skosie :P Warto sprawdzić w katalogu images jak to wygląda, żeby wiedzieć o co chodzi.

Tag [missile_frame] automatycznie zawiera parametr offset ustawiony na 0.0~1.0 (obrazek wideł przemieszcza się ze środka naszego heksa na środek heksa przeciwnika), więc nie musimy tego pisać.

[frame]
duration=100
image="units/human-peasants/peasant-attack2.png"
sound={SOUND_LIST:THROW}
[/frame]

[if]
hits=yes
[frame]
duration=50
image="units/human-peasants/peasant-ranged.png"
sound=spear.ogg
[/frame]
[/if]
[else]
hits=no
[frame]
duration=50
image="units/human-peasants/peasant-ranged.png"
[/frame]
[/else]


To drugi zestaw klatek. Odpowiada jednostce. W pierwszych 100ms wyświetla się obrazek "peasant-attack2.png" i emitowany jest dźwięk rzutu z makra {SOUND_LIST:THROW}. Makro to losuje kilka różnych dźwięków rzutu i wybiera jeden, tak aby uniknąć monotonii.
Następnie mamy warunek. Jeśli jednostka trafia to emitowany jest dźwięk trafienia włócznią "spear.ogg", jeśli natomiast jednostka chybi, to nie ma żadnego dźwięku. Na tym kończy się cała animacja.

[attack_anim]

[filter_attack]
name=pitchfork
range=melee
[/filter_attack]

start_time=-250

[frame]
duration=50
image="units/human-peasants/peasant.png"
[/frame]

[if]
hits=yes
[frame]
duration=250
image="units/human-peasants/peasant-attack.png"
sound=spear.ogg
[/frame]
[/if]
[else]
hits=no
[frame]
duration=250
image="units/human-peasants/peasant-attack.png"
sound=spear-miss.ogg
[/frame]
[/else]

[frame]
duration=100
image="units/human-peasants/peasant-attack2.png"
[/frame]
[frame]
duration=50
image="units/human-peasants/peasant.png"
[/frame]

[/attack_anim]

Tu jest podobnie jak wyżej, tylko prościej, bo mamy jeden zestaw klatek odnoszący się tylko do jednostki. Chłop w ciągu 250ms dobiega do przeciwnika i wymierza cios. Potem w ciągu 200ms powraca na miejsce. Cała animacja trwa 450ms (50+250+100+50).

Przy animacji ataku i obrony trzeba umiejętnie określić czas rozpoczęcia, tak aby zgadzał się on z klatką animacji, odpowiadającą za wymierzenie ciosu.

W przykładzie ataku chłopa wygląda to na osi tak:
peasant-oś
Widać tu dokładnie, gdzie przypada moment zero. Będzie miał miejsce w trakcie wyświetlania drugiej klatki. Akurat klatka ta została narysowana właśnie w taki sposób, aby odzwierciedlić cios (chłop trzyma wtedy widły w pozycji, jakby chciał kogoś nadziać). Dzięki temu mamy zachowany realizm. Czasem warto rozrysować sobie taką oś na kartce i dopiero wtedy programować czas.

Jeśli chodzi o animacje obrony, to są one podobne do animacji ataku. Jednak tutaj doradzałbym skorzystanie z uniwersalnego makra, którego używa sam chłop:

{DEFENSE_ANIM OBRAZEK_OBRONY OBRAZEK_PODSTAWOWY ODGLOS_ZRANIENIA}

z uzupełnionymi wartościami:
{DEFENSE_ANIM "units/human-peasants/peasant-defend.png" "units/human-peasants/peasant.png" {SOUND_LIST:HUMAN_OLD_HIT} }

Makro to jest prostym blokiem animacji obrony, składającym się z 3 klatek, z których 2 się powtarzają. Tylko środkowa klatka odpowiada za obrazek, w którym jednostka broni się. Powstaje dzięki temu dosyć prosta sekwencja, ale za to wystarczająca w większości przypadków. I ja to makro polecam każdemu. W pliku peasant.cfg znaleźć je można w linijce 22.

Uwaga odnośnie oryginalnego kodu animacji Chłopa:
Jeśli zajrzysz do pliku peasant.cfg, znajdziesz zamiast parametru duration coś takiego:

begin=
end=

Jest to alternatywna metoda określania czasu wyświetlania animacji. Jest ona jednak przestarzała i niedługo zostanie usunięta z gry. Odradzam więc korzystanie z niej.

Rodzaje bloków animacji


Teraz omówię rodzaje animacji jednostek w Battle for Wesnoth i podam odpowiadające im nazwy tagów:


[leading_anim]
- animacja dowodzenia (powinna zaczynać się od wartości negatywnych, np. -125. Punkt 0 odpowiada ciosowi jednostki wspieranej)

[recruit_anim]
- animacja rekrutacji (wyświetla się przy rekrutowaniu oddziałów)

[standing_anim] - animacja postoju (wyświetla się cały czas, mają ją, np. nietoperze)

[idle_anim] - wyświetla się co jakiś czas (u chłopa to było podniesienie kapelusza)

[levelin_anim] - animacja wyświetlana przed awansowaniem jednostki na wyższy poziom

[levelout_anim]
- animacja wyświetlana po awansie jednostki

[healing_anim]
- animacja leczenia

[healed_anim]
- animacja bycia leczonym :P

[poison_anim] - działa jak animacja postoju, tylko, że wyświetlana jest przy zatruciu

[movement_anim] - animacja przemieszczania się

[pre_movement_anim] - animacja przygotowania się do ruchu (np. startujący smok)

[post_movement_anim] - animacja kończenia ruchu (np. lądujący smok)

[draw_weapon_anim]
- animacja przygotowania broni do walki

[sheath_weapon_anim] - animacja schowania broni po walce

[defend] - animacja obrony

[attack_anim]
- animacja ataku

[death] - animacja śmierci

[victory_anim] - animacja zwycięstwa po wygranym pojedynku

[teleport_anim] - animacja teleportu (przed 0, animacja wejścia, po 0 animacja wyjścia)

[extra_anim] - animacja własna. Trzeba umieścić w niej parametr flag= i nadać mu nazwę. Potem taką animację można wywołać, np. w scenariuszu za pomocą tagu [animate_unit].

Uniwersalna rada na sam koniec:

Jeśli nie wiesz jak zaprogramować konkretną animację, podejrzyj jak jest ona zrobiona u innych jednostek.
Wszelkie pytania i problemy kieruj na forum.

W następnym odcinku zajmiemy się tworzeniem zdolności dla jednostek.
Komentarze
#1 | BAN Gibki Kaktus dnia sierpień 16 2011 15:11:11
Super, bardzo się przyda, dzięki Wink .
#2 | Kuki1537 dnia sierpień 16 2011 15:24:55
Super! Cool Teraz już nie będę miał problemów z programowaniem animacji. xD
#3 | Vetch dnia sierpień 19 2011 19:26:59
Przyjemnie napisany poradnik, jednak kilka dni wcześniej już miałem to ogarnięte. Ale i tak jest +
Dodaj komentarz
Zaloguj się, aby móc dodać komentarz.
Oceny
Tylko zarejestrowani użytkownicy mogą oceniać zawartość strony

Zaloguj się lub zarejestruj, żeby móc zagłosować.

Świetne! Świetne! 100% [7 głosów]
Bardzo dobre Bardzo dobre 0% [Brak oceny]
Dobre Dobre 0% [Brak oceny]
Średnie Średnie 0% [Brak oceny]
Słabe Słabe 0% [Brak oceny]
Logowanie
Nazwa użytkownika

Hasło



Nie masz jeszcze konta?
Zarejestruj się

Nie możesz się zalogować?
Poproś o nowe hasło
 
Shoutbox
Musisz zalogować się, aby móc dodać wiadomość.

17/08/2017 00:11
Lub dla 3 (głupie 0) 2,4km=hex 500/2,4=208,3

17/08/2017 00:09
500/3,2=156,25. Wink

17/08/2017 00:08
30km/h to trochę za dużo. Grin Tura to 4 godziny (6tur =1 dzień) piechota ma 5 ruchów (regularne wojsko) idzie z prędkością powiedźmy 4km/h. 4*4=16 16/5= 3,2 km=hex.

16/08/2017 23:54
Grin

16/08/2017 23:36
Wprowadźcie łowców niewolników XD

16/08/2017 23:33
Poza podpaleniem proponuję stworzyć jeszcze jeden efekt specjalny. Zaraza: jeżeli 90% jednostek przeciwnika jest tego samego typu, to wszystkie umierają.

16/08/2017 23:31
Ja tam się cieszę, że jestem w grupie eoma

16/08/2017 23:31
@Hejnewar ja to między bajki włożę.

16/08/2017 22:34
No to jak mogę atakować statki w walce wręcz w takim razie? Ps. 500km to 20,8(3)hexa.

16/08/2017 22:16
@Hejne zedytowałem, żeby łatwiej tobie było całą metaforę tamtego wpisu zrozumieć. Dobranoc

 
Wygenerowano w sekund: 0.03
4,994,272 unikalnych wizyt