Fondamentalmente sei sulla buona strada: devi sapere quanto dura un'animazione per fare questo genere di cose. Le animazioni sono più di una semplice raccolta di cornici, ci sono ogni sorta di altre informazioni che ti servono. Ad esempio, quanti fotogrammi ci sono, il loop di animazione, quanto velocemente viene riprodotto (ad es. 10 fotogrammi di animazione al secondo o 25 o 60?). Ogni animazione può essere definita in termini di alcuni dati, che alcuni codici di animazione generalizzati possono visualizzare e riprodurre. Dovresti incapsulare la parte di animazione nel suo bit di codice, che non è a conoscenza di nulla tranne queste definizioni di animazione e di come visualizzare i singoli fotogrammi dell'immagine. Cioè, disporre di un oggetto animazione che è possibile caricare, avviare la riproduzione, interrompere la riproduzione e dire di eseguire il rendering in una determinata posizione sullo schermo.
Un approccio flessibile consiste nell'utilizzare una sorta di definizione di animazione per incapsulare questo tipo di informazioni. Quindi, piuttosto che dire semplicemente "l'animazione X è tutti questi fotogrammi, basta riprodurli", ottieni qualcosa di un po 'più complesso.
Ad esempio con una sorta di formato dati deriso
animazioni =
{
{name = "walk", files = "walk * .png", frameCount = "12", loop = "true"},
{name = "fire" files = "fire * .png" frameCount = "6",
eventi = {
{name = "bulletLeavesGun", frame = "4", param1 = "43", param2 = "30"}
}
}
}
Quindi il tuo codice dice qualcosa del tipo:
currentAnimation = animations.Get("fire");
currentAnimation.Play();
Il modo in cui rilevi gli eventi può essere sia con il codice di animazione che ti richiama (ovvero quando rileva un nuovo evento perché l'animazione ha riprodotto un determinato frame, chiama il tuo codice di gioco per dirlo del nuovo evento), oppure eseguendo il polling del animazione così:
List<Event> events = currentAnimation.EventsSinceLastCheck();
foreach (AnimationEvent event in events)
{
if (event.name == "bulletLeavesGun")
{
Vector2 bulletPosition = new Vector2(event.param1, event.param2);
Vector2 actualBulletPosition = new Vector2(
character.x + bulletPosition.x,
character.y + bulletPosition.y);
CreateBulletAt(actualBulletPosition);
}
}
Punti da notare:
- Il codice di animazione dovrebbe esistere separatamente dal codice di gioco. Non vuoi davvero che il tuo codice di gioco sia strettamente legato ai dettagli della riproduzione dell'animazione.
- Il codice di animazione sa se eseguire il loop in base alla definizione dell'animazione
- Il codice di animazione sa quando l'animazione è terminata e può richiamare un altro codice per dire 'ehi, l'animazione chiamata "fuoco" è appena finita, cosa vuoi fare adesso? "
- Il codice di animazione non è a conoscenza di eventi diversi da quello a cui sono associati un nome e alcuni dati arbitrari (param1 e param2)
- Il codice di animazione sa quale frame è attualmente attivo e quando passa a un nuovo frame, può controllare e dire 'oh, sono sul frame 4 ora, ciò significa che questo evento chiamato "fuoco" è appena accaduto, aggiungilo a la mia lista di eventi recenti in modo da poterlo dire a chiunque ne faccia richiesta '.
Se non è necessario che il proiettile si attivi all'interno dell'animazione, ma solo una volta terminato, è possibile cavarsela con un sistema molto meno complesso senza la nozione di eventi. Ma vorrai comunque un sistema in cui le animazioni vengano riprodotte da sole, sappiano quanto durano e possono richiamare il codice di gioco una volta completata l'animazione.