En sevdiğiniz oyuna özgü kodlama taşları nelerdir? [kapalı]


24

John Carmack'in Quake III'deki Hızlı Ters Karekökü ile başlayacağım :

float Q_rsqrt(float number) {

  long i;
  float x2, y;
  const float threehalfs = 1.5F;

  x2 = number * 0.5F;
  y = number;
  i = * ( long * ) &y;
  i = 0x5f3759df - ( i >> 1 );
  y = * ( float * ) &i;
  y = y * ( threehalfs - ( x2 * y * y ) );

  return y;

}

6
Bu gerçekten bir soru değil - en azından bunu bir topluluk wiki sayfası olarak ilan edebilirsin ...
Rachel Blum

Yapıldı, toplulukla bağlantılı.
gak

3
Boşver onu! sadece büyük JC tarafından hazırlanmış tüm kodları kullanın!
Adam Naylor

3
0x5f375a86 (: Bu arada, daha doğru bir "sihirli sayı" karekök fonksiyonu ters hızlı kullanmak var ki not do en.wikipedia.org/wiki/... )
Ricket

8
Ayrıca John Carmack'in olmadığını unutmayın.
Kaj,

Yanıtlar:


25

mapValue işlevi:

float mapValue( float inVal, float inFrom, float inTo, float outFrom, float outTo )
{
    float inScale = (inFrom != inTo) 
        ? ( ( inVal - inFrom ) / ( inTo - inFrom ) ) 
        : 0.0f;
    float outVal = outFrom + ( inScale * ( outTo - outFrom ) );
    outVal = (outFrom < outTo ) 
        ? clamp( outVal, outFrom, outTo ) 
        : clamp( outVal, outTo, outFrom );
    return outVal;
}

Bir değer alır, onu bir aralık içindeki bir orana dönüştürür ve sonra bunu başka bir aralığa göre ölçeklendirir. Çift lip gibi.

Bunları normalleştirmek için kullanabilirsiniz:

float minDamage = 0.0f; float maxDamage = 300.0f;
float normalisedDamage = mapValue(damange, minDamage, maxDamage, 0.0f, 1.0f);

Veya bir aralıktan diğerine dönüştürebilirsiniz:

float brakeStrength = mapValue(timeToCollision, 
    0.0f, 10.0f, // seconds
    1.0f, 0.2f // brake values 
    );

İkinci örnekte, çıkış aralığının aralık aralığına göre farklı bir düzen olduğuna dikkat edin.

Çok görünmüyor, ama ben her yerde bu küçük adamı kullanıyorum.


14

Pisagor Teoremi'ni oyun kodumda kaç defa kullandığımı hala inanamıyorum. Bana göre, bu basit formül oyun geliştirmede bir mücevher.

a^2 + b^2 = c^2
(kaynak: mathurl.com )

veya

alt text
(kaynak: mathurl.com )

ve sadece bağıl mesafe önemli olduğunda pahalı karekök işlemi olmadan kullanılabilir

alt text
(kaynak: mathurl.com )


Dürüst olmak gerekirse, Pisagor matematiği TÜM oyun kodu üzerinde, özellikle fizik kodu, kod oluşturma, AI gibi motorlarda kullanılır.
Nick Bedford

1
Doğru. Bu yüzden bir mücevher. ;)
MrValdez

4
İlginç bir varyasyon sadece göreceli mesafeleri umursamanızdır . Ardından, potansiyel olarak pahalı sqrtaramayı atlayıp basitçe hesaplayabilirsiniz distance2 = x^2 + y^2.
mmyers

@mmyers - Başka bir harika şey: x ^ 2 uzayda çalışıyorsanız, mesafe sadece göreceli değildir.
Steven Evers

Göreceli mesafe bitini belirttiğiniz için teşekkür ederiz. Çok fazla gereksiz karekök işlemi gördüm, tıpkı A * kullanan insanların daha az kesin bir şey kullanmaları gerektiği zaman.
Ricket,


10

Duff'un Cihazı ile gitmeliyim . Kelimenin tam anlamıyla çenemi düşüren ilk kod bloğuydu. "Bunu yapabilirsin?!?"


Aman Tanrım. Gözlükler! Hiçbir şey yapmıyorlar!
Raoul

"Switch-case" içindeki iç içe geçmiş "do-while" her zaman yanıp sönmeme neden olur. 20 yıl sonra bile ...
Andreas,

1
-1. Bundan hoşlanmadım. Bugün çok kullanışlı değil (başkalarının memcpykodunuzu okuyabilmesini istiyorsanız, bunun yerine kullanabilirsiniz )
bobobobo

1
@JoeWreschnig neden olmasın? Memcpy her zaman daha okunaklı, taşınabilir ve muhtemelen daha iyi duruma getirilmiş olacak.
KaoD

1
@kaoD: Memcpy Duff cihazına eşdeğer olmadığı için - aynı şeyi yapmazsa ne kadar "okunabilir, taşınabilir ve muhtemelen daha iyi duruma getirilmiş" olduğu önemli değil! Modern CPU boru hatları Duff'un cihazı olmadan dal tahmini ve talimat önbelleklemesi nedeniyle olduğundan daha iyi sonuç verir, ancak bununla ilgisi yoktur memcpy.

7

Küçük bir C / C ++ snippet'i bir oyundan yıllar önce yazmaya başladım.

(fill ? FillRect : DrawRect) (x, y, w, h, colour);

İlk oyunumda ( bu ) 1Mb'dan fazla RAM'e erişmem gerekiyordu ve bu internetten önce, XMS ve EMS için DOS uygulamalarının ekstra RAM'e erişmek için kullandığı konusunda hiçbir belge yoktu.

Böylece, 386'da segment kayıtlarıyla ilgili küçük bir 'arka kapı' kullandım. Normalde, gerçek modda, adres seg*16+offsizi 1 MB ile sınırlandırdığı şekilde hesaplandı .

Bununla birlikte, korumalı moda geçebilir, 4Mb'ye bir segment ayarlayabilir, geri dönebilir ve segment kaydına yazmamış olmanız koşuluyla (DOS yalnızca 8086 segment kayıtlarını kullandığından beri tamam olan) tüm siteye erişebilirsiniz. Düz adres alanı olarak 4 Mb. DOS servislerini kullanmak istiyorsanız gerçek moda geri çevirmek gerekliydi.

Çok fazla DPMI genişletici mevcut değildi.


Neredeyse C # işleri (bir temsilci türü bildirmeniz ve en az bir oyuncu eklemeniz gerekir)
finnw

Gerçek modda 32 bit adresleme modları mı demek istiyorsun? (yani bir adres boyutu öneki gerektiren). Segment tanımlayıcısı oluşturmak gerektiğine ve aslında 16 * FS + normali olarak segman kaydını kullanmadığından emin misiniz? Segmentlerin 16-bit modunda bile limitleri olduğunu düşünmedim, sadece temel adres (16 * değerleri), bu yüzden FS'yi 16-bit modunda bir şeye ayarlayamadınız ve [fs:esi]ne kullanıyorsanız kullanın. aranan?
Peter Cordes,

Bunu hiç denemedim ya da 16-bit modu için herhangi bir gerçek kod yazmamıştım, sadece 32 ve 64-bit asm, ama garip geliyor. Hmm, makul olsa da. Modern CPU'lar segmenti dahili olarak kesinlikle önbelleğe alır ve segment reglerine yazarken sadece bu önbellekleri yeniden yükler, bu yüzden belki de korumalı mod üssü + limitini koruduğu şekilde gerçekleşir (eğer gerçekte olan buysa ve sadece 16 * FS'den başlayan 4 MB).
Peter Cordes

5

Şahsen ben Mersenne Twister'in tahmin edilebilir rasgele sayılar için büyük bir hayranıyım, özellikle Rand'ın birkaç farklı tohumlu örneği oluşturmanız gerekiyorsa

http://en.wikipedia.org/wiki/Mersenne_twister


Mersenne Twister, iyi bir rasgele sayı üreteci olması açısından güzel, ama özellikle şık ya da havalı değil (ya da hızlı ya da uygulaması kolay). Bunun için en.wikipedia.org/wiki/Rule_30 adresine bakmak isteyebilirsiniz .

1
KUYU .. iyi MT daha çoğu kullanımlar için genellikle en.wikipedia.org/wiki/Well_equidistributed_long-period_linear
Jari Komppa

5

İşte Chris Crawford'dan (ve görünüşe göre Atari'nin kullandığı) 'A Graphics Trick' olarak adlandırdığı biri:

LDA FIRST
EOR SECOND
AND CONTROL
EOR SECOND
STA OUTPUT

Bir açıklama için makalenin tamamını okuyun .


1
Bu bağlantı şimdi koptu, bu yüzden burada bir açıklama yapmak için yardımcı olacaktır.
finnw

Teşekkürler. Gitti ve web sitesini tekrar değiştirdi. Bağlantıyı güncelledim.
Anthony,

4

Bazı nedenlerden dolayı, insanlar oyunlarda tasarım desenlerinin gücünü çoğunlukla kullanırlar. Oyunlara başarı ile uygulanan hemen hemen her GoF kalıbını gördüm.


1
Oyun programlaması hakkında sevdiğim şeylerden biri, standart GoF "doğruluk" tarzından uzaklaşmak ve sadece mükemmel hıza odaklanmak! Bununla birlikte, MVC'nin oyundan çok daha fazla zarar veren birçok kötü uygulamasının olduğunu gördüm.
Iain,

Bence tasarım desenlerinin yeri var. Oysa oyunlarda pek değil.
blissfreak

@ blissfreak: Oyun programlamasında, kalıpların yaygın olmadığı bir tür vahşi batı yapan özel bir şey yok. Onlar gülünç ortaktır ve işte bazı örnekler.
Steven Evers,

4

Math.atan2 () son derece kullanışlıdır (tüm trig ile birlikte).


Öyle olsun, Tanrım! Çok fazla 3D yaptım ve buna hiç ihtiyacım olmadı.
Skizz

+1, x + y vektör bileşenlerinden radyan yönüne gitmenin tek yolu bu.
RCIX,

1
@RCIX: Demek istediğim, dönüşümün gereksiz olduğu, yani (x, y) -> açı, herhangi bir açı problemine bir vektör çözümü olduğu.
Skizz

6
Gerçekten çıplak bir standart kütüphane işlevine "gem" demem.

1
@Skizz: Belki 3d için, ancak normalleştirilmiş bir vektör almanın ve radyan yön değeri elde etmenin başka bir yolunu bilmiyorum. 2D oyunlarda ki değer iyi.
RCIX

3

Yukarıdaki pythagorean gem'e eklemek için ...
İnsanlara her zaman 3d programlama için sadece bilmeleri gerektiğini söylerim:
- a ^ 2 + b ^ 2 = c ^ 2
- soscastoa (günah = karşıt taraf / eğimli taraf, cos = ekli taraf) / eğimli taraf, tan = zıt taraf / ekli taraf)
- a. b = | a | * | b | * çünkü alpha
- a * b = | a | * | b | * günah alfa * birim vektör
Oyun kurallarında karşılaştığınız hemen hemen her türlü 3d (veya 2d) problemini çözebilir - 4 kural.
Elbette, daha güzel yollar var, ama bu hepsini çözebilir - Bilmeliyim, kariyerine dayanan bir hack'üm.


5
re: soscastoa Bence çoğu insan bunu sohcahtoa (bilhassa daha belirsiz, “hipotenüs” varsa, daha belirgin, “eğimli tarafı” ile değiştirerek) biliyor. Dilden daha kolay akar ve hatırlanması böylece daha kolay olur.
Asmor

1
Ortaokul (lise yaşı) beynime basıldığından beri her zaman 'Devesinde ve Eski Ulu Otu Oldu'yu tercih edeceğim.
George Duckett,

Orada da " S ome Ç ld H ıppy C ame A nd H reklam T yırtık Ç n A cid"
blissfreak

3

Benim favorilerimden biri Michael Abrash'in " The Code of Optimization" kodunda , 'Life' sürümünün İngilizce versiyonudur .

Kitaplarından herhangi birini, kodlama mücevherleri arayan herkese tavsiye ederim.

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.