2010-09-13 4 views
5

J'essaie de comprendre comment obtenir la bonne tuile «active» sous la souris lorsque j'ai des tuiles «rampe» et +1 (voir l'image ci-dessous).Écran isométrique sur la carte


Example Isometric Image

Quand mon monde est plat, tout fonctionne sans problème. Une fois que j'ajoute une tuile avec une hauteur de dire +1, avec une rampe qui remonte à +0, ma routine écran -> carte semble toujours comme si tout était "plat".

Dans l'image ci-dessus, la "rampe" verte est la vraie tuile que je veux rendre et calculer la souris -> carte, cependant la tuile bleue que vous voyez "ci-dessous" est la zone qui est calculée. Donc, si vous déplacez votre souris dans l'une des zones vert foncé, il pense que vous êtes sur une autre tuile.

Voici ma carte render (très simple)

canvas.width = canvas.width; // cheap clear in firefox 3.6, does not work in other browsers 
for(i=0;i<map_y;i++){ 
    for(j=0;j<map_x;j++){ 
     var xpos = (i-j)*tile_h + current_x; 
     var ypos = (i+j)*tile_h/2+ current_y; 

     context.beginPath(); 
     context.moveTo(xpos, ypos+(tile_h/2)); 
     context.lineTo(xpos+(tile_w/2), ypos); 
     context.lineTo(xpos+(tile_w), ypos+(tile_h/2)); 
     context.lineTo(xpos+(tile_w/2), ypos+(tile_h)); 
     context.fill(); 

    } 
}  

Et voici ma souris -> routine de carte:

ymouse=((2*(ev.pageY-canvas.offsetTop-current_y)-ev.pageX+canvas.offsetLeft+current_x)/2); 
xmouse=(ev.pageX+ymouse-current_x-(tile_w/2)-canvas.offsetLeft); 
ymouse=Math.round(ymouse/tile_h); 
xmouse=Math.round(xmouse/(tile_w/2)); 

current_tile=[xmouse,ymouse]; 

j'ai un sentiment que je vais devoir recommencer et mettre en œuvre un système de carte basé sur le monde plutôt qu'un simple écran -> routine de carte.

Merci.

Répondre

2

Votre hypothèse est correcte. Afin de «choisir» contre la géométrie mondiale, votre routine doit être consciente du monde (et pas seulement la configuration de la tuile de base). Autrement dit, sans aucun concept de la hauteur des tuiles près de celle qui est actuellement sélectionnée (par votre algorithme actuel), il n'y a aucun moyen de déterminer si une tuile voisine (ou une plus éloignée, selon la hauteur permise) devrait être intercepté en choisissant le rayon.

Vous avez déjà le dernier point possible de votre rayon de prélèvement. Ce qui reste est de définir le reste du rayon, dans l'espace-monde, et de vérifier ce rayon pour les intersections avec la géométrie du monde.

2

Si, comme l'image, l'angle de vue est toujours 45 degrés et toujours de la même direction, votre souris -> routine de carte pourrait utiliser quelque chose d'algorithme comme:

  1. calculer i, j de tuile comme vous faites actuellement (votre valeur finale de xmouse, ymouse)
  2. regarder en hauteur et l'angle de boisseaux à i, j
  3. compte tenu de la hauteur et l'angle, est-ce carrelage intersecte le rayon choisir? Si oui, définissez lasti, lastj = i, j
  4. incrémenter/décrémenter i, j un pas diagonalement vers le téléspectateur
  5. sommes-nous tombés du bord de la carte? Si oui, renvoyez lasti, lastj. Sinon, retournez à 2.

En fonction de la hauteur maximale d'une tuile, vous devrez peut-être vérifier seulement 2 tuiles, plutôt que d'aller jusqu'au bord de la carte.

3 est la partie délicate, et dépend de votre géométrie du monde. Dessinez des triangles et vous devriez être capable de le comprendre. Ou vous pourriez essayer de regarder la fonction intersect_quadrilateral_ray() here.