Bir kurşunla ateş etme animasyonu ile nasıl bağlanır


15

Bir mermi ateşlerken olmasını istediğiniz bir animasyonunuz olduğunu varsayalım. Animasyonun sonunda mermiyi nasıl gösterirsin? Anlayabildiğim tek şey, animasyonun zaman uzunluğunu bilmek ve mermi konumunu ayarlamayı geciktirmek ve bu süre geçene kadar etkin hale getirmek. Sadece bunun en iyi yaklaşım olup olmadığını merak ediyordum, herkes bunu nasıl ele alıyor?

EDIT: Bence soruyu doğru bir şekilde ifade etmekte sorun yaşıyorum.

Benim sorum


Teşekkürler! Hepinizden birçok iyi fikir, geri arama kullanma fikrini seviyorum. Sanırım bunu uygulamaya çalışacağım, gerçekten zaman takibine güvenmek istemedim.
tp0w3rn

Yanıtlar:


8

Temel olarak doğru yoldasınız - bir animasyonun bu tür şeyleri yapmak için ne kadar sürdüğünü bilmeniz gerekir. Animasyonlar sadece bir çerçeve koleksiyonundan daha fazlasıdır, etraflarında ihtiyacınız olan her türlü başka bilgi vardır. Örneğin kaç kare vardır, animasyon döngüsü ne kadar hızlı oynatılır (örneğin saniyede 10 animasyon karesi veya 25 veya 60?). Her animasyon, bazı genel animasyon kodlarının bakabileceği ve oynatabileceği birkaç veri parçası olarak tanımlanabilir. Animasyon bölümünü, bu animasyon tanımları ve tek tek görüntü çerçevelerinin nasıl görüntüleneceği dışında hiçbir şeyin farkında olmayan kendi kod bitinde kapsüllemelisiniz. Yani, yükleyebileceğiniz, oynatmaya başlayabileceğiniz, oynatmayı durdurabileceğiniz ve ekranda belirli bir yerde oluşturmayı söyleyebileceğiniz bir animasyon nesnesine sahip olun.

Esnek bir yaklaşım, bu tür bilgileri kapsüllemek için bir tür animasyon tanımı kullanmaktır. Yani sadece "animasyon X tüm bu karelerdir, sadece onlarla oynayın" demek yerine, biraz daha karmaşık bir şey elde edersiniz.

Örneğin bir çeşit sahte veri formatı ile

animasyonlar =
{
  {name = "walk", dosyalar = "walk * .png", frameCount = "12", loop = "true"},
  {name = "fire" dosyaları = "fire * .png" frameCount = "6",
       events = {
           {name = "bulletLeavesGun", çerçeve = "4", param1 = "43", param2 = "30"}
       }
  }
}

Kodunuz şöyle bir şey söylüyor:

currentAnimation = animations.Get("fire");
currentAnimation.Play();

Olayları nasıl algıladığınız, sizi geri çağıran animasyon koduyla (yani animasyon belirli bir karede oynatıldığı için yeni bir olay algıladığında, yeni olay hakkında bilgi vermek için oyun kodunuzu çağırır) veya böyle animasyon:

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);
    }
}

Dikkat edilmesi gereken noktalar:

  • Animasyon kodu oyun kodundan ayrı olmalıdır. Oyun kodunuzun animasyon oynatmanın somun ve cıvatalarına çok sıkı bağlı olmasını gerçekten istemiyorsunuz.
  • Animasyon kodu, animasyon tanımına göre döngü yapıp yapmayacağını bilir
  • Animasyon kodu, animasyonun ne zaman yapıldığını bilir ve 'hey, "ateş" adı verilen animasyon yeni bitti, şimdi ne yapmak istersiniz?
  • Animasyon kodu, bir adı ve kendileriyle ilişkili bazı rastgele verileri (param1 ve param2) olması dışında olaylar hakkında hiçbir şey bilmiyor
  • Animasyon kodu şu anda hangi karede olduğunu bilir ve yeni bir kareye dönüştüğünde 'oh, şimdi kare 4'teyim, yani "ateş" adı verilen bu etkinliğin yeni gerçekleştiğini, son olaylar listeme göre bunu soran herkese söyleyebilirim '.

Animasyon içinde mermi ateşlemesine ihtiyacınız yoksa, ancak sadece bittikten sonra, olay kavramı olmadan çok daha az karmaşık bir sistemden kurtulabilirsiniz. Ancak yine de animasyonların kendi başlarına oynattığı, ne kadar sürdüğünü bildiği ve bir animasyon tamamlandığında oyun kodunu geri çağırabileceği bir sistem isteyeceksiniz.


Mantık farkında animasyonlar tutmaya katılmıyorum (şimdi 4. karede, "ateş" adı verilen bu olay yeni gerçekleşti). Animasyonlar kör ve aptal olmalıdır. Bazı sunucu tarafı mantık ve animasyonları yırtmak zorunda kaldım ve oyundan UI tekrar yapmak istemediğim bir şey. Gerçekten çok kısa ve bölümlenmiş animasyonlar kullanmanızı öneririm, bunları mantıklara paralel olarak oynatın, mantıkların animasyon dizilerini mantıkların tanımladığı hızda tetiklemesine izin verin. Animasyonun durumu için hiçbir zaman mantık testi yapmayın.
Coyote

Animasyonu parçalara ayırmak oldukça gereksiz görünüyor. Animasyonun statüsü için oy kullanmamaya katılıyorum, ama yine de ilk tavsiyesini bırakıyor. Animasyon kodunu oyunun geri kalanından (gözlemci kalıbı?) Ayırmak için ayrı bir olay sistemi mi demek istediğini bilmiyorum ama ben böyle yapardım. Ne koymak gibi "mantık" animasyon kodu hakkında bilmek gerekir, ya da tam tersi.
jhocking

@Coyote Orada iki ayrı şeyi karıştırdığınızı söyleyebilirim. Evet, sunucu tarafı mantığı her zaman görsellerden bağımsız olmalıdır (çünkü bir mermi ateşlendiğinde anlamak için animasyon sistemini çalıştırmak istemezsiniz), ancak bu istemcide bir animasyon sistemi oluşturmanıza yardımcı olmaz . İstemcide, görsellerin sunucuya dikkatsizce köleleştirilmesini istemezsiniz, çünkü bu korkunç görünecektir - tuhaf zamanlarda ve mermilerle senkronize olmayan mermiler, çünkü oyun ve sunucu arasında bir gecikme başlangıcı vardı .
İkisine

@Coyote (devam ...), oyun görsellerden ayrılmış sunucu tarafından sürülebilir. Böylece mermi sunucuda X zamanında ateşlenir ve istemci mermi ateş simülasyonunu birkaç merminin arkasında birkaç kare geride bırakarak ateş animasyonunu hemen oynamaya başlayarak bu eylemi yansıtır. Görsel aslına uygunluk ve oyun simülasyonu arasında her türlü taviz verilmelidir, böylece "animasyonlar kör ve aptal olmalı" demek saftır. Bazen olayların kesinlikle animasyon karelerine bağlı olması gerekir, çünkü başka hiçbir yöntem onları doğru göstermeyecek veya doğru yapamayacaktır.
MrCranky

@Coyote Aslında bunu düşünüyorum, mermi ateşlemesi bunun için korkunç bir örnek, çoğunlukla aşağıdaki thedaian'ın cevabı nedeniyle. Ateş etme hemen gerçekleşmelidir. Daha iyi bir örnek, bir karakter indiğinde tetiklenen bir toz VFX olabilir - sunucu ve istemci, karakterin ne zaman atlamaya başladığıyla senkronize olur, ancak görsel ekran istemciye bırakılır. Ve animasyon ayağın yere çarptığı doğru kareye çarptığında, VFX olayı başlamalıdır. Benzer şekilde, başka bir animasyona dallanıp dallanmayacağına belirli bir animasyon karesinde karar verilmesi gerekiyorsa olaylara ihtiyaç duyulur.
MrCranky

3

Bir şekilde, animasyon bitene kadar beklemeniz ve o noktada mermi oluşturmanız gerekir.

Animasyon oranınızın sabit olduğundan eminseniz, sadece bir zamanlayıcı ayarlamak işe yarayacaktır. Küçük bir varyasyon olarak, madde işaretinin içinde, görünmeden ve hareket etmeden önce görünmez bir şekilde beklemesini sağlayan bir kodunuz olabilir.

Geliştirme platformunuza bağlı olarak, animasyonun istenen noktaya ulaştığı anı yanıtlamanıza izin verecek bir tür animasyon güncelleme fonksiyonuna veya geri aramaya sahip olabilirsiniz. Mesela Flixel ile böyle yapardım.


1
Flixel'in addAnimationCallbackyöntemi ateşleme varlığında kullanılabilir. Geri arama işlevinde, ateşleme animasyonunun geçerli çerçevesinin bir madde işareti varlığı oluşturması gereken çerçeve olup olmadığını görebilirsiniz. Eğer öyleyse, ekrana bir madde işareti ekleyebilirsiniz.
Snow Blind

2

Düz cevap: Oyuncu 'ateş' düğmesine bastığında oynatmak istediğiniz bir animasyona sahip olduğunuzu varsayar ve oynatmayı bitirdikten sonra bir mermi çıkarır. İdeal olarak, animasyon zamanını kodlamaktan kaçınmalı ve animasyon tamamlandığında mermiyi ateşlemelisiniz (platformunuza bağlı olarak bir geri arama işlevi veya başka bir şey kullanarak). Bunu yapmak için aşırı karmaşık olmayan başka bir yöntem düşünemiyorum.

Alternatif Oyun Tasarımı yanıtı: Bunu yapmak için gerçekten, gerçekten iyi bir neden olmadıkça , 'ateş' düğmesine basmaktan ve merminin görünmesini geciktirmekten kaçınırım. Animasyon gerçekten çok kısa olmadığı sürece (bir veya iki kare, maksimum, temelde bir namlu flaşı), yangın düğmesi tepkisini yavaşlatacak ve tipik bir oyuncu için sinir bozucu olacak. Mermiler çıkmadan önce bir animasyon kullanmaya devam etseniz bile (sıra tabanlı RPG'ler ve taktik oyunlar bunu yapmak için kabul edilebilir nedenler olurdu), izin vermek için bir yere "animasyonları kapat" seçeneği eklemeyi düşünürdüm oyun oyuncu daha hızlı hareket etmek istiyorsa.


Evet, yangının yavaş tepki göstermesine izin verme. Bu aynı zıplama ile ilgili genel bir sorun gibidir; animatörler büyük bir dalgalanma yaratırlar, ancak oyuncular düğmeye basar basmaz havaya uçmayı beklerler.
jhocking

2

MrCranky'nin dediği gibi; animasyon ve mantıkları birbirinden ayırmayın.

Ama en önemlisi, mantık ana kısım olarak kalmalıdır .

  • Ateş düğmesine basıldığında karakterinizin durumundaki (mantık) " eylemi " çizmeyi tetiklemelisiniz .
  • Bu eylem, çizim animasyonunu tüm parametrelerle (yaşam süresi vb.) Tetiklemelidir .
  • Çizim eylemi bittiğinde, ateş eylemini tetikleyebilirsiniz (silaha bağlı olarak bir veya daha fazla ateş edebilir)
  • Bu eylem mermi oluşturabilir ve yangın animasyonunu tetikleyebilir .

UI'yi mantıklardan kontrol etmenin, mantıklarınızı daha sonra saklayabilmenizi, yeniden kullanabilmenizi ve paylaşabilmenin tek yolu olduğunu unutmayın (yeni oluşturucu, yeni oyun, oluşturucu olmadan sunucu sürümü ...)


1

Öncelikle, kodun parçalarını ayırmak için bir olay sistemi (gözlemci deseni?) Kullanırdım. Bu sadece animasyon için değil, kesinlikle orada da geçerlidir. Ardından animasyon kodu, kodun herhangi bir kısmı birbirini bilmeye gerek kalmadan dispatchEvent (event) ve kodun başka bir bölümünü dinler.

Artık animasyon kodunun gerçekten olay dağıtıcısına (bağımlılık enjeksiyonuyla kolayca yapılabilir) bir referansı olması ve animasyonlarınızı gerçekten tanımlayan bazı XML veya JSON'a sahip olmanız gerekir. Gibi bir şey:

{
  animation: {
    name: shoot,
    length: 12,
    spritesheet: shoot.png
    event: {
      frame: 4,
      name: bulletLeavesGun,
    },
  },
}

Animasyonu yüklerken verileri okuyun ve animasyon kodunun oynatma sırasında o karede olduğunda olayı göndermesini sağlayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.