Quali sono le tue gemme di codifica preferite specifiche del gioco? [chiuso]


24

Comincerò con John Carmack l'inversa Fast radice quadrata in 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
Non è proprio una domanda - per lo meno, potresti dichiarare questa una pagina wiki della comunità ...
Rachel Blum,

Fatto, adattato alla community.
prendi il

3
Fanculo! basta andare con qualsiasi codice creato dal grande JC!
Adam Naylor,

3
A proposito, nota che c'è un "numero magico" più preciso da usare nella funzione radice quadrata inversa veloce: 0x5f375a86 ( en.wikipedia.org/wiki/… )
Ricket

8
Si noti inoltre che non è di John Carmack.
Kaj,

Risposte:


25

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

Prende un valore, lo converte in una proporzione all'interno di un intervallo, quindi lo ridimensiona rispetto a un altro intervallo. Come un doppio giro.

Puoi usarlo per normalizzare le cose:

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

Oppure puoi convertire da un intervallo all'altro:

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

Si noti nel secondo esempio che l'intervallo di uscita è un ordine diverso dall'intervallo di entrata.

Non sembra molto, ma uso questo piccolo amico dappertutto.


14

Non riesco ancora a credere quante volte ho usato il Teorema di Pitagora nel mio codice di gioco. Per me, questa semplice formula è un gioiello nello sviluppo del gioco.

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

o

testo alternativo
(fonte: mathurl.com )

e quando conta solo la distanza relativa, può essere usata senza costose operazioni con radice quadrata

testo alternativo
(fonte: mathurl.com )


Per essere onesti, la matematica di Pitagora viene utilizzata TUTTO sul codice di gioco, in particolare i motori, come il codice fisico, il codice di rendering, l'IA.
Nick Bedford,

1
Vero. Ecco perché è un gioiello. ;)
MrValdez,

4
Una variazione interessante è quando ti preoccupi solo delle distanze relative . Quindi puoi saltare la sqrtchiamata potenzialmente costosa e semplicemente calcolare distance2 = x^2 + y^2.
mmyers,

@mmyers - Un'altra cosa meravigliosa: se lavori nello spazio x ^ 2, la distanza non è solo relativa.
Steven Evers,

Grazie per aver menzionato il bit relativo della distanza. Ho visto troppe operazioni di radice quadrata non necessarie, proprio come le persone che usano A * quando dovrebbero usare qualcosa di meno esatto.
Ricket,

13

Il più grande da me stava leggendo del sistema GameObject di Scott Bilas. Anche se non uso un sistema di database come lui, mi ha impedito di creare alberi di ereditarietà a 6 livelli e mi ha permesso di creare un sistema componente che è molto più gestibile e riutilizzabile.


10

Devo andare con il dispositivo di Duff . È stato il primo blocco di codice che mi ha letteralmente lasciato cadere. "Ce la puoi fare?!?"


Oh mio Dio. Gli occhiali! Non fanno niente!
Raoul,

Il "do-while" annidato all'interno della "custodia" mi fa sempre battere le palpebre. Anche 20 anni dopo ...
Andreas,

1
-1. Non mi piace questo. Non è molto utile oggi ( memcpy
useresti

1
@JoeWreschnig perché no? Memcpy sarà sempre più leggibile, portatile e probabilmente più ottimizzato.
Kaao

1
@kaoD: Poiché memcpy non è equivalente al dispositivo di Duff - non importa quanto sia "leggibile, portatile e probabilmente più ottimizzato" se non fa la stessa cosa! Le moderne pipeline della CPU probabilmente faranno meglio senza il dispositivo di Duff che con esso a causa della previsione del ramo e della memorizzazione delle istruzioni nella cache, ma questo non ha nulla a che fare con memcpy.

7

Un piccolo frammento C / C ++ di un gioco che ho aiutato a scrivere molti anni fa:

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

Nel mio primo gioco ( questo ) avevo bisogno di accedere a più di 1 Mb di RAM e, essendo questo prima del decollo di Internet, non avevo documentazione per XMS ed EMS che le app DOS usavano per accedere alla RAM aggiuntiva.

Così, ho finito per usare una piccola "backdoor" che appariva nel 386 per quanto riguarda i registri di segmento. Normalmente, in modalità reale, l'indirizzo è stato calcolato come un seg*16+offlimite di 1 Mb.

Tuttavia, è possibile passare alla modalità protetta, impostare un segmento per indirizzare 4 Mb, tornare indietro e purché non si scriva nel registro dei segmenti (il che era OK poiché DOS utilizzava solo i registri dei segmenti 8086), si poteva accedere all'intero 4 Mb come spazio di indirizzamento piatto. Tornare alla modalità reale era necessario se si desidera utilizzare i servizi DOS.

Non c'erano nemmeno molti extender DPMI disponibili.


Funziona quasi in C # (devi dichiarare un tipo delegato e inserire almeno un cast)
finnw,

Intendi con modalità di indirizzamento a 32 bit in modalità reale? (vale a dire che richiede un prefisso di dimensione dell'indirizzo). Sei sicuro che fosse necessario impostare un descrittore di segmento e che in realtà non usasse il registro di segmento come il normale 16 * FS +? Non pensavo che i segmenti avessero anche limiti nella modalità a 16 bit, solo l'indirizzo di base (16 * il loro valore), quindi non potevi semplicemente impostare FS su qualcosa in modalità a 16 bit e usare [fs:esi]o qualunque cosa per accedere a qualunque cosa tu ricercato?
Peter Cordes,

Non ho provato questo, o scritto alcun codice reale per la modalità a 16 bit, solo a 32 e 64 bit, ma suona strano. Hmm, plausibile però. Le CPU moderne memorizzano sicuramente nella cache i contenuti dei segmenti internamente e ricaricano quelle cache solo quando si scrive nei registri dei segmenti, quindi forse è così che ha mantenuto il limite + della modalità protetta (se è effettivamente quello che è successo, e non si stava semplicemente usando il 4 MB a partire da 16 * FS).
Peter Cordes,

5

Personalmente sono un grande fan di Mersenne Twister per numeri casuali prevedibili, soprattutto se è necessario creare diverse istanze di Rand in modo diverso

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


Mersenne Twister è carino nel senso che è un buon generatore di numeri casuali, ma non è particolarmente elegante o bello (o veloce o facile da implementare). Per questo, potresti voler guardare en.wikipedia.org/wiki/Rule_30 .

1
WELL è generalmente migliore di MT per la maggior parte degli usi .. en.wikipedia.org/wiki/Well_equidistributed_long-period_linear
Jari Komppa,

5

Eccone uno menzionato da Chris Crawford (e apparentemente usato da Atari) che lui chiama "A Graphics Trick":

LDA FIRST
EOR SECOND
AND CONTROL
EOR SECOND
STA OUTPUT

Leggi l' articolo completo per una spiegazione.


1
Quel collegamento è ora interrotto, quindi sarebbe utile avere una spiegazione qui.
finnw,

Grazie. Se n'è andato e ha cambiato di nuovo il suo sito web. Ho aggiornato il link.
Anthony,

4

Per qualche ragione, le persone spesso sottovalutano il potere dei modelli di progettazione nei giochi. Ho visto quasi ogni singolo modello GoF applicato con successo ai giochi.


1
Una delle cose che mi piacciono della programmazione dei giochi è allontanarmi dal modo standard di "correttezza" GoF e concentrarmi solo sulla pura velocità adorabile! Detto questo, ho visto molte cattive implementazioni di MVC nei giochi che fanno più male che bene.
Iain,

Penso che i modelli di design abbiano il loro posto. Non tanto nei giochi, però.
Blissfreak

@blissfreak: Non c'è niente di speciale nella programmazione del gioco che lo rende una specie di selvaggio west in cui i modelli non sono comuni. Sono ridicolmente comuni e qui ci sono alcuni esempi.
Steven Evers,

4

Math.atan2 () è estremamente utile (insieme a tutti i trig).


Lo è, cavolo! Ho fatto un sacco di 3D e non ne ho mai avuto davvero bisogno.
Skizz,

+1, è l'unico modo per passare dai componenti vettoriali x + y alla direzione dei radianti.
RCIX,

1
@RCIX: Il mio punto è che quella trasformazione non è necessaria, cioè (x, y) -> angolo, esiste una soluzione vettoriale per qualsiasi problema di angolo.
Skizz,

6
Non definirei una semplice funzione di libreria standard un "gioiello".

1
@Skizz: Forse per 3d, ma non conosco nessun altro modo per prendere un vettore normalizzato ed estrarre un valore di direzione radianti. Che come un buon valore nei giochi 2D.
RCIX,

3

Per aggiungere alla gemma pitagorica sopra ...
Dico sempre alle persone che per la programmazione 3d devono solo sapere:
- a ^ 2 + b ^ 2 = c ^ 2
- soscastoa (sin = lato opposto / lato inclinato, cos = lato attaccato / lato inclinato, marrone chiaro = lato opposto / lato attaccato)
- a. b = | a | * | b | * cos alpha
- a * b = | a | * | b | * sin alpha * unit vector
Può risolvere praticamente qualsiasi problema 3d (o 2d) che riscontri nello sviluppo del gioco - 4 regole.
Certo, ci sono modi più belli, ma questo può risolverli tutti - dovrei sapere, sono un hack che ha basato una carriera su di loro.


5
re: soscastoa Penso che la maggior parte delle persone lo sappia come sohcahtoa (sostituendo il "lato inclinato" con il più specifico, seppure più oscuro, "ipotenusa"). Scorre più facilmente la lingua e penso quindi più facile da ricordare.
Asmor,

1
Preferirò sempre "The Old Arab Sat On His Camel And Howled", dal momento che la scuola secondaria (liceo) è stata impressa nel mio cervello.
George Duckett,

C'è anche " S ome O ld H ippy C ame A nd H ad T ripped O n A cid"
blissfreak

3

Uno dei miei preferiti è la versione in linguaggio assembly di "Life" e l'intera descrizione dell'ottimizzazione in " The Zen of Code Optimization" di Michael Abrash.

Consiglierei uno qualsiasi dei suoi libri a chiunque cerchi gemme di programmazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.