Nesne yönelimli bir dilde oyun motoru nasıl tasarlanır? [kapalı]


26

Ne zaman herhangi bir nesne yönelimli dilde bir oyun yazmayı denesem, her zaman karşılaştığım ilk sorun (ne tür bir oyun yazacağımı düşündükten sonra) motorun nasıl tasarlanacağıdır. Mevcut kütüphaneleri veya SDL gibi çerçeveler kullanıyor olsam bile, yine de her oyun için bazı kararlar vermek zorunda olduğumu, menüleri yönetmek için bir devlet makinesi kullanıp kullanmadığımı, kaynak yükleme için ne tür bir sınıf kullanacağımı vb. Buluyorum.

İyi bir tasarım nedir ve nasıl uygulanmalı? Yapılması gereken bazı değişimler ve artıları / eksileri nelerdir?


12
Darbeye devam etmenin ve analiz felci geçirmekten ziyade oradan kaçınmanın yanlış tarafı ne?
Komünist Ördek

7
@TommunistDuck Çünkü devam eden itici güç, önceki projelerimin hepsinde benim yaptığım yaklaşımdır - ve her biri birkaç ay sonra herhangi bir yeni özelliğin eklemek için anıtsal çaba ve karmaşıklık gerektirdiğini fark ettiğimde duvara çarpıyor. Şu anda motorlarımı tekrar yazmak için oyunu kendim yazdığımdan daha fazla harcıyorum, bu yüzden biraz uzun zaman önce ve planlama yaparak kendimi uzun vadede zaman kazanacağımı umuyorum.
extropic motor

3
@chuzzum, iyi nokta. O zaman tavsiye edebileceğim bir şey C4 motorunun mimarisini kontrol etmek; terathon.com/c4engine/images/architecture.png İhtiyacınızdan çok daha yüksek bir seviyede olabilir, ancak size bazı fikirler verebilir ;-)
Komünist Ördek


3
Ayrıca bu soru biraz belirsizdir. Belki örneklerinden birini al ve bunu daha derin bir soru yap.
Tetrad

Yanıtlar:


24

Birinin 'Bunu yapmak zorundasın ve bunu ve bununla, bu desenle X'i kullanan bu yuvaları' diyebileceğinden şüpheliyim.

Ancak, bazı yararlı kaynaklar:
Enginuity - Gamedev.net'te bir dizi motor yapım makalesi.
Oyun Kodlama Tamamlandı - Bu kitabın sahibiyim ve oyun programlamanın her (neredeyse, her) yönünü gözden geçiriyor. Ayrıca kitap boyunca inşa edilmiş bir motoru var.
Oyun Motoru Mimarisi - Bu, motor tasarımı için bir başka harika kitap.
C4 Motor Düzeni - Benim yorumumdan alınmış, ancak bu motorun her bir parçasını birbirine monte etmenin üst düzey bir yolunu gösteriyor.

Bunlar ihtiyacınız olan için biraz fazla olabilir, ama bir şey hakkında fazla bir şey bilemezsiniz ve onlardan iyi bir plan alacağınıza eminim.

EDIT: Gamedev makalelerinin yeni siteden bu yana arşivlendiğini unutmuşum :)


Enginuity bağlantısı koptu ve makalelerin googlingi artık web'de olmadıklarını gösteriyor gibiydi. (?) Kitaplar yine de iyi kaynaklara benziyor ve daha fazla programlama kitabı için sürekli göz
atıyorum

Ayrıca, ilk yorumunuzla ilgili olarak, kimsenin her oyuna uyan bir usta planı bulmasını beklemiyorum. Birkaç oyun geliştirme sürecinde, ortak kalıpların çok fazla artma eğiliminde olduğunu fark ettim, bu yüzden diğer insanların oyunlarında ne kullandıklarını merak ettim.
extropic motor

1
Bağlantı düzeltildi.
Komünist Ördek

Enginuity için +1. @chuzzum Birkaç oyun motorunu inceleyin, size ilham vermelerini ve kendiniz için en uygun mimariyi elde etmelerini sağlayın. Artı: Oyun motoru bileşeninizi hiyerarşik temelli yapmak genellikle daha iyidir, bkz. Cowboyprogramming.com/2007/01/05/evolve-your-heirachy
Dave O.

1
Bunun bir araya getirilmesi gereken motor olduğunu söyleyemem , daha çok varlık çerçevesi parçası.
Komünist Ördek

7

Örnek olarak, şu anki roguelike projem nasıl yapılandırılmıştır (Java'da). Bir 2D grafik motoru kullanıyor, bu yüzden render kodunun çoğu benim için çoktan halledildi. Eleştiri memnuniyetle karşılandı.

class Game
Bu sınıf, oyunun mevcut durumunu yöneten durum makinesini kurar. (bir menüde vs. yeni bir oyuna başlama - kaydedilmiş bir oyuna oynama)

interface State
Her bir State sınıfı iki döngü içerir: mantığı güncellemek için bir döngü ve oluşturma için bir döngü. Ayrıca, Gamesınıfı aramak ve farklı bir durumda değişiklik talep etmek için kod içerirler .

class ResourceManager
GameGerekli tüm kaynakları yükleyen ve bunlara erişime izin veren sınıf tarafından başlatılan bir tekil . Bu tasarımdan hoşlanmıyorum, çünkü kaynakların farklı seviyelerde yüklenmesini / boşaltılmasını zorlaştırıyor. Eğer baştan başlasaydım, muhtemelen bunu farklı şekilde tasarlardım.

class Map
Harita, bir dizi karo ile haritadaki tüm yaratık ve öğelerin bir listesini içerir. Oldukça basit bir sınıf.

class Creature
Yaratıklar hareket hesaplamaları dahil kendileri hakkında bilgi içerir (hangi Haritaya girdiklerini bilmelerini ve engelleri bulmak için sorgulayabilmelerini gerektirir). Bunu yapıp yapmadığına ya da bir çeşit yönetici sınıfına sahip olup olmadığına karar vermek, tüm canlılar için onunla ilgilenmek.

interface AITask
Yaratıklar, yaratığın mantık döngüsü her çalıştırıldığında yürütülen bir AITasks listesine sahip olabilir. AITask, yaratığa komutlar veren kendi mantık döngüsüne ve görevin başarıyla tamamlanıp tamamlanmadığını belirleyen bir sonlandırma koşuluna sahiptir.

interface UIElement
Bu motor için kendi kullanıcı arayüzümü uyguladım. Her UIElement'in bir oluşturma döngüsü ve bir mantık döngüsü vardır. Ayrıca klavye / fare girişini işlemek için bir döngü var. Tüm öğelerin ebeveynlerinden sonra oluşturulan bir dizi alt öğesi olabilir ve klavye / fare girişini üstlenebilir. Bu, örneğin alt menülere sahip menülere sahip olmanızı sağlar.


Bu konuda tam olarak yanlış giden ne? Bana çok iyi geliyor.
Komünist Ördek

@ TheCommunistDuck Seçtiğim örneklerde gerçekten ortaya çıkmıyor, ancak bu kodla ilgili birçok sorunum var. ResourceManager sınıfı onlardan biri, ancak devletlerle de sorunum var - büyük bir çoğalmasıyla sonuçlandım ve çok fazla kod kopyaladım. Özellikle oyuncunun herhangi bir zamanda çok fazla seçeneğe sahip olduğu bir RPG'de, gerçekten karmaşık durum grafikleriyle sonuçlanabilirsiniz. Örnek: büyü yapmak. NormalState öğesinden gider -> SelectSpellState -> SelectTargetState -> InvalidTargetState (başarısız olursa) -> DoSpellAnimationState -> NormalState. Ve bu sadece bir eylem.
extropic motor

1
Hayır hayır. NO . HAYIR. Lütfen hayır. Bekle, hoşuna gitmediğini söylemiştin.
Bartek Banachewicz

6

Yapılması gereken ilk önemli nokta, bu sorunun cevabını 'iyi' bir cevabın olmamasıdır.

Doğru cevaba en yakın şey şöyle bir şey olabilir: Oyunun türüne, hedef platformuna, kısıtlamalarına (zaman) vb. Bağlıdır.

Burada, başkalarının bu sorunu nasıl cevaplamaya çalıştıklarını (geçmişte bu konuda bilgi bulmaya çalıştığım gibi) gösteren gerçekten iyi makaleler olduğunu söyledi.
Komünist ördek oyunun enginuity makalesinde bahsettiği gibi oyun mimarisinin bazı bölümlerini anlamama yardımcı oldu.

Mevcut tasarımım Quake3 / Doom3'ün bir melezi ve biraz da .NET sınıf kütüphanesinin bir parçası :)

İki kütüphanem var (statik veya dinamik nasıl oluşturmak / teslim etmek istediğinize bağlıdır) Frameworkve Library.

Kütüphane, oyun yazılımı yapımında yardımcı olacak tüm yardımcı sınıfları içerir ancak bu tür ürünlerle sınırlı değildir. yani, oyun kodu için optimize edilmiş, ancak bağlantılı bir listenin hizmetine ihtiyaç duyan herhangi bir şey tarafından kullanılabilen bağlantılı bir listenin uygulanmasına sahiptir.

Çerçeve, onu çağırmak istersen, 'motorun bağırsaklarıdır. Bunların çoğu Quake3'ün tasarım felsefelerini izler (daha çok nesne yönelimli bir şekilde). İçerdiği CLI , zamanlama yönetimi, işletim sistemi özel kodu ve sonunda ağ katmanları vb

Bu ikisi daha sonra üretilen gerçek uygulamaya karşı bağlanır. GameEğer oyun özel kodu içeren, istersen. Quake3 de aynı şekilde hangi mod'un oynandığına bağlı olarak DLL yükler.

Size burada bir yapı hakkında fikir vermek için, her bir lib için klasörler ve içeriklerin hızlıca dağılması:


  • iskelet
    • (Uzman dosya yönetimi sınıfları, Metin Baskısı sınıfları (örneğin, CLI'ye) ve günlüğe kaydetme vb.)
      • Müşteri (Çerçevenin “oyuna katılan / oyuna bağlı kişi” olarak gördüğü şeyi temsil eden sınıflar)
      • Sunucu (çerçeve ile bağlantıyı yönetme ve yürütücüleri yönetme sınıfları)
    • Platform (Klavye / fare / kontrolcü sınıfları kullanma, getTime () gibi işletim sistemine özgü rutinler)
    • Sistem (hata mesajlarının yazdırılmasına yardımcı olmak için bir hata sınıfı gibi çok düşük seviye sınıfları, Zamanlama sınıfları ve CLI'nın kendisi.)
    • Render (kendi kendini açıklayıcı)
    • vb.

  • Kütüphane
    • Koleksiyonlar (veri koleksiyonlarını temsil eden sınıflar, bağlantılı listeler / karma tablolar vb.)
    • Matematik (Vektörler ve matrisler gibi temel matematik yardımcı sınıfları)
    • vb.

HTH! Size bazı işaretçiler vermeli ...


İçin Alternatif bağlantı Enginuity Serisi
Musaffa

-3

Düşünülmesi gereken şeyler

  • Nesne yönelimli diller, genellikle birinci sınıf işlevlere sahip olmadıkları veya tüm verilerin nesne olmadığı (Java'da tam sayı veya kayan nokta gibi) sorunlara sahiptir. Tasarım kalıpları bu problemleri birkaç kalıpla ele almaktadır. Kodlamak genellikle daha hızlıdır ve bunları yapabilen dili kullanmak için kullanmak kolaydır (birinci sınıf nesneler); örneğin, Python (aynı zamanda nesneye yönelik tasarıma izin verir), Daha yavaş hızınız olacaktır.
  • En az AI olayına
  • Hoare mantığı, en azından kodunuzu test etmek için ön koşulları ve son koşulları kullanın
  • Ajanlar, Quake varlıklarına bakın
  • İlişkisel Veritabanları, veri depolamak için güçlü bir yol

İyi tasarım

  • ER diyagramı yap
  • düzeltmek
  • Veritabanınızı, nesnelerinizi veya veri verilerinizi ondan oluşturun.

Veri programlama için anahtardır. Verilerinizi iyi tasarlarsanız, algoritma genellikle onlardan ortaya çıkar (bilgisayarlı determinant gibi bazı sayısal algoritmaları saymazsanız).


-1 çünkü bu cevap çok belirsiz ve kafa karıştırıcı. İlişkisel veritabanlarının kesinlikle bir OO motoruyla ilgisi yoktur. İngilizcenin ilk diliniz olmadığını, ancak ilk paragrafınızda ne demek istediğinizi açıklayabilir misiniz? Çelişkili görünüyor (OO dillerinin sorunları var ama tasarım desenleriyle dilde programlanması daha kolay… tasarım desenleri neredeyse her zaman OO yapıları olsa bile).
Komünist Ördek

@duck Çelişkili? OO'nun diğer dillerde olmayan problemleri var, DP bunları çözmek için bkz. C2.com/cgi/wiki?DesignPatternsInDynamicProgramming .
user712092

@Duck 1) SQL'i C ++ 'da kullanabilirsiniz 2) ER'den nesnelerin niteliklerini çıkartabilirsiniz (önerilen uygulama olmasa da) 3) İlişkilerden veri yapılarını alabilirsiniz (bu bir liste çünkü elemeleri willm'de yeniden sıralamam gerekiyor bu hızlı bir karmaşaya ihtiyacım var çünkü)
user712092

@Duck özür dilerim, yeniden düzenleyerek hata yaptım. "DP'nin XY'ye daha kolay" olduğunu iddia etmek istemedim ama "birinci sınıf yapabilen diller ...". :)
user712092

Evet, işlevsel dillerin avantajları olabilir. Ancak, tarafsız bir şekilde bile, bir OO yaklaşımının bir gamedev perspektifinden mantıklı geldiğini hissediyorum Ayrıca, herhangi bir yerde ilişkisel bir veritabanına ihtiyaç duymanız için hiçbir neden yoktur . Elbette, faydalı olabilirler. Bununla birlikte, hiçbir yerde gerekli bir bileşen haline gelmez.
Komünist Ördek
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.