Apa permata pengkodean khusus permainan favorit Anda? [Tutup]


24

Saya akan mulai dengan Root Inverse Square dari John Carmack di Quake III:

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
Itu sebenarnya bukan pertanyaan - paling tidak, Anda mungkin menyatakan ini halaman komunitas wiki ...
Rachel Blum

Selesai, digerakkan oleh komunitas.
gak

3
Persetan itu! ikuti saja dan semua kode yang dibuat oleh JC hebat!
Adam Naylor

3
Ngomong-ngomong, perlu diketahui bahwa ada "angka ajaib" yang lebih akurat untuk digunakan dalam fungsi root kuadrat terbalik cepat: 0x5f375a86 ( en.wikipedia.org/wiki/… )
Ricket

8
Juga perhatikan bahwa itu bukan milik John Carmack.
Kaj

Jawaban:


25

fungsi mapValue:

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;
}

Dibutuhkan nilai, mengubahnya menjadi proporsi dalam rentang, dan kemudian skala itu relatif terhadap rentang lain. Seperti double-lerp.

Anda dapat menggunakannya untuk menormalkan hal-hal:

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

Atau Anda dapat mengonversi dari satu rentang ke yang lain:

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

Perhatikan pada contoh kedua bahwa rentang keluar adalah urutan yang berbeda dengan kisaran dalam.

Itu tidak terlihat seperti banyak, tapi saya menggunakan teman kecil ini di semua tempat.


14

Saya masih tidak percaya berapa kali saya menggunakan Teorema Pythagoras dalam kode permainan saya. Bagi saya, formula sederhana ini adalah permata dalam pengembangan game.

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

atau

teks alternatif
(sumber: mathurl.com )

dan ketika hanya masalah jarak relatif dapat digunakan tanpa operasi akar kuadrat mahal

teks alternatif
(sumber: mathurl.com )


Sejujurnya, matematika Pythagoras digunakan SEMUA atas kode permainan, terutama mesin, seperti kode fisika, kode render, AI.
Nick Bedford

1
Benar. Itu sebabnya permata. ;)
MrValdez

4
Variasi yang menarik adalah ketika Anda hanya peduli pada jarak relatif . Kemudian Anda dapat melewatkan sqrtpanggilan yang berpotensi mahal dan cukup menghitung distance2 = x^2 + y^2.
Mmyers

@mmyers - Hal luar biasa lainnya: jika Anda bekerja di ruang x ^ 2, jaraknya tidak hanya relatif.
Steven Evers

Terima kasih telah menyebutkan bit jarak relatifnya. Saya telah melihat terlalu banyak operasi root kuadrat yang tidak perlu, seperti halnya orang yang menggunakan A * ketika mereka seharusnya menggunakan sesuatu yang kurang tepat.
Ricket

13

Yang terbesar dari saya adalah membaca tentang sistem GameObject Scott Bilas. Meskipun saya tidak menggunakan sistem database seperti dia, itu menghentikan saya membuat pohon pewarisan 6 tingkat dan membuat saya membuat sistem komponen yang jauh lebih mudah dikelola dan digunakan kembali.


10

Saya harus menggunakan Duff's Device . Itu adalah blok kode pertama yang benar-benar membuat rahang saya jatuh. "Kamu bisa melakukannya?!?"


Oh Tuhan. Kacamata! Mereka tidak melakukan apa pun!
Raoul

"Do-while" yang bersarang di dalam "switch-case" selalu membuat saya berkedip. Bahkan 20 tahun kemudian ...
Andreas

1
-1. Saya tidak suka yang ini. Ini tidak terlalu berguna hari ini (Anda akan menggunakannya memcpy, jika Anda ingin orang lain dapat membaca kode Anda)
bobobobo

1
@ JoWreschnig kenapa tidak? Memcpy akan selalu lebih mudah dibaca, portabel dan mungkin lebih dioptimalkan.
Ayah

1
@ kaoD: Karena memcpy tidak setara dengan perangkat Duff - tidak masalah seberapa "mudah dibaca, portabel, dan mungkin lebih dioptimalkan" adalah jika memcpy tidak melakukan hal yang sama! Pipa CPU modern mungkin akan bekerja lebih baik tanpa perangkat Duff daripada dengan itu karena prediksi cabang dan caching instruksi, tetapi itu tidak ada hubungannya dengan memcpy.

7

Cuplikan C / C ++ kecil dari permainan yang saya bantu tulis bertahun-tahun yang lalu:

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

Pada game pertama saya ( ini ) saya perlu mengakses lebih dari 1Mb RAM, dan, ini sebelum internet lepas landas, saya tidak punya dokumentasi untuk XMS dan EMS yang digunakan aplikasi DOS untuk mengakses RAM tambahan.

Jadi, saya akhirnya menggunakan 'pintu belakang' kecil yang ditampilkan di 386 sehubungan dengan register segmen. Biasanya, dalam mode nyata, alamat dihitung sebagai seg*16+offyang membatasi Anda hingga 1 MB.

Namun, Anda dapat beralih ke mode terproteksi, mengatur segmen ke alamat 4Mb, beralih kembali, dan asalkan Anda tidak menulis ke register segmen (yang OK karena DOS hanya menggunakan register segmen 8086), Anda dapat mengakses keseluruhan 4Mb sebagai ruang alamat datar. Membalik kembali ke mode nyata diperlukan jika Anda ingin menggunakan layanan DOS.

Tidak ada banyak ekstensi DPMI yang tersedia.


Hampir berfungsi di C # (Anda perlu mendeklarasikan tipe delegasi dan memasukkan setidaknya satu pemeran)
finnw

Maksud Anda dengan mode pengalamatan 32-bit dalam mode nyata? (Yaitu membutuhkan awalan ukuran alamat). Apakah Anda yakin perlu membuat deskriptor segmen, dan bahwa itu tidak benar-benar menggunakan register segmen sebagai 16 * FS + normal apa pun? Saya tidak berpikir segmen bahkan memiliki batasan dalam mode 16-bit, hanya alamat dasar (16 * nilainya), jadi tidak bisakah Anda mengatur FS ke sesuatu dalam mode 16-bit, dan menggunakan [fs:esi]atau apa pun untuk mengakses apa pun yang Anda ingin?
Peter Cordes

Saya belum mencoba ini, atau menulis kode nyata untuk mode 16-bit, hanya 32 dan 64 bit asm, tetapi kedengarannya aneh. Hmm, masuk akal. CPU modern pasti men-cache hal-hal segmen secara internal, dan hanya memuat ulang cache ketika Anda menulis ke regs segmen, jadi mungkin begitulah ia mempertahankan batas + mode dasar terlindungi (jika itu yang sebenarnya terjadi, dan Anda tidak hanya menggunakan 4MB mulai dari 16 * FS).
Peter Cordes

5

Secara pribadi saya penggemar berat Mersenne Twister untuk angka acak yang dapat diprediksi, terutama jika Anda perlu membuat beberapa contoh yang berbeda dari Rand

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


Mersenne Twister bagus dalam arti itu adalah penghasil angka acak yang baik, tetapi tidak terlalu elegan atau keren (atau cepat atau mudah diimplementasikan). Untuk itu, Anda mungkin ingin melihat en.wikipedia.org/wiki/Rule_30 .

1
WELL umumnya lebih baik daripada MT untuk sebagian besar kegunaan .. en.wikipedia.org/wiki/Well_equidistributed_long-
Period_linear

5

Berikut ini yang disebutkan oleh Chris Crawford (dan tampaknya digunakan oleh Atari) yang ia sebut 'A Graphics Trick':

LDA FIRST
EOR SECOND
AND CONTROL
EOR SECOND
STA OUTPUT

Baca artikel lengkap untuk penjelasan.


1
Tautan itu sekarang terputus, jadi akan membantu jika ada penjelasan di sini.
finnw

Terima kasih. Dia pergi dan mengubah situs webnya lagi. Saya memperbarui tautannya.
Anthony

4

Untuk beberapa alasan, orang sering meremehkan kekuatan pola desain dalam game. Saya telah melihat hampir setiap pola GoF diterapkan dengan sukses ke gim.


1
Salah satu hal yang saya sukai dari pemrograman game adalah menjauh dari cara standar "kebenaran" GoF dan hanya berfokus pada kecepatan murni yang indah! Yang mengatakan, saya telah melihat banyak implementasi buruk dari MVC di game yang lebih berbahaya daripada baik.
Iain

Saya pikir pola desain ada di tempatnya. Tidak begitu banyak dalam game.
blissfreak

@blissfreak: Tidak ada yang istimewa tentang pemrograman game yang membuatnya menjadi semacam liar di mana pola tidak umum. Mereka sangat umum dan inilah beberapa contohnya.
Steven Evers

4

Math.atan2 () sangat berguna (bersama dengan semua trigonometri).


Ya ampun! Saya telah melakukan banyak 3D dan tidak pernah benar-benar membutuhkannya.
Skizz

+1, ini satu-satunya cara untuk beralih dari komponen vektor x + y ke arah radian.
RCIX

1
@RCIX: Maksud saya adalah bahwa transformasi itu tidak perlu, yaitu sudut (x, y) ->, ada solusi vektor untuk setiap masalah sudut.
Skizz

6
Saya tidak akan benar-benar menyebut fungsi perpustakaan standar yang kosong sebagai "permata".

1
@ Skizz: Mungkin untuk 3d, tetapi saya tahu tidak ada cara lain untuk mengambil vektor dinormalisasi dan mengekstrak nilai arah radian. Yang sebagai nilai bagus dalam game 2D.
RCIX

3

Untuk menambah permata pythagoras di atas ...
Saya selalu memberi tahu orang-orang bahwa untuk pemrograman 3d mereka hanya perlu tahu:
- a ^ 2 + b ^ 2 = c ^ 2
- soscastoa (sin = sisi berlawanan / sisi miring, cos = sisi terlampir / sisi miring, tan = sisi yang berlawanan / sisi yang menempel)
- a. b = | a | * | b | * cos alpha
- a * b = | a | * | b | * sin alpha * vektor unit
Dapat menyelesaikan hampir semua masalah 3d (atau 2d) yang Anda temui dalam pengembangan game - 4 aturan.
Tentu, ada cara yang lebih baik, tetapi ini bisa menyelesaikan semuanya - Saya harus tahu, saya adalah hack yang mendasarkan karir pada mereka.


5
re: soscastoa Saya pikir kebanyakan orang tahu itu sebagai sohcahtoa (mengganti 'sisi miring' dengan yang lebih spesifik, jika memang lebih jelas, 'hypotenuse'). Mengalir dari lidah lebih mudah, dan saya pikir itu lebih mudah diingat.
Asmor

1
Saya akan selalu lebih suka 'The Old Arab Sat On Camel And Howled', sejak sekolah menengah (usia sekolah menengah) itu sudah dicetak di otak saya.
George Duckett

Ada juga " S ome O ld H ippy C ame A nd H ad T ripped O n A cid"
blissfreak

3

Salah satu favorit saya adalah versi bahasa rakitan 'Life', dan seluruh deskripsi untuk mengoptimalkannya, di " Zen Pengoptimalan Kode" oleh Michael Abrash.

Saya akan merekomendasikan buku-bukunya kepada siapa pun yang mencari permata coding.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.