Bir oyunda saldırı ve saldırı türleri için programlama tasarımıyla ilgili bazı fikirler mi arıyorsunuz?


14

Bu yüzden, 2D uzay RTS'imize saldırmayı tanıtmaya başlıyorum (Bu Unity'de, bu yüzden bileşen odaklı). Başlangıçta "menzil içindeki düşman, hasar uygulandı" kadar basitti. Ancak, kendi gemileriyle veya yapılarıyla ilişkilendirilen birden fazla "tip" silah / saldırı olacaktır. Hasar türü ve muhtemelen atalet gibi sadece ham hasarı geçmiş diğer faktörlerin yanı sıra.

Her birimin ve yapı tipinin kendi saldırı tipi var mı? Yani her birim / yapı için saldırı tipi, hasar, efekt, menzil, parçacıklar, sprite ... vb tanımlayan bir komut dosyası yapmak Ve bir bileşen olarak eklemek?

Ya da bir saldırı türünü tanımlayan bir komut dosyası, bununla ilişkili mermi türü için bir komut dosyası yapın ... vb. Ve sonra bunları genişletin ve her birim için olanları değiştirin, her komut dosyasını birime / yapıya ekleyin.


Umarım bir anlam ifade ederim, bunu çok uzun zamandır düşünmekteyim, bir problemi çözüp çözmediğimden emin değilim, ya da sadece kendi problemlerimi uydurup kendimi bir çukura kazıyorum.

Belirli bir birim / yapı ile sınırlı olabilecek veya sınırlandırılmayacak çok sayıda saldırı türüne sahip olabileceğiniz bir oyununuz olduğunda, bunu bileşen odaklı bir tasarım ortamındaki belirli birimlere / yapılara bağlayan çerçeveyi nasıl tasarlarsınız? ?

Bu yeterince açık değilse bana bildirin.

Düzenleme: Harika yanıtlar, teşekkür ederim.

Genişletilmiş Soru:

Yanıtlar, "her nesnenin kendi saldırı komut dosyası olabilir" den "Saldırı türlerini kendi komut dosyaları olarak kullanmak ve her nesneye daha yeniden kullanılabilir bir çözüm için atamak" şeklinde değiştiği görülmektedir. Diyelim ki bir "blaster" saldırım var, belirli bir hızda kırmızı bir mermi vuruyor. Hasar, ateş hızı ve mermi boyutu onu ateşleyen birime bağlıdır. Bu birim için bir saldırı komut dosyası yapmak mı yoksa kullanmak isteyen her birimin amacına uyacak şekilde bir "blaster saldırısı" nı değiştirmek ve değiştirmek mi daha iyidir?


1
Genel oyun programlama fikirleri için, RPG FFV'nin
Code Whisperer

Yanıtlar:


12

Dürüst olmak gerekirse, bu konuda uzman değilim ama ... Bence bu, saldırıların ne kadar karmaşık ve çeşitli olduğunu düşünüyorsun. Bir RTS olduğundan, kendi saldırı türlerine sahip belki de 10-50 kadar farklı birim veya yapıya sahip olacağını tahmin ediyorum.

Seçenek 1: Biraz benzer saldırıları olacak nispeten az sayıda birim varsa, her şeyi tek bir büyük betiğe koyar ve denetçide kullanılan parametreleri tanımlarım.

Seçenek 2: Öte yandan, farklı davranışlarla çok sayıda saldırı türü tasarlarsanız, her birimi ve binanın kendi benzersiz saldırı komut dosyasını almasını sağlamak için her şeyi parçalayabilirsiniz. Bunu yaparsanız, birçok bireysel komut dosyası kapmak yaygın olarak kullanılan kod parçaları tanımlayan bir "yardımcı" komut dosyası oluşturmak isteyebilirsiniz düşünüyorum. Bu şekilde her şeyi yeniden yazmak zorunda kalmazsınız ve her şeyin nerede olduğunu bilirsiniz.

Seçenek 3: Muhtemelen yapmamanız gereken, belirli birimler gruplarının komut dosyalarını paylaşmasıdır, bu muhtemelen sizi şaşırtacak ve bir saldırı için ihtiyacınız olan kod 10 farklı komut dosyasındaysa karışıklık yaratacaktır.

Burada sana bir resim çizdim.

resim açıklamasını buraya girin


2
Cevabınız için çok teşekkür ederim. Nedense 3. seçeneğe doğru eğilmeye başlamıştım ve bunu haklı çıkarmanın bir yolunu bulmakta zorlanıyordum. Muhtemelen 2. rotaya gideceğim, her birim ortak kod her birim / binanın bir bileşeni olarak saldırıya uğrayarak paylaşılan kendi özel saldırı komut dosyasını alır. Beni seçenek 3'e götüren düşünce treniyle nereye gittiğimden emin değilim, teşekkür ederim.
Douglas Gaskell

Sorun değil, kesin bir cevap değil ama umarım yardımcı olur.
Mir

1
Büyük bir senaryoda benzer saldırıları koyarak 1 ve 2'yi melezleştirebilir ve farklı saldırıları ayırabilirsiniz
cırcır ucube

4
Şaşırdım # 3 karşı tavsiye edilir? Modüler / jenerik sınıfların tüm noktası her birimin kendi tipini tanımlaması gerekmediği için değil mi? Bir oyun bir RTS ise ve Kuşatma hasarı (genellikle "uzun menzil") bir hasar tipiyse, bir kez tanımlamak ve hasar toplarını gerçekleştirirken birden fazla topçu tarzı üniteye sahip olmasını istersiniz, böylece Kuşatma hasarı varsa hiç sinirlenmeye (yeniden dengelenmeye) gerek vardı, sadece bir sınıfı güncellemelisin?
HC_

1
"Here, I drew you a picture."bana bu
FreeAsInBeer

4

Unity hakkında çok şey bilmiyorum ve bir süredir oyun geliştirme yapmadım, bu yüzden size bu soruya genel programlama yanıtı vereyim. Cevabımı genel olarak varlık-bileşen sistemleri hakkında sahip olduğum bilgilere dayanıyorum, burada bir varlık N birçok bileşenle ilişkilendirilmiş bir sayıdır, bir bileşen yalnızca veri içerir ve bir sistem, ilişkili bileşen kümeleri üzerinde çalışır aynı varlık.

Sorun alanınız şudur:

  • Oyunda bir düşmana saldırmanın birçok yolu vardır.
  • Her geminin, yapının vb. Birden fazla saldırı yolu olabilir (her biri bir şekilde belirlenir)
  • Her saldırının kendi parçacık etkileri olabilir.
  • Saldırı, hedefte ve kullanıcıda bulunan bazı faktörleri (örneğin atalet veya zırh gibi) hesaba katmalıdır.

Çözümü aşağıdaki gibi yapılandıracağım:

  • Bir saldırının bir tanımlayıcısı vardır - bu bir dize olabilir.
  • Bir işletme saldırıyı (saldırının tanımlayıcısına dayanarak) kullanabileceğini 'bilir'.
  • Saldırı varlık tarafından kullanıldığında, karşılık gelen görüntüleme bileşeni sahneye eklenir.
  • Saldırının hedefi, saldırgan ve kullanılan saldırı hakkında bilgi sahibi olan bir mantığınız var - bu mantık ne kadar hasar verdiğinize karar vermelidir (ve atalete veya her iki varlıktan herhangi birine sahip olmanız gerekir).

Saldırılar ve varlıklar arasındaki temas noktasının olabildiğince ince olması önemlidir - bu, kodunuzu tekrar kullanılabilir tutacaktır ve aynı saldırı türünü kullanan her farklı varlık türü için yinelenen kod bulmanıza engel olacaktır. . Başka bir deyişle, size bir fikir vermek için bazı JavaScript sözde kodu.

// components
var bulletStrength = { strength: 50 };
var inertia = { inertia: 100 };
var target = { entityId: 0 };
var bullets = {};
var entity = entityManager.create([bulletStrength, inertia, target, bullets]);

var bulletSystem = function() {
  this.update = function(deltaTime, entityId) {
    var bulletStrength = this.getComponentForEntity('bulletStrength', entityId);
    var targetComponent = this.getComponentForEntity('target', entityId);
    // you may instead elect to have the target object contain properties for the target, rather than expose the entity id
    var target = this.getComponentForEntity('inertia', targetComponent.entityId);

    // do some calculations based on the target and the bullet strength to determine what damage to deal
    target.health -= ....;
  }
};

register(bulletSystem).for(entities.with(['bullets']));

Üzgünüm bu cevap biraz 'sulu'. Sadece yarım saat öğle yemeği molam var ve Unity hakkında tam bir bilgi sahibi olmadan bir şey bulmak zor :(


3

Bir birim / yapı / silah saldırdığında, muhtemelen saldırganı ve savunmacıyı (veya savunucuları) alan bir Saldırı (tüm eğlenceli detaylarınızla alt sınıfta) oluştururdum. Saldırı daha sonra hedef / savunmacı ile etkileşime girebilir (yavaş, zehir, hasar, durumu değiştir), kendini çizebilir (ışın, ışın, kurşun) ve bittiğinde kendini imha edebilir. Birden fazla zehir saldırısı gibi bazı sorunları öngörebilirim, bu yüzden hedefleriniz Saldırı'nın etkileşime girdiği Hasarlı bir arayüz uygular, ancak bence bu modüler ve değişmesi esnek, uygulanabilir bir yaklaşım.

Genişletilmiş Yanıt
Bu yaklaşımla blaster saldırısına bu şekilde yaklaşırım . Diğerlerinin kendilerine cevap vermesine izin vereceğim.

Birimlerimin temel saldırı istatistikleri / yöntemleri ile bir IAttacker arayüzü veya sınıfı uygulamasını isterdim. Bir IAttacker, Değiştirilebilir bir saldırıya saldırdığında, kendisini ve hedefini (IAttacker ve IDamalable veya belki de IDamageables topluluğu) geçirerek kendine özgü bir Saldırı oluşturur. Saldırı, IAttacker'dan ihtiyaç duyduğu istatistikleri alır (yükseltmeler sırasındaki değişikliklerden veya bunun gibi bir şeyden kaçınmak için - Saldırı'nın başlatıldıktan sonra istatistiklerini değiştirmesini istemiyoruz) ve özel istatistiklere ihtiyaç duyuyorsa, IAttacker'ı gerekli türü (ör. IBlasterAttacker) ve özel istatistikleri bu şekilde alır.

Bu yaklaşıma göre, bir BlasterAttacker'ın sadece bir BlasterAttack oluşturması gerekiyor ve BlasterAttack gerisini halleder. BlasterAttack alt sınıfını oluşturabilir veya ayrı bir FastBlasterAttacker, MegaBlasterAttacker, SniperBlasterAttacker, vb. Oluşturabilirsiniz ve her birinin saldırı kodu aynıdır (ve muhtemelen BlasterAttack'tan devralınmıştır): BlasterAttack'ı oluşturun ve kendimi ve hedef (ler) i içeri aktarın. BlasterAt handles .


Temelde, birim bir IAttacker arabiriminden miras alır (buna zaten sahibim) ve "düşman" için IDamalable arabirimi var (buna da sahip). Saldırgan saldırdığında bir BlasterAttack (veya türetilmiş sınıf) çağrılır. Bu "saldırı" İhtiyaç duyduğu verileri IAttacker'dan alacak ve mermi isabet ettiğinde IDamalable'a uygulayacak mı? Merminin kendisi BlasterAttack sınıfını içeriyor mu, böylece ateşlendikten sonra artık IAttacker'daki değişikliklerden etkilenmez ve hasarını / etkilerini ancak mermi isabet ederse IDamaeable üzerine uygulayabilir.
Douglas Gaskell

"Bir BlasterAttack (veya türetilmiş sınıf)" olarak adlandırdığınızda, BlasterAttack'ın oluşturulduğunu söyleyebilirim. O kadar BlasterAttack bu yeni oluşturulan örnek, ışın (veya madde işareti veya ışın ya da her neyse) temsil olduğunu mermi. BlasterAttack, ihtiyaç duyduğu istatistikleri IAttacker ve IDamaeable nesnelerinden kopyalar: konumlar, saldırgan istatistikleri vb. BlasterAttack daha sonra kendi konumunu izler ve varsa "kişi" ye hasar verir. Hedefi (hedefin eski konumu) kaçırır veya ulaşırsa ne yapacağınızı bulmanız gerekir. Yere mi yaktınız? Kaybolmak? Çağrınız.
ricksmt

Etki alanı Saldırısı için, kim menzilde ve menzil dışında kimin ateş ve çarpma arasında değişebileceğinden, küresel (düşman) birimler koleksiyonuna erişmek isteyebilirsiniz. Elbette, BlasterAttack için de benzer bir tartışma yapılabilir: ilk hedefinizi kaçırıyorsunuz, ancak arkasındaki adama vuruyorsunuz. Benim tek endişem, bir çok Düşman üzerinden yinelenen Saldırılara sahip olabilmenizdir. Bu bir performans sorunu.
ricksmt

Ah, bu mantıklı. Kaçırılan bir saldırı için merminin önceden belirlenmiş bir menzili / ömrü olacaktır. Bu ömrünün bitiminden önce başka bir şeye çarparsa, çarpıştığı katı gövdeye sahip olan herhangi bir nesneye bir referans alacak ve hasar bu şekilde uygulanacaktır. Aslında tüm mermiler bu şekilde çalışacaklar, sadece ne seyahat ettiklerini "neye" gittiklerini bilmiyorlar (füzeler gibi güdümlü mermiler hariç). AEO efektleri, hedefte bir küre çarpıştırıcısını etkinleştirebilir ve içindeki tüm nesneleri alabilir. Yardım için teşekkürler.
Douglas Gaskell

Sorun değil. Yapabildiğim için memnunum. Unity'nin tüm bu çarpışma olaylarını kolaylaştırdığını unutma.
ricksmt
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.