2011-10-31 12 views
14

Sto realizzando un gioco in C++ dove è un carro armato che può spostarsi su un palco. Il carro armato ha un angolo (galleggia, in gradi, e suppongo che il serbatoio sia a 0º quando il suo cannone punta a destra), una velocità (galleggiante), e c'è una costante di tempo chiamata "deltaT" (galleggiante).C++ gamedev: truncating float to int

Quando il giocatore sposta il serbatoio in avanti, io uso la trigonometria e l'equazione fisica della posizione in funzione del tempo (intendo X (t), non so come si dice in inglese) per calcolare il nuovo coordinate del carro armato nel palco.

Questo è il mio problema: a causa del passaggio da float a int, i valori più vicini allo zero non vengono presi in considerazione. Quindi, ad alcuni angoli, il serbatoio appare ruotato, ma si muove in una direzione diversa.

Questo è quello che il mio codice fa:

1 - primo, io separare la velocità nei suoi componenti X e Y, utilizzando l'angolo della ricezione di tale serbatoio è in movimento:

float speedX = this->speed * cos(this->angle); 
    float speedY = this->speed * sin(this->angle); 

2 - quindi utilizzare l'equazione ho citato sopra per ottenere le nuove coordinate:

this->x = (int) ceil(this->x + (speedX * deltaT)); 
    this->y = (int) ceil(this->y - (speedY * deltaT)); 

il problema inizia al primo passo: in certi angoli, il valore del cos o il peccato è molto vicino a zero. Quindi, quando lo si moltiplica per ottenere la velocità, ad esempio, speedX, ho ancora un numero molto basso, e poi quando lo si moltiplica per deltaT è ancora troppo basso, e infine quando si applica il ceil, quella somma è totalmente persa .

Per esempio, al 94º, con deltaT = 1,5, e la velocità = 2, e assumendo valore iniziale di X è di 400, abbiamo:

speedX = -0.1395... 
this->x = 400 //it must be 399.86..., but stays in 400 due to the ceiling 

Così, nel mio gioco appare ruotato il serbatoio, ma si muove dritto in avanti. Inoltre, a volte si muove bene all'indietro ma sbaglia in avanti, e viceversa.

¿Come posso fare per rendere più precisa la direzione del serbatoio? Per aumentare la velocità o il valore di deltaT non sono opzioni poiché si tratta di un serbatoio, non di una formula 1: P

+4

+1: buon lavoro che spiega la tua domanda e fornisce codice minimo pertinente. – ObscureRobot

+1

La memorizzazione degli angoli come gradi è raramente utile. C++ funziona in modo nativo in radianti. Finirai per convertire avanti e indietro. L'unica eccezione in cui non utilizzeresti i radianti è quando hai una schiera di sprite, una per ogni rotazione del serbatoio. In tal caso, può essere utile utilizzare l'indice dell'array. Ma nessuno farebbe sprites 360; 128 (4x32) sarebbe molto più comune. – MSalters

+0

@MSalters Sì, mi sono reso conto dei radianti troppo tardi. Ma in realtà, il codice che ho postato è un po 'semplificato: non uso le funzioni sin e cos dalla libreria matematica, ma ho tabulato i valori di cos e sin di certi angoli, per evitare di calcolare li in runtime. Inoltre, per le immagini ruotate, non ho 128 sprite, ma ne ho solo una, e uso la funzione "rotozoomSurface" (in SDL_gfx lib, un add on per SDL), che funziona con gradi. – Granjero

risposta

9

Come posso fare per rendere più precisa la direzione del serbatoio? Per aumentare la velocità o il valore di deltaT non sono opzioni in quanto si tratta di un carro armato, non è una formula 1: P

È possibile memorizzare il valori di posizione come float s, anche se sono in ultima analisi, utilizzati come int s per posizionamento sullo schermo. In questo modo, non perderai la porzione non intera della tua posizione. Basta trasmettere a int proprio alla fine quando fai il tuo disegno.

+1

Oh, grazie mille! Ho appena apportato le modifiche al codice e funziona! Non posso credere che sia stato così semplice – Granjero

5

Mantenere la posizione del serbatoio in float s tutto il tempo. In alternativa, lasciare ruotare il serbatoio solo con incrementi di 45 gradi. Decidi se il tuo gioco utilizzerà posizioni e titoli approssimativi o quelli esatti e manterrai la decisione fino in fondo.

+0

_In alternativa, lasciare ruotare il serbatoio solo di 45 gradi._ Sì, l'ho provato prima, ma il serbatoio ruotava troppo velocemente e in modo non molto fluido. – Granjero