J'écris un jeu 2D isométrique et j'ai du mal à déterminer avec précision sur quelle tuile se trouve le curseur. Voici un dessin:
où xs et ys sont des coordonnées d'écran (pixels), xt et yt sont des coordonnées de tuile, W et H sont la largeur et la hauteur de tuile en pixels, respectivement. Ma notation pour les coordonnées est (y, x), ce qui peut prêter à confusion, désolé.
Le mieux que j'ai pu comprendre jusqu'à présent est le suivant:
int xtemp = xs / (W / 2);
int ytemp = ys / (H / 2);
int xt = (xs - ys) / 2;
int yt = ytemp + xt;
Cela semble presque correct mais me donne un résultat très imprécis, ce qui rend difficile la sélection de certaines tuiles, ou parfois il sélectionne une tuile à côté de celle sur laquelle j'essaie de cliquer. Je ne comprends pas pourquoi et j'aimerais que quelqu'un m'aide à comprendre la logique derrière tout ça.
Merci!
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):
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:
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:
la source
Vous utilisez un bon système de coordonnées. Les choses deviennent beaucoup plus compliquées si vous utilisez des colonnes décalées.
Une façon de penser à ce problème est que vous avez une fonction pour transformer (xt, yt) en (xs, ys). Je vais suivre la réponse de Thane et l'appeler
map_to_screen
.Vous voulez l' inverse de cette fonction. Nous pouvons l'appeler
screen_to_map
. Les inverses de fonction ont ces propriétés:Ces deux sont de bonnes choses pour le test unitaire une fois que vous avez écrit les deux fonctions. Comment écris-tu l'inverse? Toutes les fonctions n'ont pas des inverses mais dans ce cas:
Assurez-vous de tester que la fonction inverse + originale donne la réponse avec laquelle vous avez commencé. Thane's réussit les deux tests, si vous sortez le
+ TILE_HEIGHT/2
décalage de rendu. Quand j'ai résolu l'algèbre, j'ai trouvé:qui je crois est le même que celui de Thane
screen_to_map
.La fonction transformera les coordonnées de la souris en flottants; utiliser
floor
pour les convertir en coordonnées de tuiles entières.la source