zondag 23 december 2012

Over animatie

In het spel van de bro's wordt uitvoerig gebruik gemaakt van geanimeerde objecten zoals monsters en spelers. Het systeem is in eerste instantie door Kevin gemaakt en later door mij nog eens extra bezoedeld.
Eerst moest je namelijk een animatie aanmaken. Deze animatie had de volgende dingen nodig:
Een spritesheet. Bestaande uit een plaatje en de afmetingen van afzonderlijke sprites.
Een startcolumn, endcolumn, startrow en endrow. De precieze hoeveelheid sprites op een sheet. Let op: bij een 4x4 sheet was de startcolumn 0 en de endcolumn 3.
De yorickoffset. De animaties staan vaak in een sheet met meerdere andere richtingen. Deze integer is de hoeveelheid plaatjes die per frame moet worden overgeslagen. Aangezien er voor vier windrichtingen plaatjes zijn in de meeste spritesheets en voor een aantal maar eentje, is dit eigenlijk altijd 1 of 4. Eigenlijk zou het looprichtingen moeten heten, maar het is als een soort running gag maar zo gelaten, aangezien het in het jargon van de Bro's een vaste plek had verdiend. (Mocht degene die ons beoordeelt punten aftrekken vanwege het verzinnen van rare namen voor variabelen, foei, je had dit stukje ook moeten lezen! PS: we houden van je!)
Ook was er een float die de frametime aangaf in seconden. Verder was er nog een bool MovesWithCamera die iets te maken had met de True3D engine en on screen zaken, maar eigenlijk altijd op false stond, en zo snel tot een rudimentair iets was vervallen dat niemand er ooit echt iets van heeft gemerkt.

De moderne versie van de animatie heeft een aantal toevoegingen en een aantal verwijderingen van parameters gekend. Eerst maar eens de weglatingen:

Voor zich spreekt dat de MovesWithCamera is verdwenen.
Eveneens moesten de startcolumn en startrow er aan geloven, aangezien alle spritesheets gewoon linksboven begonnen. Het was een handige manier om verschillende animaties in verschillende richtingen in de zelfde sheet op te slaan, maar dit vereist een boel parameters en een boel hardcoden, iets dat je liever wilt vermijden.
Nu komen de toevoegingen:
Een bool isLooping om te kijken of een animatie eenmalig af wordt gespeeld of continue. Ook een nieuwe toevoeging: het aantal frames. Als een animatie met maar 1 richting en 8 frames in een 3 bij 3 sheet staat, is het handig dat het lege negende vakje niet wordt getoond. Random Fact #1280: De slime was degene voor wie dit werd gemaakt, maar ook voor sheets met 4 richtingen kan dit soms handig zijn.
Tot slot is er een directionaloffset. Er worden immers telkens 3 frames overgeslagen omdat die bij een andere richting horen. De directionaloffset houdt bij waar de animatie begint. In Kevin zijn versie lag dit nog vast, maar ik heb het verbeterd. Eerst moest namelijk voor elke richting een aparte animatie worden gemaakt, nu is er nog maar één animatie en wordt deze offset aangepast.

Het enige soort object dat met animaties kan werken is het AnimatedGameObject. Dit is een upgrade van SpriteGameObject.

Dit object heeft een aantal methoden en variabelen om met de eerder behandelde animaties om te springen:

Er zijn twee mogelijkheden om een bruikbare animatie aan te maken:

LoadAnimation: het object heeft een dictionary waarin hij animaties kan bijhouden. Dit is al zo sinds het begin van de animatie in het spel. Met deze functie kan een animatie worden gemaakt en opgeslagen worden in deze dictionary. Vrijwel alle parameters die worden gebruikt in het aanmaken van een animatie komen hier ook aan bod, alleen is de eerder genoemde yorickoffset door een bool vervangen: directional. Zo is er geen verwarring mogelijk omtrent de rare naam. Ook worden er een paar kleine bewerkingen gedaan, namelijk wordt het animatedgameobject de parent van de animatie, en wordt de Origin gedefinieerd. Ook moet er een id in string-vorm worden meegegeven om het object in de dictionary op te kunnen vragen. Random Fact #1281: Vroeger werden er hier automatisch meerdere animaties aangemaakt voor de richtingen van de animatie, die allemaal onder een eigen naam werden opgeslagen in de dictionary.
CreateAnimation: Er zijn hier twee verschillende mogelijkheden. Er kan een animatie worden meegegeven of dezelfde waarden als bij LoadAnimation. Er wordt door deze methode een animatie teruggegeven. Het klinkt misschien raar dat je een animatie mee kunt geven, maar bij het handmatig aanmaken van een animatie worden de bewerkingen aan het eind van LoadAnimation niet uitgevoerd. Mocht iemand een animatie willen maken die exact hetzelfde is als een animatie die in LoadAnimation is gemaakt, dan kan dat hier. Bij een al gemaakte animatie wordt alleen het fine-tunen dat voorheen alleen via LoadAnimation mogelijk was alsnog toegevoegd.

Er zijn tevens twee manieren om een animatie af te spelen, namelijk met de methoden PlayAnimation en FlickAnimation.

Animaties kunnen direct worden meegegeven aan deze methoden of in string vorm, zodat ze uit de dictionary kunnen worden geplukt.
PlayAnimation stelt de huidige animatie van het object in als de gegeven animatie en FlickAnimation speelt de gegeven animatie een keer af om vervolgens terug te keren naar de vorige animatie. Mocht dit worden aangeroepen terwijl er al een Flick bezig is, Wordt naar de laatste normaal ingestelde animatie geretourneerd.
Ook kan de decimaldirection worden meegegeven om de richting van de animatie te bepalen zoals eerder al is uitgelegd.(zie: directionaloffset)
Een functie die Play wel heeft en Flick niet is een animatie stil afspelen door de bool Still die standaard false is. Het eerste frame wordt dan weergegeven en de animatie wordt niet verder afgespeeld. Random Fact #1282: voor FlickAnimation heeft een AnimatedGameObject een aparte variabele om de Animatie in op te slaan waar terug naar gegaan wordt na afloop.

PS: de decimaldirection kan door objecten in hun gewone methoden gebruikt worden. Zijn nut blijft dus niet beperkt tot het regelen van animatie. De loop/kijk richtingen zijn als volgt gedefinieerd: 0 is naar beneden, 1 is omhoog, 2 is rechts, 3 is links. Dit geld ook voor de directionaloffset. Bij het aanpassen van de decimaldirection wordt de animatie ook automatisch aangepast, tenzij de animatie maar 1 richting heeft.


PPS: Mocht je het nog niet vergeten zijn, er moet nog even gemeld worden waarom ik vandaag een domme jongen was. Ik dacht namelijk een bug op te moeten lossen waardoor de animaties niet loopten, maar alle animaties die ik gebruikte bij het debuggen stonden per ongeluk op niet loopen. Dom, dom, dom...

Geen opmerkingen:

Een reactie posten