Oyun geliştirmede yararlı olan bazı programlama tasarım kalıpları nelerdir? [kapalı]


129

Tasarım Desenleri üzerine birkaç kitabım var ve bazı makaleler okudum, ancak hangi programlama tasarım desenlerinin oyun geliştirmede yararlı olacağını sezgisel olarak çözemiyorum.

Örneğin, Model Görünümü Denetleyici, Singleton, Fabrika, Komut vb. Gibi birkaç tasarım desenini ayrıntılandıran Tasarım Desenleri ile ActionScript 3 adlı bir kitabım var.

Bunun için yeni biri olarak, bunlardan hangisinin yararlı olacağını veya aslında bunlardan herhangi birinin öğrenip kullanmaya çalışmam gereken tasarım kalıpları olup olmadığını anlayamıyorum. Belki de bilmediğim başka, oyun programlamaya özel tasarım desenleri var?

Oyun geliştirmede belirli bir tasarım modelini kullanma konusunda deneyiminiz varsa, duymayı çok isterim. Neden kullanıldığına dair bir gerekçe, kod örnekleri veya çevrimiçi kaynaklar sizin de varsa, çok yardımcı olacaktır. Şu anda en fazla ActionScript 3 ve C ++ uygulamalarıyla ilgileniyorum, ancak kesinlikle herhangi bir dilden edinilen deneyim ve örneklerden faydalanabiliyorum.

Teşekkürler!


“Belki de farkında bile olmadığım başka, oyun programlamaya özel tasarım desenleri var?” - hayır, bu desenler geneldir ve kullandığınız dilin özelliklerini genişletmek için daha fazlasını uygular. Başvurunuzun konusu ile ilgisi yok.
Kylotan

3
@Kylotan Sınırlı görüşüme göre, her bir tasarım modelinin belirli bir sorunu etkili bir şekilde ele alması gerektiğinden, doğası gereği bazı tasarım modellerinin belirli bir sorun kümesi için verilen diğerlerinden daha yararlı olacağı anlaşılmaktadır, bu sorun oyun geliştirmeye özgüdür. Elbette bazı kurallar var ya da deneyimlerinize dayanarak, kendinizi diğerlerinden daha sık kullandığınız belirli tasarım desenleri var mı?
jcurrie33

Herkes söner 1000 farklı tasarım desenleri öğrenir önce okuyunuz bu ve bu
BlueRaja - Dany Pflughoeft

@ BlueRaja-DannyPflughoeft Seconder bağlantısı geçersiz.
Tekrar

Yanıtlar:


163

Şimdi bazı önerileri ile daha az saygısız bir yanıt için. Bunları uygulama önerileri olarak almayınız, daha muhtemel kullanım örnekleri olarak.

  • Oluşturucu: verilere dayalı olarak bileşen tabanlı varlığı bir defada bir bileşen ayarlayın
  • Fabrika Yöntemi: bir dosyadan okunan dizeye dayanarak NPC'ler veya GUI widget'ları oluşturun
  • Prototip: İlk özelliklere sahip genel bir 'Elf' karakteri saklayın ve klonlayarak Elf örnekleri oluşturun.
  • Singleton: bu boşluk kasten boş bırakılmıştır.
  • Bağdaştırıcı: isteğe bağlı bir 3. parti kitaplığı mevcut kodunuza benzeyen bir katmana sararak dahil edin. DLL'lerde çok kullanışlıdır.
  • Kompozit: canlandırılabilir nesnelerden bir sahne grafiği yapın veya bir Widget ağacından GUI yapın
  • Cephe: daha sonra hayatınızı kolaylaştırmak için daha basit bir arayüz sağlayarak karmaşık 3. parti kütüphaneleri basitleştirin.
  • Flyweight: Bir NPC'nin paylaşılan yönlerini (örneğin, modeller, dokular, animasyonlar) ayrı ayrı yönlerden (örneğin konum, sağlık) ayrı ayrı saklayın.
  • Proxy: İstemcide, sunucudaki daha büyük, daha karmaşık sınıfları temsil eden küçük sınıflar oluşturun ve isteklerini ağ üzerinden iletin.
  • Sorumluluk zinciri: girdilerin bir işleyici zinciri olarak ele alınması, örn. genel tuşlar (örneğin ekran görüntüleri için), ardından GUI (örneğin, bir metin kutusunun odaklanması veya bir menü olması durumunda), ardından oyun (örneğin, bir karakter taşımak için)
  • Komut: oyun işlevselliğini, konsola yazılabilen, saklanabilen ve tekrarlanan, hatta oyunun test edilmesine yardımcı olacak şekilde yazılabilen komutlar olarak saklayın
  • Arabulucu: Oyun varlıklarını farklı bileşenler üzerinde çalışan küçük bir arabulucu sınıfı olarak uygular (örneğin, verileri AI bileşenine aktarmak için sağlık bileşeninden okuma)
  • Gözlemci: Bir karakterin rendeble gösterimini, oyun mantığı olmadan kod oluşturma hakkında herhangi bir şey bilmeye gerek duymadan, gerektiğinde görsel sunumu değiştirmek için, olayları mantıksal gösterimlerden dinletmek
  • Durum: NPC AI'yi birkaç durumdan biri olarak saklayın, örn. Saldırı, Gezinme, Kaçma. Her birinin kendi update () yöntemi ve ihtiyaç duyduğu diğer veriler ne olursa olsun (örneğin, hangi karaktere saldırdığını veya kaçtığını, gezindiği alanı vb. Saklamak gibi) olabilir.
  • Strateji: A * aramanız için ne tür bir arazide olduğunuza bağlı olarak farklı sezgisel taramalar arasında geçiş yapın veya hatta hem yol bulma hem de daha genel planlama için aynı A * çerçevesini kullanın.
  • Şablon yöntemi: Her bir basamağı işlemek için çeşitli kanca işlevleriyle genel bir 'savaş' rutini kurun, örn. cephaneyi azalt, isabet şansını hesapla, isabet ya da özledim çöz, hasar hesapla ve her bir saldırı yeteneği kendi yöntemlerini kendi yöntemlerine uygular.

İlham eksikliği nedeniyle bazı desenler kalmadı.


Singletonlar üzerine çok aydınlatıcı bir tartışma burada bulunabilir: misko.hevery.com/2008/08/25/root-cause-of-singletons
Andrew Wang

Strateji kalıbı için +1. Yukarıda belirtilen tam amaç için kullandım (farklı A * sezgisel tarama).
Mike Strobel

1
Bu cevap için teşekkürler, bunlar her yerde duyduğum "singleton" dan ziyade tasarım deseni gibi geliyor ...
jokoon

Örneklerin harika bir listesi. Singleton modelinin kronik olarak kötüye kullanılmasına rağmen (kılık değiştirmiş küresel devlet), meşru kullanımlar var: Aslında yalnızca sizin (veya istediğiniz) sahip olduğunuz bir kaynağı temsil ettiğinde . Bu, donanım sarma (örn. Klavye / fare) veya yinelenmeyen bir kitaplığı sarma gibi bir şey olabilir (olur ve tüm dillerin sihirli senkronizasyon anahtar kelimeleri yoktur).
charstar

11
Donanım kaynakları için singleton'ları kullanmayacağım - yıllarca süren video kartlarının ve monitörlerin yaptığı gibi, daha sonra çarpma eğiliminde olacağınızı düşündüğünüz öğeler. Benzer şekilde, bazı API'ler altında 1 gamepad'i anlamak için 2 joystick okumanız gerekir. Bu yüzden, yalnızca bir şeye ihtiyacınız olursa, bir tanesini başlatmanız yeterli, muhtemelen gerekli olmayan keyfi kısıtlamaları zorlamayın.
Kylotan

59

Tam da bu konuda bir kitap yazdım: Oyun Programlama Kalıpları . Buradaki bölümler sizin için yararlı olabilir.


2
+1 Birinin buna bağlı olduğunu umuyordum ve yazarın olduğunu gördüm! Bileşen kalıp açıklaması oldukça yardımcı oldu ve göstermek için tüm kod örneklerini kullanmayı denemenizi seviyorum.
CodexArcanum

2
Evet - birkaç yıl önce bağlantınızı okuduğumu hatırlıyorum. Bu makaleleri bitirmelisin!
onedayitwillmake

2
Şimdi kitap bitti :)
dusan

1
Mevcut programlama bilgimi oyunlar için programlamaya çevirmeme yardımcı olan harika bir kaynak. Yazdığın için teşekkürler!

Oyun programlama kalıplarının bu açıklaması aslında - tasarım kalıplarını - hiçbir yazılım tasarım kalıp kitabının gerçekten yapmadığı şekilde anlamama yardımcı oldu! Bu kısmen oyun geliştirme gücünün (benimle konuşan ve genel olarak gelişimimi daha iyi hale getirmeme izin veren bir dilde somut örnekler), ancak daha büyük bir kısmı çünkü yazı çok iyi.
Kzqai

19

Brandon Eich'in İşyerindeki Kodlayıcılara katılması iyi bir şeydi , kalıpların hack ve geçici çözümler olduğu: [Kalıplar] dilin içinde bir çeşit kusur olduğunu gösteriyor. Bu desenler bedava değil. Bedava öğle yemeği yok. Bu yüzden, doğru bitleri ekleyen bir dilde evrim aramalıyız.

Derleyici tasarımcılardan ziyade oyun programcıları olarak nadiren kullandığımız dilleri geliştirme seçeneğine sahibiz, ancak dilimize ve gereksinimlerimize daha iyi uyacak şekilde kendi stilimizi geliştirmeyi öğrenebiliriz. Kalıplar bunlardan bazılarıdır, ancak kalıp kullanmamak başka bir parçadır, özellikle Brandon'ın söylediği gibi, kalıplar nadiren kayda değer bir performans ya da bellek ya da kod çevikliği maliyeti olmadan gider. MVC sadece oyunlarda pek çok şey için mükemmel bir model değil. Singleton, topallama C ++ statik başlatma kuralları için bir geçici çözümdür ve muhtemelen bunları yine de yapmamalısınız. Fabrika karmaşık nesnelerin oluşturulmasını basitleştirir - belki nesnelerin başlaması daha kolay olmalı. Popüler modeller, ihtiyaç duyduğumuzda başvuracağımız araçlardır. Karmaşık bir şey yönetmek için, başlangıçta karmaşık bir şey inşa etmek için kullanmaya can atmamız gereken araçlar değil.

İyi (oyun) kod desenleri kullanabilir veya kullanmayabilir. Modelleri kullanıyorsa, sorun değil - kod yapısını diğer programcılara yüksek, dilden bağımsız bir seviyede açıklamak için harika bir iletişim aracıdır. Eğer bir şablon kullanmadan kodun daha iyi olduğunu düşünüyorsanız, bunun üzerine atmayın - muhtemelen öyle.


4
Evet, orijinal kitapta açıkça ifade edilen şeylerden biri (ancak genellikle gözden kaçan), C ++ / Smalltalk yerine C için yazılmış olsaydı, bir "Kalıtım" deseni ve aynı dilde bazı dilleri içermiş olabilirlerdi. önceden inşa edilmiş olan GoF kalıplarından bazılarını içerebilir.
Kylotan

13
Orijinal kitapta sıklıkla göz ardı edilen bir diğer şey (GoF değil Alexander'ın orijinal orijinal kitabı) kalıpların uygulama için değil, iletişim için bir araç olduğuydu . Tasarımcıların uygulama hakkında daha yüksek düzeyde iletişim kurmasına izin verir ve zorunlu olduklarında kullanılmaları gerektiği için tekrarlama yaptıkları için belirlenirler.

1
Bununla birlikte, yalnızca terminolojiye sahip olmak, sorun hakkında aklınıza gelebilecek ve böyle bir yaklaşımın iyi bir çözüm olduğunu anlayabilmenize yardımcı olabilir. En iyi kalıplar tipik olarak vasıflı ve deneyimli işçiler tarafından zaman içerisinde rafine edilmiş ve daha az vasıflı çalışanlar bu kodlanmış örnekler olmadan aynı kalıpları kendileri keşfetmeyeceklerdir.
Kylotan

Terminolojiye sahip olmanın harika olduğunu ve bir model tanımının bir kısmının, bazı problemler için iyi ve düzenli bir çözüm olduğu konusunda hemfikirim. Ne yazık ki, daha az vasıflı işçiler çoğunlukla Singleton'u bulma eğilimindedir ve henüz bir sorun olmasa bile her soruna uygularlar .

Bu yanıt için teşekkürler; Yazılımın tasarımında yaratılan sorunları çözmek için tasarım deseninin yapıldığını okumaktan rahatlamış hissediyorum. Büyük bir yazılımın yapısının, bir şeyi kodlamaya başlamadan önce baştan sona düşünülmüş olması gerektiğini düşünüyorum. İşlevleri her zaman bir defada bir kez uygulayamazsınız, bazen her bir özellik hakkında düşünmeniz gerekir ve yazılımın global yapısına karışıp karışmayacağını kontrol edin veya yalnızca yazılımın nasıl kullanılması gerektiğine karar verin. Davranmak. Görevleri çeşitli programcılara
bölmek

7

Elbette, başkalarının söylediği gibi, tüm modeller doğru koşullarda kullanışlıdır ve onları nasıl kullanacağını öğrenmenin bir parçası ne zaman ne zaman kullanılacağını öğrenmektir. Ancak, Daniel Sanchez-Crespo Dalmau'nun Oyun Programcılığındaki mükemmel Çekirdek Teknikleri ve Algoritmalar adlı kitap , özellikle oyun programlamasında faydalı olan altı programlama modelini ve altı kullanılabilirlik modelini listeler.

Programlama:

  • Singleton: Birçok insanın yaptığı gibi bundan nefret etmiyorum; Tek oyunculu veya klavyeli okuyucu gibi şeyler için kullanılabilir.
  • Factory: Nesneleri verimli bir şekilde yaratıp yok etmeni sağlar.
  • Strateji: AI stratejilerini zarif bir şekilde değiştirmenizi sağlar.
  • Mekansal Dizini: Mekansal veri kümeleri üzerinde sorgulamalar yapılmasına yardımcı olur.
  • Kompozit: Yararlı bir nesne heirarşi kurar.
  • Flyweight: Aynı düşmanlar gibi şeyleri genelleştirerek belleği serbest bırakır.

Kullanılabilirlik:

  • Kalkan: Dramatik eylemlerin yanlışlıkla etkinleştirilmesinden korur.
  • Devlet: Dünya / UI durumunun görsel ipuçları.
  • Otomatik Mod İptali: Oyunun daha sezgisel çalışmasını sağlar.
  • Manyetizma: Otomatik arama ve kolay ünite seçimi.
  • Odak: Dikkat dağıtıcı UI öğelerini ortadan kaldırmak.
  • İlerleme: Evrensel olarak faydalı.

Elbette kitap, bunların her biri üzerinde daha ayrıntılı olarak yer alıyor.


Giriş için teşekkürler! Bu kitabın farkında değildim, ancak yayınınızın bir sonucu olarak şimdi inceleyeceğim. Tekrar teşekkürler!
jcurrie33

2
Klavye okuyucusu için Singleton, tam olarak sormam gereken bir durum - Gerçekten de ana işlevinizde erken belirlenmiş bir küresel işaretçi yapamaz mısınız? Hiç yanlışlıkla iki klavye okuyucusunu başlattınız mı?

Lütfen singleton'dan nefret et. İki şeyi kötü yapar. Global erişim ve aritelik. Genellikle geliştiriciler küresel erişimin == singleton olduğunu düşünüyor. Bir Orada çok daha az problem gerçek bir singleton gerekir ve bir singleton ile çözdüğünde daha zarif olduğunu daha belki birkaç.
deft_code

7

Varlık sistemleri güzel bir kalıptır. Tamamen bir tasarım deseni değil, çünkü OOP kesinlikle değil. Ancak onu OOP ile karıştırabilirsiniz.

Bazı iyi linkler (intro için baştan başlar):


3
“Bu tam olarak bir tasarım deseni değil, çünkü [sic] OOP değil.” Tasarım kalıplarının OOP ile ilgisi yoktur; Bir şey olursa, OOP'un kendisi bir tasarım desenidir. Tasarım desenleri sadece OOP dışında değil, tamamen yazılım geliştirme dışında da görünür.

Orada OOP design patternstipik sınıflar / nesneler arasındaki ilişkileri ve etkileşimleri göstermektedir ki. Ve başka birçok tasarım deseni var. OOP bir kavram değil, bir kalıptır. Design patternbir kavram da.
Topright,

6
Anlamsallıktan bahsetmek yerine, verdiğim yanıtın faydasını değerlendirmemelisin?
Wernight

6

Hepsi. Singleton hariç. [/ Havailik]


Oyun geliştirmenizde sıkça kullandığınız bir veya iki tasarım desenini muhtemelen ve hangi nedenle adlandırırsınız? Tasarım desenleri açısından bir başlangıç ​​olarak, "hepsi" özellikle yararlı bir cevap değildir. Yine de cevap verdiğiniz için teşekkürler.
jcurrie33

5
"Hangi kalıpları kullandın?" Diye sormak. "hangi değişken isimlerini kullandın?" Kişisel stil ve gereksinimler ve etki alanına gelir. Bir noktada, muhtemelen daha önce adlandırılmış olan herhangi bir deseni kullanacaksınız. Muhtemelen daha önce adlandırılmayan birçok şeyi kullanacak ve hatta bazılarını yenilerini icat edeceksiniz.

@ jcurrie33: pardon, önce singletons'da kazıma dayanamadım. ;)
Kylotan

6

Gerçekten kalıplar hakkında değil, onların arkasındaki temel ilkeler hakkında. In "Tasarım Kalıpları: Yeniden Kullanılabilir Nesne Odaklı Yazılım Öğeleri" (1995) ;:, çete dört (Gama, Erich Richard Helm, Ralph Johnson ve John Vlissides) nesne yönelimli tasarım için sadece iki ilkeleri önermektedir (1) programı bir uygulama için bir arayüz değil, bir uygulama ve (2) sınıf mirası üzerinden nesne kompozisyonunun tercih edilmesi.

Bu 2 ilke oyun geliştirmenin birçok görevinde çok faydalıdır. Örneğin, birçok oyun programcısı oyun varlıklarını temsil etmek için derin bir sınıf hiyerarşisi kullandı. Kompozisyon - bileşen tabanlı oyun nesnelerine dayalı başka bir yaklaşım var . Bu yaklaşımla ilgili makale . Daha da fazla bağlantı . Bir Dekoratör kalıbı örneğidir.


Oyun tasarımında kullanılan bileşenler, doğal olarak C / C ++ / Java / C # dışındaki kapanışlar ve içlerindeki bileşen nesneler olarak ifade edilen durumlu bir strateji modeli gibidir. Dekoratör modeli daha çok bir vekil gibidir; sahiplik ve veri akışı normalde oyunlardaki bileşen sistemlerinden bahsettiğimizde kastettiğimizin tersidir.

Bileşenlerin ayrıca Mediator, Observer ve Composer gibi kalıpları getirerek birbirleriyle konuşmaları gerekir. "Bileşen Tabanlı Oyun" tek başına bir kompozit tasarım modelidir.
CodexArcanum

@CodexArcanum, Observer, kesinlikle ama her zaman Mediator (yerine Sorumluluk Zinciri kullanılabilir). Besteci, yalnızca GameObject (GameObjectComponent'ten oluşur) GameObjectComponent'in kendisi ise (gerekli değildir).
Topright

6

Merakla yinelenen şablon desen sanal metotlar ve sanal işlev çağrıları gelebilir performans kaybına kaçınmak için gerçekten yararlı olabilir.

Bu, aslında peşinde olduğunuz arayüze sahip olan temel sınıf tipinde bir kabın olması gerekmediğinde, ancak benzer şekilde adlandırılmış davranış ve arabirimlere sahip olmak istediğinizde uygun model olabilir.

Örneğin, bu türün varyansının derleme zamanında bilindiği birden fazla platform veya motor (dx ve opengl) için sınıfları derlerken bunu kullanabilirsiniz.


Os soyutlama katmanının sanal olmasından her zaman nefret ettim. İki os soyutlama katmanına ihtiyacınız olacak gibi değil. CRTP kullanmak çok daha iyi.
deft_code

Belki sadece yaşlandım, ama DX / OpenGL veya platform arayüzleri için CRTP bile kullanmam. Derlemek için çok yavaş - sadece typedefs kullanırdım. CRTP, sınıflar arasındaki arayüzleri ve uygulamaları paylaşmak istediğinizde ancak bir yapı veya diğerini seçmek istediğinizde değil, başka bir ilişkiye sahip olmadığınızda iyidir.

4

Uzun yıllar boyunca geliştiğim ve benim için olağanüstü faydalı olan bir tasarım deseni, “tanımlanmış tanım kümeleri” olarak adlandırdığım bir şey; GOF terimlerinde nasıl özetleneceği tartışmalı görünmektedir, ancak StackOverflow hakkında bu konuda yazdığım soru , bu konuyla ilgili bazı ayrıntılara giriyor.

Temel kavram, bir modelin bazı özelliklerinin, bir yaratığın türü gibi, mülk için olası her değerin, davranışını belirten, değer başına tek, paylaşılan bir nesne olan karşılık gelen bir tanım nesnesine sahip olacak şekilde ayarlanmış olmasıdır ve bunlara merkezi bir aracı kurum aracılığıyla erişilir (bu, GOF-bilge Tescil, Fabrika veya her ikisi de olabilir). Kullanımım sırasında, çalışma zamanı morfizmi amaçları için zayıf bağlanmayı kolaylaştırmak için genellikle skaler tuşlar aracılığıyla da erişilebilirler.


Bunun nasıl bir singleton olduğunu görmüyorum ve uç ağırlığı şeklini tartışırken "kayıt defteri" kelimesi gereksiz. Bu sadece uçar.

SO iş parçacığından anladığım kadarıyla, insanlar sınıf olarak tanımlamaları nedeniyle Singleton'u bunun bir parçası olarak tanımladılar. Tescil başvurusu yapıldığı sürece, Fabrika ile ne zaman değiştirileceğini veya bir araya getirileceğini nasıl gereksiz hale getirebileceğini anlamıyorum.
kaos

-1, kalıplar hızlı bir şekilde iletişim kuruyorsa, bu muhtemelen gördüğüm en büyük başarısızlık. Gerçekten bu tanımı ciddiye alamam.

Tanrım, senin için yeterince çerez kesici olamadığım için kusura bakma. GOF terimlerinde anında özetlenemediğinden "Varlık sistemleri" yanıtını da mı oylayacaksınız?
kaos

1
Bir miktar “çerez kesici” veya en azından semantik netlik, tam olarak hangi kalıpların faydalı olması gerektiğidir. Genel olarak anlaşıldıkları gibi "flyweight" ve "singleton" gibi terimler birbirini dışlar. Birincisi, birden çok örnek arasında otomatik olarak veri paylaşımı hakkında; ikincisi ise tam olarak bir örneğe sahip olmakla ilgili. Tasarım seçiminizin işe yaramaz hatta kötü olduğunu söylemiyorum, ancak "yeterince yakın" desen adlarını bir araya getirmek sadece herkesi daha fazla karıştırıyor. (Lütfen kişisel olarak, özellikle CW'de, kişisel oyunuzu düşürmeyin.)
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.