Animasyon hala mantık ve oluşturma arasında mükemmel şekilde bölünebilir. Animasyonun soyut veri durumu, grafik API'nızın animasyonu oluşturması için gerekli bilgilerdir.
Örneğin 2D oyunlarda, hareketli grafik sayfanızın çizilmesi gereken geçerli bölümünü görüntüleyen alanı işaretleyen bir dikdörtgen alan olabilir (karakterinizin çeşitli adımlarını içeren 30 80x80 çizimden oluşan bir sayfanız varsa atlama, oturma, hareket etme vb.). Ayrıca, oluşturma için ihtiyaç duymadığınız herhangi bir veri türü olabilir, ancak geçerli animasyon adımının süresinin bitmesine kadar kalan süre veya animasyonun adı ("yürüme", "ayakta" gibi animasyon durumlarını kendileri yönetmek için olabilir) vb.) Tüm bunlar istediğiniz şekilde temsil edilebilir. Bu mantık kısmı.
Oluşturma bölümünde, her zamanki gibi yapın, bu dikdörtgeni modelinizden alın ve grafik API'sine çağrı yapmak için oluşturucunuzu kullanın.
Kodda (burada C ++ sözdizimi kullanılarak):
class Sprite //Model
{
private:
Rectangle subrect;
Vector2f position;
//etc.
public:
Rectangle GetSubrect()
{
return subrect;
}
//etc.
};
class AnimatedSprite : public Sprite, public Updatable //arbitrary interface for classes that need to change their state on a regular basis
{
AnimationController animation_controller;
//etc.
public:
void Update()
{
animation_controller.Update(); //Good OOP design ;) It will take control of changing animations in time etc. for you
this.SetSubrect(animation_controller.GetCurrentAnimation().GetRect());
}
//etc.
};
Veriler bu. Oluşturucunuz bu verileri alır ve çizer. Hem normal Spritelar hem de animasyonlu olanlar aynı şekilde çizildiğinden, burada polimorfiyi kullanabilirsiniz!
class Renderer
{
//etc.
public:
void Draw(const Sprite &spr)
{
graphics_api_pointer->Draw(spr.GetAllTheDataThatINeed());
}
};
TMV:
Başka bir örnek buldum. Diyelim ki bir RPG'niz var. Örneğin, dünya haritasını temsil eden modelinizin muhtemelen karakterin dünyadaki konumunu harita üzerinde döşeme koordinatları olarak saklaması gerekecektir. Ancak, karakteri taşıdığınızda, bir sonraki kareye birkaç piksel yürürler. Bu "döşemeler arasında" konumunu bir animasyon nesnesinde saklıyor musunuz? Karakter sonunda haritadaki bir sonraki karo koordinatına "ulaştığında" nasıl güncellersiniz?
Dünya haritası oyuncuların konumunu doğrudan bilmiyor (Vector2f veya oyuncuların konumunu doğrudan saklayan buna benzer bir şey yok = bunun yerine oyuncu nesnesinin kendisine doğrudan bir referansı var, bu da AnimatedSprite'den geliyor böylece oluşturucuya kolayca iletebilir ve gerekli tüm verileri ondan alabilirsiniz.
Genel olarak, tilemap sadece her şeyi yapmak mümkün olmamalı - Ben tüm karoları yönetmek ilgilenen bir sınıf "TileMap" olurdu ve belki de ben teslim nesneleri arasında çarpışma algılama yapar ve harita üzerinde fayans. Daha sonra, başka bir "RPGMap" sınıfım olacaktı ya da onu aramak istersiniz, bu da hem tilemap'ınıza hem de oynatıcıya referansa sahiptir ve oynatıcınıza ve bilgisayarınıza gerçek Update () çağrılarını yapar. tilemap.
Oynatıcı hareket ettiğinde modeli nasıl güncellemek istediğiniz, ne yapmak istediğinize bağlıdır.
Oynatıcınızın karolar arasında bağımsız olarak hareket etmesine izin veriliyor mu (Zelda stili)? Sadece girişi tutun ve oynatıcıyı her kareye göre hareket ettirin. Yoksa oyuncunun "sağ" tuşuna basmasını ve karakterinizin otomatik olarak bir döşemeyi sağa hareket ettirmesini mi istiyorsunuz? RPGMap sınıfınızın, hedefine ulaşana kadar oyuncuların konumunu enterpole etmesine izin verin ve bu arada tüm hareket tuşu giriş işlemlerini kilitleyin.
Her iki durumda da, kendiniz için daha kolay hale getirmek istiyorsanız, tüm modelleriniz kendilerini güncellemek için gerçekten bir mantığa ihtiyaç duyuyorlarsa (sadece değişkenlerin değerlerini değiştirmek yerine) Update () yöntemlerine sahip olacaklar - Denetleyiciyi vermiyorsunuz MVC modelinde bu şekilde, kodu "yukarıdaki bir adım" dan (kontrolör) modele indirirsiniz ve tüm kontrolör modelin bu Update () yöntemini çağırır (Bizim durumumuzdaki kontrolör RPGMap). Mantık kodunu kolayca kolayca değiştirebilirsiniz - sadece sınıfın kodunu doğrudan değiştirebilirsiniz veya tamamen farklı bir davranışa ihtiyacınız varsa, sadece model sınıfınızdan türetebilir ve sadece Update () yöntemini geçersiz kılabilirsiniz.
Bu yaklaşım yöntem çağrılarını ve bunun gibi şeyleri çok azaltır - bu, saf MVC deseninin ana dezavantajlarından biri olmuştur (sonuç olarak GetThis () GetThat () çok sık çağrılır) - kodu hem daha uzun hem de küçük bir parça daha zor ve aynı zamanda daha yavaş - bunun gibi bir çok şeyi optimize eden derleyiciniz tarafından halledilmesine rağmen.