Ich hatte das gleiche Problem für ein Spiel, das ich schrieb. Ich stelle mir vor, dass dieses Problem davon abhängt, wie genau Sie Ihr isometrisches System implementiert haben, aber ich werde erklären, wie ich das Problem gelöst habe.
Ich habe zuerst mit meiner Funktion tile_to_screen begonnen. (Ich gehe davon aus, dass Sie die Kacheln auf diese Weise an der richtigen Stelle platzieren.) Diese Funktion hat eine Gleichung zur Berechnung von screen_x und screen_y. Meins sah so aus (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)
Ich nahm diese beiden Gleichungen und machte sie zu einem System linearer Gleichungen. Lösen Sie dieses Gleichungssystem mit einer beliebigen Methode. (Ich habe eine rref-Methode verwendet. Außerdem können einige Grafikrechner dieses Problem lösen.)
Die endgültigen Gleichungen sahen folgendermaßen aus:
# 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)
Wie Sie sehen können, ist es nicht so einfach wie die Anfangsgleichung. Aber es funktioniert gut für das Spiel, das ich erstellt habe. Gott sei Dank für die lineare Algebra!
Aktualisieren
Nachdem ich eine einfache Point-Klasse mit verschiedenen Operatoren geschrieben hatte, vereinfachte ich diese Antwort auf Folgendes:
# 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)