Video oyunları ne kadar nesneye yöneliktir? [kapalı]


18

Video oyunları, özellikle de büyük 3D projeleri tarafından nesne yönünün ne ölçüde kullanıldığını hep merak ettim. Ben de o serin olacağını hesaba katmak trollve werewolfonun özelliklerini miras enemyve bazıları üzerine yazıldı. Ama belki dersler pratik olamayacak kadar ağır, bilmiyorum ...


2
Kişi nesne yönelimini nasıl ölçebilir (hatta nesnel olarak niteleyebilir)? Meyers veya Dahl-Nygaards'da bir cevap ister misiniz?

Açıkçası o kadar ağırlar ki, ağır bir OO tabanlı dil endüstri standardı.
Komünist Ördek

4
C ++ demek istiyorsan, bu tür-güvenli jenerik programlamayı hızlı-bilinçli bir şekilde keşfetmek için iyi bir dil olduğu için seçildi; birkaç OOP özelliği, sadece geriye dönük uyumluluk için tutulan talihsiz bir yanlış tasarımdır. ;)

Yanıtlar:


20

Örneğinize gelmek için video oyunlarındaki Entites hakkındaki düşüncelerimi açıklayacağım. Nesnelerin ve sınıfların genel avantajını ve dezavantajını, ne Video Oyunları'ndaki tüm rollerini tartışmayacağım.

Küçük video oyunlarındaki varlıklar çoğunlukla ayrı sınıflarla tanımlanır, büyük oyunlarda genellikle dosyalarda tanımlanır. İzlenecek iki genel yaklaşım vardır:

Uzatma : En örnekte Trollve Werewolfuzatacaktır Enemyuzanır hangi Entity. Entityhareket, sağlık vb. temel şeylerle ilgilenirken Enemy, alt sınıfları düşman olarak ifade eder ve başka şeyler yapar (Minecraft bu yaklaşımı izler).

Bileşen tabanlı : İkinci yaklaşım (ve benim favorim) Entitybileşenleri olan bir sınıftır. Bir bileşen Moveableveya olabilir Enemy. Bu bileşenler hareket veya fizik gibi bir şeyle ilgilenir . Bu yöntem uzun Uzatma zincirlerini kırar ve çatışmaya girme riskini en aza indirir. Örneğin: Hareket edebilen bir Karakterden miras alırlarsa, hareket ettirilemeyen Düşmanları nasıl yapabilirsin? .

World of Warcraft veya Starcraft 2 gibi büyük video oyunlarında, Varlıklar sınıf değildir, tüm Varlığı belirten veri setleri değildir. Komut dosyası da önemlidir, çünkü Varlığın bir Sınıfta değil, bir Komut Dosyasında (benzersizse hareket etme gibi şeyler değil) ne tanımladığınızı tanımlarsınız.

Şu anda bir RTS programlıyorum ve Girişler, Beceriler, Öğeler ve oyundaki dinamik her şey için Tanımlayıcı ve Komut Dosyaları ile bileşen tabanlı yaklaşımı kullanıyorum.


2
Araya giren sesler. Ancak yalan söylemeyeceğim, componentbu bağlamda a'nın ne olduğunu bilmiyorum . Bir bağlantı çok takdir edilecektir.
vemv

Bileşen, tek bir işlevsellikten sorumlu olan bir varlıktır. Bileşen tabanlı varlığın bir bileşeni (varsa) kendisinden devralmayacaktır. Sahiplik, bir varlığın davranışlarından birini değiştirerek bileşenlerinden birini devre dışı bırakabileceğini ima eder. Klasik Eklenti paradigmasında davranış, bir süper sınıfa ait olmaktan kaynaklanır. Bir varlık bir bileşen olabilir ve bir bileşen isterseniz sınıf veya yapı olarak modellenebilir.
FxIII

Bileşen (bazen Varlık sistemleri olarak da adlandırılır) - bu blogda fikirler için arama yapabilirsiniz t-machine.org Varyantlar var, ancak temel fikir, bir bileşenin özel amaçlı bir nesne olması ve aktörünüzün bir model oluşturmak gibi bir grup bileşeni birbirine bağlaması Legos'tan.
Patrick Hughes

2
Oyun geliştirme hakkında bir blog başlattım ve bununla ilgili ilk blog girişimi yazdım. Yeni bir şey yok, ama biraz kodla: jagamedev.wordpress.com/2011/06/26/…
Marco

23

Hem trolün hem de kurtadamın niteliklerini düşmandan miras almasının ve bazılarının üzerine yazmasının harika olacağını düşünüyorum.

Ne yazık ki 90'larda popüler olan polimorfizme bu yaklaşım, pratikte kötü bir fikir olduğunu göstermiştir. Düşman listesine 'kurt' eklediğinizi düşünün - iyi, kurtadamla bazı özellikleri paylaşıyor, bu yüzden bunları paylaşılan bir temel sınıfta birleştirmek istiyorsunuz, örn. 'Wolflike'. Artık düşman listesine 'İnsan' ekliyorsunuz, ama kurtadamlar bazen insanlardır, bu yüzden 2 ayak üzerinde yürümek, konuşabilmek, vb. Gibi özellikleri de paylaşırlar. İnsanlar ve kurtadamlar için 'İnsansı' ortak bir üs oluşturuyor musunuz? ve sonra kurt kurtlarını WolfLike'tan türeyen durdurmanız mı gerekiyor? Yoksa ikisinden de miras alırsınız - bu durumda, Humanoid'deki bir şey WolfLike'daki bir şeyle çakıştığında hangi özellik öncelik kazanır?

Sorun şu ki, gerçek dünyayı bir sınıf ağacı olarak denemek ve modellemek etkisizdir. Herhangi bir 3 şey alın ve muhtemelen davranışlarını paylaşılan ve paylaşılmayan olarak değerlendirmek için 4 farklı yol bulabilirsiniz. Bu nedenle, birçoğu, bir nesnenin bütünü oluşturan birkaç küçük nesneden oluştuğu ve daha küçük nesnelerin, istediğiniz davranışı oluşturmak için değiştirilebileceği veya değiştirilebileceği modüler veya bileşen tabanlı bir modele dönüşmüştür. Burada sadece 1 Düşman sınıfınız olabilir ve nasıl yürüdüğüne dair alt nesneler veya bileşenler (örn. Bipedal vs. Quadrupedal), saldırı yöntemleri (örn. Isırık, pençe, silah, yumruk), cildi (yeşil) troller için, kurtadamlar ve kurtlar için tüylü) vb.

Bu hala tamamen nesne yönelimlidir, ancak yararlı bir nesnenin ne olduğu kavramı, eskiden ders kitaplarında yaygın olarak öğretilenlerden farklıdır. Ağacın uçlarında çeşitli soyut sınıflardan ve birkaç somut sınıftan oluşan büyük bir miras ağacına sahip olmak yerine, genellikle soyut bir kavramı temsil eden (örneğin 'düşman') ancak daha soyut kavramları temsil eden daha somut sınıflar içeren sadece 1 beton sınıfınız vardır. (örn. ataklar, cilt tipi). Bazen bu ikinci sınıflar en iyi 1 miras düzeyi (örneğin, bir temel Saldırı sınıfı ve belirli saldırılar için türetilmiş birkaç sınıf) aracılığıyla uygulanabilir, ancak derin miras ağacı kaybolur.

Ama belki dersler pratik olamayacak kadar ağır, bilmiyorum ...

Çoğu modern dilde, sınıflar 'ağır' değildir. Kod yazmanın başka bir yoludur ve genellikle daha kolay sözdizimi dışında, yazdığınız prosedürel yaklaşımı sararlar. Ama elbette, bir işlevin yapacağı bir sınıf yazmayın. Sınıflar kendiliğinden daha iyi değildir, sadece kodun yönetilmesini veya anlaşılmasını kolaylaştırdığı yerlerde.


3
Bu yanıtı seviyorum :)
Czarek Tomczak

8

"Çok ağır" ile ne demek istediğinizden emin değilim ama C ++ / OOP, başka bir yerde kullanılan aynı iyi nedenlerle oyun geliştirmenin ortak dili.

Üfleme önbellekleri konuşmak bir dil özelliği değil, bir tasarım meselesidir. C ++ son 15-20 yıldır oyunlarda kullanıldığından çok kötü olamaz. Akıllı telefonların çok sıkı çalışma süresi ortamlarında kullanıldığı için Java çok kötü olamaz.

Şimdi asıl soruya bakalım: uzun yıllar boyunca sınıf hiyerarşileri derinleşti ve bununla ilgili sorunlardan muzdarip olmaya başladı. Daha yakın zamanlarda sınıf hiyerarşileri düzleşti ve mantık güdümlü kalıtımdan ziyade kompozisyon ve diğer veri güdümlü tasarımlar yapılıyor.

Hepsi OOP ve yeni yazılım tasarlarken hala temel olarak kullanılıyor, sadece sınıfların somutlaştırdıklarına farklı odaklanılıyor.


2

Sınıflar herhangi bir çalışma zamanı yükü içermez. Çalışma zamanı polimorfizmi sadece bir fonksiyon göstergesinden geçiyor. Bu genel giderler, Çizim aramaları, eşzamanlılık senkronizasyonu, disk G / Ç, çekirdek modu anahtarları, zayıf bellek konumu, dinamik bellek ayırmanın aşırı kullanımı, zayıf algoritma seçimi, komut dosyası dillerinin kullanımı ve liste gibi diğer maliyetlerle karşılaştırıldığında son derece azdır. devam eder. Nesne yöneliminin kendisinden önce gelenleri yerine koymasının bir nedeni var ve bunun nedeni çok daha iyi.


Çeşitli polimorfik tipler arasında sevkıyat kötü hafıza yeri verecek şekilde yapılır. C ++ vtables veya Objective-C IMP önbellekleme gibi en hafif uygulamalarda bile , farklı türdeki nesnelerle uğraşmak için polimorfizmi kullanırsanız , önbelleklerinizi patlatacaksınız. Tabii ki polimorfizmi kullanamazsanız, vtable önbelleğinizde kalır veya IMP önbelleğe alınan mesaj doğru yere götürür, ancak neden rahatsız oluyor? Java veya C # 'da maliyet daha ağırdır ve JavaScript veya Python'da maliyet hala daha yüksektir.

1
@Joe Wreschnig: Bu daha yavaş dilleri kullanıyorsanız, OO'nun maliyeti, yorumlama / JIT gibi diğer maliyetlerle karşılaştırıldığında önemsizdir. Daha da önemlisi, zayıf bellek konumu hakkında ne istediğinizi teorikleştirebilirsiniz, ancak gerçek şu ki, CPU'daki şube tahmini, sıra dışı yürütme ve benzer özellikler neredeyse tamamen maliyeti düşürmektedir. Yoksa neden bu kadar yüksek performanslı yazılım nesne yönelimi kullanılarak yazılıyor?
DeadMG

1

Dikkat edilmesi gereken bir şey, nesne yönelimli kod kavramlarının genellikle dillerdeki uygulamalarından daha değerli olduğudur. Özellikle, bir ana döngüdeki varlıklarda 1000'lerce sanal güncelleme çağrısı yapmak zorunda kalmak, 360 veya PS3 gibi platformlarda C ++ önbelleğinde karışıklığa neden olabilir - böylece uygulama uğruna "sanal" veya "sınıf" anahtar kelimelerinden kaçınabilir hız.

Çoğu zaman hala OO kalıtım ve kapsülleme kavramlarını takip edecektir - bunları sadece dilin kendisinden nasıl farklı uyguladığını uygular (örneğin merakla özyinelemeli şablonlar, kalıtım yerine kompozisyon (Marco tarafından tanımlanan bileşen tabanlı yöntem)). Kalıtım derleme zamanında her zaman çözülebilirse, performans sorunları ortadan kalkar, ancak kod şablonlarla, özel RTTI uygulamalarıyla (yine yerleşik olanlar genellikle pratik olarak yavaştır) veya derleme zamanı mantığında biraz tüylü olabilir makrolar vb.

İOS / Mac için Objective-C'de, mesajlaşma şemasıyla (süslü önbellekleme şeylerinde bile) benzer, ancak daha kötü sorunlar var ...


0

Kullanmaya çalışacağım yöntem, sınıf mirasını ve bileşenlerini karıştırıyor. (Öncelikle, Düşmanı bir sınıf yapmıyorum - bunu bir bileşen haline getiriyorum.) Her şey için bir genel Entity sınıfı kullanma ve daha sonra varlığı temizlemek için gerekli bileşenleri ekleme fikrinden hoşlanmıyorum. Bunun yerine, bir sınıfın yapıcıya bileşenleri (ve varsayılan değerleri) otomatik olarak eklemesini tercih ederim. Daha sonra alt sınıflar ek bileşenlerini yapıcılarına ekler, böylece alt sınıf bileşenlerine ve üst sınıf bileşenlerine sahip olur. Örneğin, bir Silah sınıfı tüm silahlar için ortak olan temel bileşenleri ekler ve ardından Kılıç alt sınıfı kılıçlara özgü ek bileşenleri eklerdi. Hala varlıklar (veya belirli kılıçlar) için değerleri tanımlamak için metin / xml varlıkları kullanıp kullanmayacağımı tartışıyorum, ya da hepsini kodda ya da doğru karışımın ne olduğunu. Bu, oyunun kod dilinin tür bilgisini ve polimorfizmini kullanmasına izin verir ve ObjectFactories'i çok daha basit hale getirir.


3
Selam Chris. Deneyiminizi ve planlarınızı paylaşmak harika olsa da, soruyu doğrudan cevaplamıyor. Bence soru daha çok bu şeylerin nasıl yapıldığına dair, nasıl yapmayı planladığınıza cevap verirken . Bunlar benzer sorular, ama aslında aynı değil.
MichaelHouse
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.