J'ai eu ce même problème pour un jeu que j'écrivais. J'imagine que ce problème différera en fonction de la façon dont vous avez implémenté votre système isométrique, mais je vais vous expliquer comment j'ai résolu le problème.
J'ai d'abord commencé avec ma fonction tile_to_screen. (Je suppose que c'est ainsi que vous placez les tuiles au bon endroit en premier lieu.) Cette fonction a une équation pour calculer screen_x et screen_y. Le mien ressemblait à ceci (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)
J'ai pris ces deux équations et les ai transformées en un système d'équations linéaires. Résolvez ce système d'équations dans la méthode que vous choisissez. (J'ai utilisé une méthode rref. De plus, certaines calculatrices graphiques peuvent résoudre ce problème.)
Les équations finales ressemblaient à ceci:
# 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)
Comme vous pouvez le voir, ce n'est pas aussi simple que l'équation initiale. Mais cela fonctionne bien pour le jeu que j'ai créé. Dieu merci pour l'algèbre linéaire!
Mise à jour
Après avoir écrit une classe Point simple avec différents opérateurs, j'ai simplifié cette réponse comme suit:
# 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)