Saya memiliki masalah yang sama untuk permainan yang saya tulis. Saya membayangkan bahwa masalah ini akan berbeda berdasarkan pada bagaimana tepatnya Anda menerapkan sistem isometrik Anda, tetapi saya akan menjelaskan bagaimana saya memecahkan masalah tersebut.
Saya pertama kali mulai dengan fungsi tile_to_screen saya. (Saya berasumsi itulah bagaimana Anda menempatkan ubin di lokasi yang tepat di tempat pertama.) Fungsi ini memiliki persamaan untuk menghitung screen_x dan screen_y. Milik saya terlihat seperti ini (python):
def map_to_screen(self, point):
x = (SCREEN_WIDTH + (point.y - point.x) * TILE_WIDTH) / 2
y = (SCREEN_HEIGHT + (point.y + point.x) * TILE_HEIGHT) / 2
return (x, y)
Saya mengambil dua persamaan itu dan membuatnya menjadi sistem persamaan linear. Selesaikan sistem persamaan ini dalam metode apa pun yang Anda pilih. (Saya menggunakan metode rref. Juga, beberapa kalkulator grafik dapat menyelesaikan masalah ini.)
Persamaan akhir terlihat seperti ini:
# constants for quick calculating (only process once)
DOUBLED_TILE_AREA = 2 * TILE_HEIGHT * TILE_WIDTH
S2M_CONST_X = -SCREEN_HEIGHT * TILE_WIDTH + SCREEN_WIDTH * TILE_HEIGHT
S2M_CONST_Y = -SCREEN_HEIGHT * TILE_WIDTH - SCREEN_WIDTH * TILE_HEIGHT
def screen_to_map(self, point):
# the "+ TILE_HEIGHT/2" adjusts for the render offset since I
# anchor my sprites from the center of the tile
point = (point.x * TILE_HEIGHT, (point.y + TILE_HEIGHT/2) * TILE_WIDTH)
x = (2 * (point.y - point.x) + self.S2M_CONST_X) / self.DOUBLED_TILE_AREA
y = (2 * (point.x + point.y) + self.S2M_CONST_Y) / self.DOUBLED_TILE_AREA
return (x, y)
Seperti yang Anda lihat, ini tidak sederhana seperti persamaan awal. Tapi itu bekerja dengan baik untuk game yang saya buat. Syukurlah untuk aljabar linier!
Memperbarui
Setelah menulis kelas Point sederhana dengan berbagai operator, saya menyederhanakan jawaban ini sebagai berikut:
# constants for quickly calculating screen_to_iso
TILE_AREA = TILE_HEIGHT * TILE_WIDTH
S2I_CONST_X = -SCREEN_CENTER.y * TILE_WIDTH + SCREEN_CENTER.x * TILE_HEIGHT
S2I_CONST_Y = -SCREEN_CENTER.y * TILE_WIDTH - SCREEN_CENTER.x * TILE_HEIGHT
def screen_to_iso(p):
''' Converts a screen point (px) into a level point (tile) '''
# the "y + TILE_HEIGHT/2" is because we anchor tiles by center, not bottom
p = Point(p.x * TILE_HEIGHT, (p.y + TILE_HEIGHT/2) * TILE_WIDTH)
return Point(int((p.y - p.x + S2I_CONST_X) / TILE_AREA),
int((p.y + p.x + S2I_CONST_Y) / TILE_AREA))
def iso_to_screen(p):
''' Converts a level point (tile) into a screen point (px) '''
return SCREEN_CENTER + Point((p.y - p.x) * TILE_WIDTH / 2,
(p.y + p.x) * TILE_HEIGHT / 2)