Rendu isométrique et picking?

23

Je cherchais une formule pour tracer (monde-> écran) et choisir des tuiles isométriques (monde-> écran) dans un monde en forme de diamant. Ceux que j'ai essayés semblent toujours éteints. Quelle est la manière habituelle / correcte de procéder?

mpnk121
la source
La méthode et la formule exactes utilisées dépendent un peu de la forme de vos carreaux, et probablement un peu de la façon dont vous dessinez la carte (est 0,0 en haut, en bas ou sur l'un des côtés de la carte) Plus de détails à propos de votre problème serait utile.
thedaian
1
Les tuiles sont 2: 1 (plus précisément, 64x32). Le système de coordonnées n'a pas d'importance puisque j'écris l'éditeur. (0,0 en haut ou à gauche semble cependant raisonnable.)
mpnk121
Très tard à la question et je n'ai même pas de réponse complète, mais il y a eu un très bon Google Tech Talk sur ce sujet précis. Leur configuration comprend la sélection de la partie non transparente des images arbitraires (en javascript, pas moins). youtube.com/watch?v=_RRnyChxijA
Seth Battin

Réponses:

21

Sur la base de votre commentaire, voici le code que j'utilise pour convertir les valeurs des tuiles x, y en coordonnées à l'écran. Maintenant, il ne prend pas en compte les "tuiles 3D", tout est considéré comme étant sur le même plan, donc si vous écrivez un jeu là où ça compte, ce code ne fonctionnera pas.

//this converts a map x/y coordinate into screen coordinates
//public, static method, so can be called outside the Tile object
point Tile::convertToScreen(int x, int y, int offsetX, int offsetY)
{
        point screen;
        //calculate the screen coordinates
        //note: these will then be modified by the camera
        screen.x = offsetX - (y * TILE_WIDTH/2) + (x * TILE_WIDTH/2) - (TILE_WIDTH/2);
        screen.y = offsetY + (y * TILE_DEPTH/2) + (x * TILE_DEPTH/2);
        return screen;
 }

le point est simplement une structure contenant des entiers x et y, TILE_WIDTH serait 64 dans votre cas, TILE_DEPTH est un peu mal nommé (c'est en fait la hauteur des graphiques de tuile), mais ce serait 32 dans votre cas. Les décalages sont si vous voulez que votre carte de tuiles "commence" à un emplacement x, y différent (comme si vous voulez que les tuiles soient au-dessus d'un autre ensemble de tuiles). Le décalage peut généralement être 0,0.

Cela générera une carte avec 0,0 en haut, au milieu, comme ceci:

        0,0
    0,1     1,0
0,2     1,1     2,1

Quant à trouver la tuile x, y du curseur:

point selectedTile;
int x = mX - camera.x;
int y = mY - camera.y;
selectedTile.x = (y + x/2)/TILE_DEPTH;
selectedTile.y = (y - x/2)/TILE_DEPTH;

Dans ce morceau de code, mX et mY sont les coordonnées de l'écran de la souris, que nous combinons avec les valeurs de la caméra pour savoir où nous en sommes dans les "coordonnées mondiales". Tout le reste est identique à l'exemple de code précédent.

Encore une fois, cela suppose une carte de tuile isométrique plate 2D. Il y a du travail supplémentaire si vous voulez utiliser une vue semi-3D de la carte, et tout cela suppose que vous travaillez dans 2d de toute façon.

thédaïen
la source
1
Merci! - cela fonctionne très bien pour les cartes plates. Maintenant, pouvez-vous m'en dire un peu plus sur la façon dont je pourrais ajouter des tuiles de taille arbitraire (c'est-à-dire avec une profondeur Z) qui sont sur une autre couche? (Comme des accessoires comme un puits ou un lampadaire)
mpnk121
2
C'est à ce moment que vous utilisez les valeurs offsetY et offsetX. Si votre lampadaire est 64x64, le fait de passer un 32 négatif pour la valeur offsetY devrait le faire apparaître au bon endroit. J'espère que cela suffit pour vous lancer.
thedaian
6
La coordonnée "2,1" dans votre exemple ne devrait-elle pas être un "2,0"?
Chris