2011-11-02 10 views
6

Ćwiczę proste programowanie gier 2D i wymyśliłem teorię, która podczas animacji (rzeczywista zmiana położenia obrazu jest najlepiej obliczana z liczb zmiennoprzecinkowych). Mam wrażenie, że jeśli przesuniesz obraz z ints animacja nie będzie tak gładka.Co stanie się, gdy konwertujesz podwójne (lub pływające) na ints?

W Javie wydaje się, że nie można narysować obrazu z liczbami zmiennoprzecinkowymi, aby nadać obrazowi pozycję. Ale najwyraźniej, kiedy początkowo zadeklarujesz swoje numery, możesz zadeklarować je jako Double lub Float, a jeśli chodzi o rysunek, musisz je przesłać do int. Jak znajdę 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); 
} 

Moje pytanie brzmi, jak Java obsługuje konwersję? Jeśli kod rzuca te dwójki w ostatniej chwili, dlaczego ma je jako dwójka? Czy Java ukrywa liczby po przecinku?

Wiem, że w C i C++ liczby po przecinku zostają odcięte i widać tylko to, co przed nim. W jaki sposób Java obsługuje ten odlew?

+2

Po prostu upuszcza dziesiętne, tak samo jak C, C++. http://www.fluffycat.com/Java/Casting/ – dmcnelis

+0

Powinieneś wykonywać obliczenia w podwójnej ilości, jak tylko możesz, a kiedy w końcu przekazujesz ją do metody akceptującej int, robisz Math.round(). – Stephan

Odpowiedz

4

Piksele na wyświetlaczu są dyskretne i mają ograniczoną liczbę; dlatego współrzędne muszą być liczbami całkowitymi - liczby zmiennoprzecinkowe nie mają sensu, ponieważ fizycznie nie ma piksela na przykład (341.4, 234,7).

To powiedziawszy, liczby całkowite powinny być używane tylko na końcowym etapie rysowania. Podczas obliczania ruchu obiektu, prędkości itp. Należy używać liczb zmiennoprzecinkowych. Liczby całkowite spowodują niesamowitą liczbę problemów precyzji. Rozważmy następujący fragment:

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

Jeśli a i x są liczb zmiennoprzecinkowych, x będzie wreszcie oczekiwaną liczbę 1. Jeśli są liczbami całkowitymi, otrzymasz 0.

Linia bazowa: w przypadku obliczeń fizycznych należy używać typów zmiennoprzecinkowych i przekształcać je w int w czasie rysowania. Umożliwi to wykonywanie obliczeń fizyki z taką precyzją, jaka jest wymagana.

EDIT:

Jeśli chodzi o konwersję z numerami FP do liczb całkowitych jest zaniepokojony, gdy numery FP mają większy zasięg, wartości produkowany przez obliczeń fizyki po normalizacji do rozmiaru obszaru rysunku nie powinna normalnie przelewać int typ.

Niemniej Java obcina liczb zmiennoprzecinkowych przy konwersji do typu całkowitego, co może powodować artefakty (np animacji bez pikseli w kolumnie piksela skrajnej prawej, spowodowane np 639.9 przekształceniem 639 niż 640). Możesz chcieć rzucić okiem na Math.round() lub niektóre inne metody zaokrąglania zapewniane przez Javę, aby uzyskać bardziej sensowne wyniki.

2

Java rzuca pływa do int, upuszczając dziesiętny. Ale nie sądzę, że posiadanie współrzędnych x i y w elementach pływających ma jakiś sens. Na ekranie masz piksel, którego nie można wyświetlić w pikselach mniejszych niż jeden piksel. Na przykład nie można narysować piksela .5px x .5px, ponieważ na ekranie będzie to po prostu piksel o rozdzielczości 1px x 1px. Nie jestem programistą gier komputerowych, ale napisałem jeden silnik animacji w Javie i było bardzo gładko. Mogę to udostępnić, jeśli chcesz.

Pamiętaj, że powinieneś narysować używając ints, ale wykonuj wszystkie swoje obliczenia używając podwójnych. Rzeczy takie jak obracanie lub cokolwiek, co opiera się na matematycznej formule, powinno być wykonywane dziesiętnie.

+1

Pływaki są użyteczne z różnych powodów - między innymi, że "grzech"/"cos" (prawie konieczność przyzwoitej rotacji) praktycznie ich wymagają, a wiele macierzy ops może skorzystać z możliwości liczb do przyjmowania wartości ułamkowych. Przekształcasz je w int, w końcu tracisz dużą elastyczność (chyba, że ​​chcesz pisać własne funkcje trygonometryczne i takie). Tak wielu zachowa je jako podwójne lub pływające, dopóki nie będą musieli być intami. – cHao

+0

To prawda. Nie chciałem wykonywać twoich obliczeń w intach. W mojej aplikacji nadal wykonuję wszystkie obliczenia w podwójnym i losowaniu używając ints. Zaktualizuję, aby odzwierciedlić tę notatkę. –

+0

@AmirRaminfar mogę to obejrzeć? – mastrgamr

3

Java obcina znaki dziesiętne. Np:

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

Powodem nie jest w stanie wyciągnąć w pozycji pływającej jest po prostu, że nie ma pół pikseli itp :)

+0

Rozumiem. Dzięki za dane wejściowe, to ma sens – mastrgamr

1

Powodem x i y trzeba być podwaja się, gdy muszą obliczyć matematycznie, na przykład:

x += (delta * dx)/1000; 

chcesz uniknąć przepełnienia i utraty dokładnością aż farba piksel.

+0

, więc domyślam się, że przed wyrzuceniem podwójnej liczby oblicza się, aby uzyskać jak najbliższe dokładniejsze int, jak to możliwe? (jeśli to ma sens O_o) – mastrgamr

Powiązane problemy