Table des matières

3D et Isométrie

Pourquoi cet article

J'ai écris cet article, car malgré des recherches avancées, je n'arrive pas a trouver de source complète sur le sujet ni vraiment de mise en pratique de la théorie, certes il existe des plug-ins ou du code tout fait, mais rien qui satisfasse réellement ma soif de connaissances et mon envie de comprendre.

L'une des raisons à ce manque d'informations est sans doute que la 3d isométrique à été supplantée dans les jeux par la “3D pure”.

Dans le cadre d'un jeu WEB, les développeurs préfèrent la 2D pure, c'est plus simple à gérer, et beaucoup plus rapide a calculer; c'est donc une technologie très rentable;

Seulement, je trouve que c'est moche, et que la 3D isométrique est le meilleur compromis.

Qu'est ce que la 3D isométrique

La 3D isométrique est un moyen de rendre l'effet de perspective et de profondeur en utilisant des éléments en 2D. Appliquée à une carte composée de cases, cette technique donne un rendu saisissant mais pour bien la comprendre, il est nécessaire de réfléchir à ses implications mathématiques. L'objet de ce tutoriel est d'expliquer pas à pas la théorie de la 3D isométrique lorsqu'elle est utilisée sur un site WEB. Les paragraphes qui suivent contiennent de nombreuses références mathématiques mais peu de code.

Les bases

Les jeux de "cartes"

Pour faire un bon jeu d'aventure ou un jeu de rôle, rien ne vaut un monde vaste, et qui dit monde, dit carte(s); le plus simple pour faire une carte, c'est de prendre une feuille de papier quadrillé, et de dessiner dessus…

En informatique, c'est pareil…

C'est donc un univers 2D qui est représenté, vu de haut; c'est facile a faire avec un ordinateur, une case de la carte s'affiche sans modification sur l'écran (tout au plus faut il gérer les très grandes cartes qui dépassent de l'écran. Mais il faut avoué que cela manque d'entrain, et aussi belles soient les cases, cela reste une carte et non un monde…

Tiles et changement de vue...

Oui, je vais parler de “tiles” et non de “tuiles” car je n'aime pas la francisation dans n'importe quel sens… donc je parle de tile et de tileset :-)

Avant tout, je rappelle la “procédure” pour créer des tiles isométriques.

Par le passé, les logiciels de dessin utilisaient comme référence le pixel d'écran; et les graphistes devenaient souvent soit des Dieux du positionnement “au pixel près” soit adepte du Zoom; l'un des logiciels les plus connu sur Amiga était le Deluxe Paint (qui fut d'ailleurs porté sur PC) et RIEN n'a (à mes yeux) remplacé ce merveilleux logiciel pour ce type de dessins.

Pour créer une vue isométrique utilisable sur ordinateur, on applique une rotation de 45° vers la droite, puis un “écrasement” de 50% en hauteur.

Dans le temps, il fallait une sacrée dose de patience pour réaliser ces “tiles” afin qu'elles s'associent l'une à l'autre par les cotés.

Aujourd'hui, il existe de très bon logiciels qui réalise ces opérations pour vous, je citerais le World Creator de Inet2inet. Ce logiciel n'est peut-être pas le plus efficace, mais il est certainement le plus précis.

On se retrouve donc avec des images rectangulaires contenant des formes tordues, d'où la difficulté de les coller les unes aux autres. Je rappelle que si l'on considère la carte comme un plan orthonormé, l'origine est en haut à gauche.

Avec ces formes “en losange”, si on est un peu codeur, on comprend très vite que cette vue 2.5D est un peu une sorte d'enfer, car il faut avancer dans deux dimensions x/y alors que l'on dessine un ligne (ou une colonne) de notre carte.

Affichage

Pour des raisons de simplicité, je melangerais dans ce tutorial HTML, CSS et JavaScript; il est évident qu'il ne faut surtout pas faire comme cela, mais bien séparer les trois (quand c'est possible évidement)

Là, où en simple 2D, vous auriez imbriqué deux boucle for(); et vous auriez multiplier les indices de case par la taille de l'image a affiché.

Admettons que nos tiles fasse 64×64 pixels, voici comment vous auriez affiché:

for(y=0;y<maps_sizey;y++)
   for(x=0;x<map_sizex;x++)
      echo "<div id=\"case_".y."_".x."\" style=\"position: absolute; left: ".($x*64)."px; top: ".($y*64)."px;
                 background-image: url('".$impath."floor-".$im.".png');width: 64px;height: 64px;\"></div>";

En isométrique, cela ne fonctionnera pas… car il faut “imbriquer” les losanges… mais pas de panique, voici la marche a suivre:

for($y=0;$y<$maps_sizey;$y++)
   for($x=0;$x<$map_sizex;$x++)
   {
      $px = ($x-$y)*(64/2);
      $py = (($x+$y)/2)*(64/2);
 
      echo "<div id=\"sol_".$y."_".$x."\" style=\"position: absolute; left: ".$px."px; top: ".$py."px; width: 64px; height: 64px;
                  background-image: url('".$impath."floor-".$im.".png');\"></div>";
   }

Et voilaaaa… vous avez un sol en 3D isométrique.

Optimisation ?

Là, je vous vois crier au scandale. Oui, j'affiche une fois toute la map, elle va dépasser de l'écran, ça va être moche etc…

En fait non, c'est assez simple d'éviter de montrer toute la carte; j'affiche la carte dans un DIV qui est lui même dans un DIV view; je centre la vue au début:

$maps_sizey  = 10;
$maps_sizex  = 10;
 
$centerx    = ($maps_sizex/2);
$centery    = ($maps_sizey/2); 
$positionx    = (($centerx-$centery)*(64/2));
$positiony    = -((($centerx+$centery)/2)*(32/2))+(640/2);
 
echo "
<div id=\"view\" tabindex=\"0\" style=\"width:768px; eight:640px; overflow:hidden;\">
<div id=\"view\" style=\"position:absolute; top: $positiony; left:$positionx;\">";