Bir noktada bir motor oyun hakkında uzmanlaşmalı ve Bilmeniz GEREKİR. Burada bir tanjantla gideceğim.
Kaynakları bir RTS'de alın. Bir oyun olabilir Credits
ve Crystal
başka Metal
vePotatoes
OO kavramlarını düzgün kullanmalı ve maks. kod yeniden. Burada bir kavram olduğu açıktır Resource
.
Bu yüzden kaynakların aşağıdakilere sahip olduğuna karar veriyoruz:
- Ana döngüdeki bir kanca, kendilerini arttırmak / azaltmak için
- Geçerli tutarı almanın bir yolu (döndürür
int
)
- Keyfi olarak çıkarma / ekleme için bir yol (oyuncular kaynak aktarımı, satın alma ....)
Bu a fikrinin Resource
bir oyundaki öldürme veya puanları temsil edebileceğine dikkat edin ! Çok güçlü değil.
Şimdi bir oyun düşünelim. Bir miktar para birimiyle başa çıkıp çıktıya ondalık nokta ekleyerek bir çeşit paraya sahip olabiliriz. Yapamayacağımız şey "anlık" kaynaklar. Gibi "güç şebekesi üretimi" demek
Diyelim ki InstantResource
benzer yöntemlere sahip bir sınıf ekliyorsunuz . Artık motorunuzu kaynaklarla kirletmeye başlıyorsunuz.
Sorun
RTS örneğini tekrar alalım. Varsayalım ki oyuncu Crystal
başka bir oyuncuya bağışta bulunursa . Gibi bir şey yapmak istiyorsunuz:
if(transfer.target == engine.getPlayerId()) {
engine.hud.addIncoming("You got "+transfer.quantity+" of "+
engine.resourceDictionary.getNameOf(transfer.resourceId)+
" from "+engine.getPlayer(transfer.source).name);
}
engine.getPlayer(transfer.target).getResourceById(transfer.resourceId).add(transfer.quantity)
engine.getPlayer(transfer.source).getResourceById(transfer.resourceId).add(-transfer.quantity)
Ancak bu gerçekten çok dağınık. Genel amaçlı ama dağınık. Zaten bir dayatmasına rağmen resourceDictionary
, kaynaklarınızın isimleri olması gerektiği anlamına geliyor! VE oyuncu başına, bu yüzden artık takım kaynaklarına sahip olamazsınız.
Bu "çok fazla" soyutlama (itiraf edeceğim mükemmel bir örnek değil), bunun yerine oyununuzun oyuncuları ve kristali olduğunu kabul ettiğiniz bir noktaya çarpmalısınız, o zaman sadece (örneğin)
engine.getPlayer(transfer.target).crystal().receiveDonation(transfer)
engine.getPlayer(transfer.source).crystal().sendDonation(transfer)
Bir sınıf ile Player
ve bir sınıf bireyin nesne otomatik bağış gönderen / transferi için HUD şeyler gösterecektir.CurrentPlayer
CurrentPlayer
crystal
Bu, motoru kristalle, kristal bağışını, mevcut oyuncular için HUD'daki mesajları ve tüm bunları kirletir. Okuması / yazması / bakımı hem daha hızlı hem de daha kolaydır (bu, daha hızlı olmadığı için daha önemlidir)
Son açıklamalar
Kaynak durumu parlak değil. Umarım yine de noktayı görebilirsiniz. Belirli bir oyunun ihtiyaç duyduğu ve tüm kaynak kavramları için geçerli olan şeylerin "kaynaklar motora ait olmadığını " göstermiş olduğum bir şey varsa ÇOK farklı şeylerdir. Genellikle bulacağınız 3 (veya 4) "katman"
- "Çekirdek" - bu motorun ders kitabı tanımı, olay kancaları olan bir sahne grafiği, gölgelendiriciler ve ağ paketleri ve soyut bir oyuncu kavramı ile ilgileniyor
- "GameCore" - Bu, oyun türüne oldukça geneldir, ancak tüm oyunlara değil - örneğin RTS'deki kaynaklar veya FPS'lerde mühimmat. Oyun mantığı burada sızmaya başlar. Burası daha önceki kaynak anlayışımız olacaktı. Çoğu RTS kaynağı için anlamlı olan bu şeyleri ekledik.
- "GameLogic" Gerçek oyun ÇOK özel yapılır.
creature
Veya ship
veya gibi adlara sahip değişkenler bulacaksınız squad
. Kullanımı devralma tüm 3 kat yayılan sınıfları alırsınız sizin (örneğin Crystal
bir olduğunu Resource
hangi bir olduğunu GameLoopEventListener
söylemek)
- "Varlıklar" diğer oyunlarda işe yaramaz. Örneğin AI betiklerini yarı ömür 2'de birleştirin, aynı motorla bir RTS'de kullanılmayacaklar.
Eski bir motordan yeni bir oyun yapmak
Bu ÇOK yaygındır. Aşama 1, katman 3 ve 4'ü (ve oyun tamamen farklı bir türse 2) sökmektir. Eski bir RTS'den bir RTS yaptığımızı varsayalım. Hala kristal ve malzeme değil, kaynaklarımız var - bu nedenle katman 2 ve 1'deki temel sınıflar hala anlamlıdır, 3 ve 4'te atıfta bulunulan tüm kristal atılabilir. Biz de öyle. Ancak bunu yapmak istediğimiz şey için bir referans olarak kontrol edebiliriz.
Katman 1'deki kirlilik
Bu olabilir. Soyutlama ve performans düşmandır. Örneğin UE4 çok sayıda optimize edilmiş kompozisyon örneği sağlar (bu nedenle X ve Y'yi isterseniz biri X ve Y'yi birlikte gerçekten hızlı yapan bir kod yazdı - her ikisini de yaptığını biliyor) ve sonuç olarak oldukça büyük. Bu fena değil ama zaman alıcı. Katman 1, "verileri gölgelendiricilere nasıl aktardığınız" ve şeylere nasıl animasyon uyguladığınıza karar verecektir. Projeniz için en iyi yolu yapmak DAİMA iyidir. Sadece geleceği planlamaya çalışın, kodu yeniden kullanmak arkadaşınızdır, mantıklı olduğu yeri miras alın.
Katmanları sınıflandırma
LASTLY (söz veriyorum) katmanlardan çok korkma. Motor, motorların hemen hemen aynı şekilde grafiksel olarak aynı şekilde çalıştığı (ve sonuç olarak ortak bir noktaya sahip olduğu) sabit işlevli boru hatlarının eski günlerinden eski bir terimdir. geliştiricilerin ulaşmak istedikleri her türlü etkiyle. AI, motorların ayırt edici özelliğiydi (sayısız yaklaşım nedeniyle), şimdi AI ve grafikler.
Kodunuz bu katmanlara dosyalanmamalıdır. Ünlü Unreal motorunun bile her biri farklı bir oyuna özgü birçok farklı versiyonu vardır. Değişmeyen birkaç dosya (belki de veri yapıları dışında) vardır. Bu iyi! Başka bir oyundan yeni bir oyun yapmak istiyorsanız bu süre 30 dakikadan fazla sürecektir. Anahtar planlamak, kopyalamak ve yapıştırmak için hangi bitleri ve neyi geride bırakmak gerektiğini bilmek.