Pada dasarnya Anda berada di jalur yang benar - Anda perlu tahu berapa lama animasi berlangsung untuk melakukan hal semacam ini. Animasi lebih dari sekadar kumpulan bingkai, ada segala macam informasi lain di sekitar mereka yang Anda butuhkan. Misalnya berapa banyak frame yang ada, apakah loop animasi, seberapa cepat pemutarannya (misalnya 10 frame animasi per detik atau 25, atau 60?). Setiap animasi dapat didefinisikan dalam beberapa bagian data, yang dapat dilihat dan diputar ulang oleh beberapa kode animasi umum. Anda harus merangkum bagian animasi dalam sedikit kode sendiri, yang tidak mengetahui apa-apa kecuali definisi animasi ini dan cara menampilkan masing-masing bingkai gambar. Artinya, miliki objek animasi yang dapat Anda muat, mulai mainkan, hentikan mainnya, dan suruh untuk merender di lokasi tertentu di layar.
Pendekatan yang fleksibel adalah dengan menggunakan semacam definisi animasi untuk merangkum informasi semacam ini. Jadi daripada hanya mengatakan "animasi X adalah semua frame ini, cukup mainkan melalui mereka", Anda mendapatkan sesuatu yang sedikit lebih kompleks.
Misalnya dengan semacam format data mocked up
animasi =
{
{name = "walk", files = "walk * .png", frameCount = "12", loop = "true"},
{name = "fire" files = "fire * .png" frameCount = "6",
acara = {
{name = "bulletLeavesGun", frame = "4", param1 = "43", param2 = "30"}
}
}
}
Jadi kode Anda mengatakan sesuatu seperti:
currentAnimation = animations.Get("fire");
currentAnimation.Play();
Cara Anda mendeteksi peristiwa bisa dengan kode animasi yang memanggil Anda kembali (yaitu ketika ia mendeteksi acara baru karena animasi telah diputar ke bingkai tertentu, ia memanggil kode permainan Anda untuk memberi tahu tentang acara baru), atau dengan polling animasi seperti ini:
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);
}
}
Poin yang perlu diperhatikan:
- Kode animasi harus ada secara terpisah dari kode permainan. Anda benar-benar tidak ingin kode gameplay Anda terlalu terikat dengan mur dan baut pemutaran animasi.
- Kode animasi tahu apakah akan mengulang berdasarkan definisi animasi atau tidak
- Kode animasi tahu kapan animasi dilakukan, dan dapat memanggil kembali ke kode lain untuk mengatakan 'hei, animasi yang disebut "api" baru saja selesai, apa yang ingin Anda lakukan sekarang?'
- Kode animasi tidak tahu apa-apa tentang acara selain bahwa mereka memiliki nama dan beberapa data arbitrer yang terkait dengannya (param1 dan param2)
- Kode animasi tahu frame apa yang saat ini aktif, dan ketika itu berubah menjadi bingkai baru, ia dapat memeriksa dan berkata 'oh, saya di frame 4 sekarang, itu berarti peristiwa yang disebut "api" ini baru saja terjadi, tambahkan ke daftar acara terbaru saya sehingga saya dapat memberi tahu siapa pun yang bertanya tentang hal itu '.
Jika Anda tidak memerlukan tembakan peluru untuk terjadi di dalam animasi, tetapi hanya setelah itu selesai, Anda dapat pergi dengan sistem yang jauh lebih kompleks tanpa gagasan peristiwa. Tetapi Anda masih menginginkan sistem tempat animasi diputar sendiri, tahu berapa lama, dan dapat memanggil kembali kode permainan saat animasi selesai.