2011-11-02 2 views
6

Mi sto esercitando in una semplice programmazione di giochi 2D e mi è venuta in mente una teoria durante l'animazione (il cambiamento effettivo in una posizione dell'immagine viene calcolato al meglio con numeri in virgola mobile). Ho la sensazione che se si muove un'immagine con ints l'animazione non sarà così liscia.Cosa succede quando si converte double (o float) in ints?

In Java sembra che non sia possibile disegnare un'immagine con numeri in virgola mobile per dare un'immagine a una posizione. Ma apparentemente quando dichiari inizialmente il tuo x e y, puoi dichiararlo come Double o Float, e quando si tratta di disegnare effettivamente l'immagine devi lanciarli in ints. Come trovo HERE:

/** 
* Draw this entity to the graphics context provided 
* 
* @param g The graphics context on which to draw 
*/ 
public void draw(Graphics g) { 
    sprite.draw(g,(int) x,(int) y); 
} 

La mia domanda è su come Java gestisce la conversione? Se il codice lancia questi doppi all'ultimo minuto, perché li hanno raddoppiati? Java nasconde i numeri dopo il decimale?

So che in C e C++ i numeri dopo il decimale vengono troncati e si vede solo che cosa c'è prima. In che modo Java gestisce questo casting?

+2

Diminuisce solo il decimale, come C, C++. http://www.fluffycat.com/Java/Casting/ – dmcnelis

+0

Dovresti eseguire i calcoli in doppio il più possibile, e quando alla fine lo passi a un metodo che accetta int, fai Math.round(). – Stephan

risposta

4

I pixel su un display sono discreti e in numero limitato; quindi le coordinate di visualizzazione devono essere numeri interi - i numeri in virgola mobile non hanno senso, poiché non si ha fisicamente un pixel ad es. (341.4, 234,7).

Detto questo, gli interi devono essere utilizzati solo nella fase di disegno finale. Quando si calcola il movimento dell'oggetto, la velocità ecc., È necessario utilizzare i numeri in virgola mobile. Gli interi causeranno un numero incredibile di problemi di precisione. Si consideri il seguente frammento di codice:

a = 1; 
x = (a/2) * 2; 

Se a e x numeri in virgola sono galleggianti, x avranno finalmente il numero atteso di 1. Se sono numeri interi, otterrai 0.

Linea di base: utilizzare i tipi a virgola mobile per i calcoli fisici e convertire in int in fase di disegno. Ciò ti consentirà di eseguire i calcoli fisici con la stessa precisione richiesta.

EDIT:

quanto riguarda la conversione da numeri FP interi è interessato, mentre i numeri FP hanno una gamma maggiore, i valori prodotta dal calcolo fisica dopo normalizzazione alle dimensioni dell'area di disegno, non dovrebbero traboccare un int tipo.

Detto, Java tronca i numeri in virgola mobile durante la conversione in un tipo intero, che può creare artefatti (ad esempio un'animazione con nessun pixel alla colonna di pixel più a destra, per esempio 639.9 essendo convertito 639 anziché 640). Potresti dare un'occhiata a Math.round() o ad alcuni degli altri metodi di arrotondamento forniti da Java per ottenere risultati più ragionevoli.

2

Java lancia float su int facendo cadere il decimale. Ma non penso che avere le coordinate x e y nei float abbia senso. Hai pixel sullo schermo che non possono essere presentati in qualcosa di meno di un pixel. Ad esempio, non è possibile disegnare un pixel .5px x .5px perché sullo schermo sarà solo 1px x 1px pixel. Non sono un programmatore di giochi per computer, ma ho scritto un motore di animazione in Java ed è stato molto semplice. Posso condividerlo se vuoi.

Nota che dovresti disegnare usando ints ma fai tutti i tuoi calcoli usando il doppio. Per cose come la rotazione o qualsiasi cosa che si basa su una formula matematica dovrebbe essere fatto in decimale.

+1

I float sono utili per vari motivi - tra questi, che 'sin' /' cos' (quasi una necessità per una rotazione decente) li richiede praticamente, e molti strumenti matrix possono beneficiare della capacità dei numeri di assumere valori frazionari. Li trasformi in intarsi, finisci per perdere molta flessibilità (a meno che tu non voglia scrivere le tue proprie funzioni trigonometriche e così via). Così molti li manterranno come doppi o galleggianti fino a che devono essere assolutamente intatti. – cHao

+0

Questo è vero. Non intendevo fare i tuoi calcoli in pollici. Nella mia applicazione faccio ancora tutti i calcoli in doppio e disegno usando gli inte. Aggiornerò per riflettere questa nota. –

+0

@AmirRaminfar posso dare un'occhiata a questo? – mastrgamr

3

Java tronca i decimali. Es:

(int) 2.34 == 2 
(int) 2.90 == 2 

La ragione per non essere in grado di elaborare in una posizione flottante è semplicemente che non c'è nessun pixel mezze ecc :)

+0

Vedo. Grazie per l'input, ha senso – mastrgamr

1

La ragione xey necessità di essere doppi è per quando devono essere calcolato matematicamente, ad esempio:

x += (delta * dx)/1000; 

si vuole evitare di overflow e perdita di precisione fino a quando si dipinge il pixel.

+0

quindi immagino che prima che il doppio venga castato è calcolato per avvicinarsi il più vicino possibile al più accurato int possibile? (se ciò avesse senso O_o) – mastrgamr