C oyun motorunu yazmak mantıklı mı? [kapalı]


53

C ++ kral gibi görünse de, söylenenlere göre C hala oyunlarda, özellikle konsollarda yaygın olarak kullanılıyor. Ancak, bütün bir oyun motorunu C dilinde yazmak bugün mantıksız olur mu? C'nin C ++ 'a göre sahip olduğu bazı avantajlar nelerdir? Neden biri muhtemelen C ++ 'ı C yi kullanmak istesin ki?


1
Konsol oyunları c ++ FYI kullanın!
Alan Wolfe,

Aslında C'nin belirli bir seviyeye kadar oyun yazmanın daha kolay olacağını, on binlerce LOC veya daha fazlasını söyleyebileceğini düşünüyorum, çünkü sadece karmaşık veri türleri olmadan bitlere ve baytlara odaklanmanıza izin veriyor ve C ++ ile karşılaştırıldığında çok hızlı bir şekilde oluşturuyor. Ancak belirli bir ölçekte (yüzbinlerce LOC'ye ulaşma demek) sonra, gerçekten karmaşık veri türleri, daha fazla güvenlik, istisnalar, şablonlar ve daha da büyük bir boyutta istemeye başlayacağım C ++ 'a ulaşmak istiyorum. C ++ C ve C ++ kodları ile birleştirmek için C ++ dışındaki şeyler için ölçeklendirin (milyonlarca).

C ayrıca ABI için bile geniş ölçüde taşınabilir olma avantajına sahiptir, bu nedenle mevcut C kodunuzu almak ve daha sonra FFI'den başka dillerde kullanmaya başlamak oldukça kolaydır. C ++, isim sınırlaması, modül sınırlarını güvenli bir şekilde alamaması, derleyiciler arasında aynı olmamakla birlikte vtable reprodüksiyonları, satıcılar arasında farklı standart kütüphane uygulamaları vb. İle biraz daha gariptir. Tarzın dışına çıkmak, onunla birlikte bir ölçek yazmak için daha uzun sürüyor.

Yanıtlar:


49

Ancak, bütün bir oyun motorunu C dilinde yazmak bugün mantıksız olur mu?

Makul, ama soru şu ki, ne satın alıyor? Muhtemelen C tekliflerinin aşırı taşınabilirliğine ihtiyacınız yoktur ve gerçekten felsefi olarak karşı olmadığınız sürece, C ++ 'nın sunduğu tüm özelliklerden vazgeçmek utanç vericidir.

C'nin C ++ 'a göre sahip olduğu bazı avantajlar nelerdir?

Daha iyi derleme zamanı?

Neden biri muhtemelen C ++ 'ı C yi kullanmak istesin ki?

Bence daha çok estetik bir seçim. C gibi birçok insan basit ve minimal ve temiz hissettirdiği için. C ++ bir çok hoş özelliğe sahiptir (sadece ad alanlarını kullanmaya değer yapar), ancak aynı zamanda büyük ve dağınıktır.


3
Id Tech 4'e kadar
gözlükçü,

9
@Josh: Kolay hata ayıklama !? C programlarının , büyük ölçüde işaretçiler ve bellek yönetimi nedeniyle hata ayıklaması oldukça zor . C ++ programları (mümkün olduğunda işaretçilerden ve hafıza yönetiminden kaçınma eğiliminde olan gerçek C ++ programlama deyimleri kullanılırken) hata ayıklaması daha kolay olan birkaç büyüklük sırasıdır.
BlueRaja - Danny Pflughoeft

14
C sadece ölümlüler tarafından anlaşılabilir. C ++ birçok özelliğe sahip görünüyor ve tecrübeli programcılar, yaşamlarını her gün kullandıktan on yıl sonra bile öğrendiler.
Jari Komppa

13
C ++ büyük bir dildir, ancak korkutucu bir üne sahip olmak çoğu zaman korku hikayelerini okuyan ve öğrenmek için zaman harcamamış kişiler tarafından yayılmış olmasıdır. Öğrenilecek çok şey var, ama bunun karşılığında çok değer alıyorsunuz. C ++, C'nin basitçe yapamayacağı birçok şeyi ifade etmenizi sağlar.
belediye

2
@ BlueRaja-DannyPflughoeft #define malloc(x) my_malloc(x) #define free(x) my_free(x)ve şimdi bellek hata ayıklama vardır. C ++ ile ne zaman tahsis edeceğinizi asla bilemezsiniz, çünkü bellek
ayırmanın

59

Birçok ürün gönderen saf bir C oyun motoruyla yoğun bir şekilde çalıştım, bu yüzden kesinlikle mümkün. İşte hem C vs C ++ hem de motorlarda çalışma deneyimim:

  1. Pure-C yapılarını kullanmak, yapıların hizalanması hakkında bilgiden faydalanmanıza izin verir ve daha sonra bu bilgiyi nesnenin kalıcılığını ve seri hale getirme katmanlarını oluşturmak için kullanabilirsiniz. Çalıştığım motorda yapılar hakkında otomatik olarak bu meta verileri yaratacak basit başlık ayrıştırıcıları vardı ve bazı veri işlemlerini önemsiz hale getirdi. Keyfi C ++ başlık dosyalarının ayrıştırılması esasen imkansızdır ve kalıtım ve sanal fonksiyonlar ekler eklenmez tam olarak nerede bellekte olduğunu bilme yeteneğini kaybedersiniz
  2. Derleme süresi önemli ölçüde kısalır, çünkü başlık dosyalarınızı çok küçük tutabilir ve ileriye dönük yapı bildirimlerinden yararlanabilirsiniz.
  3. Hata ayıklama geliştirilebilir, çünkü şablonlar ve kalıtım kullanmadan, belirli bir nesnenin ne olduğunu ve ne yaptığını tam olarak anlamak çok kolaydır.

Bu faydaların tümü aynı zamanda, seri hale getirilmiş nesnelerde şablon ve kalıtım kullanmaktan kaçınan kısıtlanmış c ++ kodu kullanılarak da kolayca elde edilebilir, ancak CTO'nun C ++ 'nın daha kafa karıştırıcı unsurları olmasaydı basitliği zorlamanın daha kolay olacağı kararıydı. mevcut.

Şahsen, bu döngüleri biraz aşırı olduğunu düşünüyorum, çünkü döngülerde değişkenleri açık bir şekilde bildirme yeteneğini ve miras için tamamen meşru olanları kullanma hakkını kaçırdım. Ancak, sonuçta, göz önünde bulundurduğumuz her şey bize çok fazla üretkenlik göstermedi.


5
Sizi miras bırakmanızı engelleyen hiçbir şey yok. Ve eğer C99 kullanıyorsanız değişkenleri döngüler için beyan edebilirsiniz.
jsimmons

15
3. noktaya katılmıyorum. C ++ 'ta olduğu gibi dağınık, hata ayıklaması zor bir kod yazmak da C ++' ta olduğu kadar kolay. Daha iyi hata ayıklama, C dilinde doğal bir şey değildir.
Dan Olson

7
C ++ 'ta temiz kodların bile anlaşılması zor olabilir - aşırı yükleme, şablonlar, sanal fonksiyonlar ve istisnalar dışında, gerçek kontrol akışının tam olarak ne olacağını bir bakışta görmek çok daha zor.
Kylotan

6
@Dan: Sadece daha fazla şey alarak, C ++ hata ayıklaması daha zordur. Elbette bu tür şeylerden herhangi birini kullanmanızla sınırlayabilirsiniz, bu durumda C kadar hata ayıklamak kolaylaşır - çünkü C olur.

Daha az malzeme aslında C'yi memcpysevme sebebimdir. Örneğin, CI'de bitleri ve baytları bir for ile kopyalayabilirsiniz çünkü tip sistemi kopyalayıcılar ve dtors gibi şeylere izin vermez. Kod fonksiyonunu, herhangi bir kod satırında, yan etkilerini geri almak zorunda olmayacağımı bilerek kod yazabilirim, çünkü açıkça bir işlevden çıkmadığım sürece bir işlevden dolaylı olarak çıkamıyorum; atılan hiçbir istisna yoktur. Tüm bunlar veri yapılarını yazmayı çok daha kolaylaştırıyor - C ++ 'da sadece standartlara uygun bir yazı yazmak vectorçok zaman alıyor, özellikle de yapmak istiyorsanız ...

18

C ++ ve Lua'da yazılmış bir 2D oyun motorunu C ve Lua'ya yeniden yazıyorum. Şimdiye kadar deneyim oldukça iyiydi. Açıkçası, vektör ve matris işlemleri C'ye bakmak kadar güzel bitmiyor ama bunun dışında 10 + yılını C ++ geliştiricisi olarak geçirdikten sonra oldukça ferahlatıcı bir deneyim buldum.

C, C ++ 'a göre birçok avantaja sahiptir:

  1. Derleyici statik başlatma zamanında hiçbir kodun çalıştırılmadığından emin olacaktır. Bu, örneğin anahtar olarak kullanılan dizeler gibi global verilerin statik olarak tahsis edilmesini tamamen güvenli kılar.
  2. Şeffaflık. C tahsisinde veya bir değişkeni tahsis etmek veya tanımlamak, kod yüklerinin çalışmasına neden olmaz. C ++ sizin için otomatik olarak kopya kurucuları oluşturacak, böylece atama yaparken nelerin yürütüleceği üzerinde daha az kontrol sahibi olacaksınız.
  3. İşlev isimlerinin karıştırılmaması nedeniyle birçok hata ayıklama işlemi daha kolay olabilir .
  4. C'de memcpy kullanmak genellikle tamamdır , fakat kopya kurucuları çalıştırılmayacağından C ++ 'ta sorun çıkarmaz . Göz önüne alındığında memcpy çok daha hızlıdır std :: copy konularda söyledi.

Bunun dışında, C düşünce tarzına girmenin bir çok avantajı vardır. C ++ 'da sık sık kendimi işleri biraz aşırı ve soyut hale getirerek bulurum. CI'de genellikle get-set yöntemleri gibi şeyler kesilir ve genellikle dinamik diziler kullanmak yerine sabit boyutlu diziler önceden dağıtılır. Çoğu zaman, C'de daha kısa ve daha kolay hata ayıklama koduyla karşılaşıyorum. Veri yapıları genellikle daha düz ve hata ayıklayıcıda daha kolay görüntüleniyor.

Adil olmak gerekirse, asla C'de özel bir uygulama yapmazdım. İşe almamın nedeni, C'yi çok iyi tamamlayabilen Lua gibi daha yüksek bir dille birleştirmemin nedeni, C'nin çok güçlü olmamasıydı.

Id yazılımı CI'daki motorlarının çoğunun yazdığına inanıyor, Dönüş C'ye yazılmış olan Wolfenstein Kalesi'ne bakabilirsiniz .

Düz dizilere kıyasla C - C ++ ölçeklenebilirliği ve STL vektörünün dezavantajları üzerine deneyimlerimin bir kısmını yazdım .


11
Bilginize, kontrol ettiğim her durumda (ki sanırım, darwin gcc ve vc2008), std :: copy sadece her iki tür de POD ise memcpy çağrısını derleyecektir.
Brffle

3
Ayrıca, RE: STL vektörü düz dizilere karşı, neden vektörün güzel kısımlarını kullanmıyor ve beğenmiyorsanız yineleyiciler yerine normal C işaretçileri kullanmıyorsunuz? Sadece yapabilirsiniz & myvector [N]. Her iki dünyanın da en iyisi gibi, C kodunuzun hafıza tahsisini aynı şekilde yaptığını varsayar. Veya döngüler için BOOST_FOREACH adresini ziyaret edin. C'den daha da kolaylaştırır
BRaffle

1
Std :: copy memcpy hakkındaki ipucu için teşekkür ederiz. Bunu bilmiyordum. Alexandrescu bunu birkaç yıl önce tedavi ettiğinde durum böyle değildi. C ++ yineleyiciler hakkında. Temelde felsefe ile ilgili olarak, C ++ 'ın hem çalıştığım insanlar adına hem de C ++ özelliklerinden yararlanmaya yönelik olarak nasıl programlandığını programlamaya çalışıyorum. Genel olarak STL kapları gibi bazı C ++ geliştirmelerinin eski C tarzında yapmaktan her zaman daha iyi olmadığını belirtmek için yapılmıştır.
Erik Engheim

7

Başka birinin de belirttiği gibi, C ++ dayanabileceğiniz büyük omuzların avantajını getiriyor (BOOST, STL vb.). Sonunda, kişisel bir seçim, ancak mevcut kaynaklar nedeniyle C ++ 'ı seçecektim. C ++ 'da kullanmak istemediğiniz özellikler varsa, bunları kullanmayın.


1
Ticari ve şirket içi oyun motorlarının% 99'unun çeşitli nedenlerden dolayı (performans garantisi, hata ayıklama, iplik güvenliği, kontrol) Boost ve STL'den uzaklaştığını unutmayın.
Kaj,

42
İstatistiğin% 99'u oluşturuldu.
Brffle

Tüm istatistikleri alıntı yapmanın bir kural olması gerektiğini düşünüyorum.
Matt Jensen,

3

Bugünlerde kimsenin C kullandığını sanmıyorum, genellikle daha üst bir dille karıştırılıyor.

C programlama, C ++ ile programlama yapmanın üzerinde bazı faydalar sağlar. C ++ olabilir eğer dikkatli değilseniz performansını olumsuz etkileyebileceğini kullanıcı için görünmez başlık altında şeylerin çok. C ++ , yine performansınıza zarar verebilecek olan önbellek kullanımı söz konusu olduğunda korkunç olabilir.

Bu nedenle, bir oyunun performans açısından kritik kısımlarını geleneksel bir C ++ yönteminden ziyade C benzeri bir şekilde yazmak bazı faydalar sağlayabilir. Daha önce kimseyi hiç duymamıştım, son yıllarda aslında C'nin tamamını yazdım.

Bazı platformlarda, iPhone gibi, C ++ kullanmak, çalıştırılabilir boyutunuzu belirli bir kilobaytlık bir yığınla artırabilir (ne kadar, üzgünüm unuttum); -C.


3

Bugün C ++ yerine bir oyun motoru yazmanın neden mantıksız olacağına dair birkaç neden daha vereceğim: STL ve BOOST.

listKutudan çıkan kodlara (ve yazmak zorunda olmadığınıza) güvenebileceğiniz başka bir uygulama daha yazmanın ne kadar değerli olduğunu hayal edemiyorum .


1
Herhangi bir büyük stüdyo aslında bir destek kullanıyor mu? STL kullanımı bile, taşınabilirlik nedeniyle hala tartışılmaktadır. En azından konsol motorları için.
slicedlime

2
Şahsen, c ++ / lua etkileşimi için Boost.FunctionTypes kullanıyorum (bkz. Gamedev.net/reference/programming/features/CPPLuaExport/… ) ve tekdüze rastgele sayı üretimi için rastgele sayı kitaplığını artırın (parçacık sistemleri için). Ayrıca, Boost.Foreach temizdir. BTW, büyük stüdyoların BOOST kullanmamasını önemseyen kim? Kendi STL kütüphanelerini sıfırdan yazma yeteneğine sahipler, değil mi?
Loris

1
Evet, aynı zamanda C için de benzer kütüphaneler olduğunu fark et.
jsimmons

2
Birçok insan oyunlarda güçlendirme kullanıyor. Ancak birçoğumuz için bir zorunluluktan (ya da arzu edilenden) uzaktır.
Dan Olson

6
Millet, inandığınız şeyin önemi yok: ya biliyorsunuz ya da bilmiyorsunuz .
'.

3

C oyun motorunu yazmak makul. Hızlı ve çoklu sistemlere taşınabilir. Örneğin, Android için kullanabilirsiniz (NDK ile). İPhone için kullanabilirsiniz (Amaç c sadece c'nin bir uzantısıdır). Ayrıca Linux, Mac veya Windows gibi ana işletim sistemleri için de kullanabilirsiniz. C ile rahat hissediyorsanız, denemenizi öneririm!


2

Tabii ki makul. Ben şahsen bunu yapmazdım ve tanıdığım birçok C hayranı aslında .cpp dosyalarına C-benzeri bir kod yazıyor. Ancak diller, gerçekten önemli olmadığı yere yeterince benziyor.

Neden birisinin bunu yapmayı seçtiğine gelince, bunun çoğunlukla C ++ karşıtı felsefeye bağlı olduğunu düşünüyorum. Şahsen ben hala bu "C tarzı C ++" yerine C seçmek için iyi bir neden olduğunu sanmıyorum. typedef yapı çılgınlığı, C'den uzak durmak için yeterince iyi bir nedendir ve çok sayıda başkaları da vardır.

Ne yazık ki, C ve C ++, aşağı indiğimizde oldukça korkunç dillerdir. Bu, insanların son yıllarda kodlarında kodlarının çoğunu yapmaya çalışmasının bir nedeni.

C'de çalışan insanlara örnek arıyorsanız, C'yi uzun zaman önce terk ettiklerini okuduğumu hatırladığım için kimliği görmezden gelebilirsiniz. Cryptic Studios (Star Trek Online) tüm motor geliştirmelerini C’de yapıyor. Söyleyebileceğim kadarıyla, evet, somut bir avantajdan ziyade felsefe yüzünden.


0

Evet ve hayır. Evet birkaç yıl önce yaptım ama oyunumun aptal terminallerde oyuncuları olan bir unix (linux değil) 64 bit uzaktan kumanda sunucusunda 3D olarak çalışması gerekiyordu. Önemsiz değildi. C güzel olabilir, LUA'yı entegre etmek istersiniz ama sonunda C ++ 'da çalışmak için lua yaptım, bu yüzden evet demek mümkün olur ama yapma.


0

Olası iyi bir cevap "ikisini birden kullan" olabilir mi?

Panda3d projelerinin optimize edilebileceğini duyduğum gibi, bazı cythonları kullanarak ya da bu kısımları yeniden kodlayan darboğazı öldürdüm.

Çoğu zaman, optimize edilmesi gereken kısımlar, çok sayıda yinelemeye ve yuvalamaya veya çok sayıda sayısal hesaplamaya sahip olan kısımdır, bu yüzden (vahşi) tahminime göre, adil bir uzlaşmanın her iki dili de kullanması gerektiğidir. çok düşük seviye programlama içeren parçalar için, hız gerektiren kısım için C ++ dilini ve oyunun geri kalanında C ++ 'ı kötüye kullanamazsınız.

İdeal olarak, motorun hızlı kısmını yüksek seviyede göz önünde bulundurarak yaparsınız ve daha sonra çok daha az yuva / ilmek kullanacak bir betik dili veya C ++ kullanın.

Elbette, motorunuzu özel bir oyun türüne adamazsanız, geliştiricilerin yapması gereken tüm oyunlara uygun bir motor asla yapamazsınız.

Ama tecrübeli bir oyun geliştiricisi ya da deneyimli geliştiricisi olmadığım için tavsiyemi alma ... Sanırım C, bir oyun kadar büyük bir proje için hızlı ve iyi C ++ kodu yazarken hızlı kod yazmaya zorluyor. farklı bir şey ...


0

C, John Carmack için çalıştı , C'yi kullanarak birçok avantaj elde edebilirsiniz, ancak onlardan faydalanmak için oraya gitmeniz biraz zaman alabilir.

Burada bir kısmı C ile yazılmış oyun motorlarının bir listesini bulabilirsiniz , belki de kendi kaynak kodlarını kullanarak bir C oyun motorunun nasıl yapılacağı hakkında fikir edinebilirsiniz.


0

C kodu normalde geçerlidir C ++ kodu.

C ++ ile ilgili ana sorunlar onu yanlış kullanıyor ( Linus Torvalds bu sebepten nefret ediyor , kütüphane taşınabilirliği ile ilgili başka sorunları da vardı ve bu nedenle satın alma konusunda işletim sistemleri düzeyinde çalışıyor ve her rasgele bir şeyleri çalıştırabilmesi gerekiyor. orada çip).

Örneğin, cstyle dizisini [] bir c ++ std :: vector <> (veya benzeri bir kabın) üzerinden kullanmanın neredeyse hiçbir avantajı yoktur.

Vektörler yazı tipi güvenlidir ve sınırlar kontrol edilebilir (get () veya [] kullanarak öğelere erişebilirsiniz, dizi denetleme yöntemini kullanmasanız bile, işaretçiyi ortalıkta gezdirmek yerine boyutu sorgulayabilirsiniz).

Ama vektörler olabilir örneğin, yapıcı içinde varsayılan boyutu beyan yok, eğer yavaş. Ayrıca bir vektöre bir şeyler eklemek, daha sonra yeniden boyutlandırılması gerekiyorsa yavaşlamalara neden olabilir. C ++ 11, tek tip başlatma (şimdi aynı sözdizimini kullanarak vektörleri tanımlayıp başlatabilirsiniz) ve kopyalamayı engellemenize izin veren hareket yapıcıları gibi birçok avantaj sağlar. Kendi özel başlatıcılarınızı bile yapabilirsiniz (bir nedenden dolayı malloc kullanmaktan başka bir şey yapmak istiyorsanız).

Ya da bir şeyleri yeniden boyutlandırmanız gerekiyorsa, o zaman vektörler ile bunu yapmak daha kolaydır, malloc ile uğraşmak zorunda değilsiniz, elle şeyleri kopyalamak vb.

C ++ size nesne yönelimli kod verir. Derlendiğinde, kodla çalışan insanlar için gerçekten bir soyutlama olduğundan, bu kadar verimli olacak. Her ne kadar inşaatçılar gibi şeyler nesne oluşumunu yavaşlatabilir. Ancak, varsayılan değerleri ayarlamak için yapıcıya ihtiyacınız olacak veya aksi takdirde yapıcıyı kullanmadan (('lar)' ı bırakarak nesneleri başlatabilirsiniz.

Ancak nesne yönelimi programlama oyunlarını çok daha kolaylaştırır. Oyunlar genellikle nesnelerle ilgilenir.

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.