JeuWeb - Crée ton jeu par navigateur
Application de la 3D isométrique sur des tuiles hexagonales - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Gameplay, gamedesign (https://jeuweb.org/forumdisplay.php?fid=48)
+--- Sujet : Application de la 3D isométrique sur des tuiles hexagonales (/showthread.php?tid=1205)

Pages : 1 2 3 4 5 6 7 8 9 10


RE: Application de la 3D isométrique sur des tuiles hexagonales - Harparine - 17-12-2008

Je suis content que ce tuto serve. Roworll, je me suis posé exactement la même question que toi mais faute de temps, je n'ai jamais trouvé la solution malgré quelques recherches infructueuses. Je crois qu'il faudrait que je consacre vraiment une après-midi au problème pour parvenir à le résoudre. N'hésitez pas à proposer la solution si vous l'avez car je ne pourrais pas faire évoluer ce tuto avant moment (ma vie professionnelle est particulièrement chargée).
Bonne soirée !


RE: Application de la 3D isométrique sur des tuiles hexagonales - jo_link_noir - 27-12-2008




RE: Application de la 3D isométrique sur des tuiles hexagonales - gameprog2 - 23-01-2009

Vraiment bravo !!!!!!!!
Où on voit que les maths ça peut servir à jouer hein ^^


RE: Application de la 3D isométrique sur des tuiles hexagonales - Harparine - 23-01-2009

Yes ! Ca c'est cool. Il va falloir que je teste ça un de ces jours. Si ça marche vraiment, ça ne te dérange pas que je rajoute tes formules au tuto sur le wiki ? (en précisant évidemment qui en est l'auteur Wink)


RE: Application de la 3D isométrique sur des tuiles hexagonales - Hakushi - 23-01-2009

J'avais commencé un petit moteur de rendu en Flash pour jeu de strategie en tile Hexagonal, faudrait que je fouille mon PC voir si je peux en tirer des fichiers re-utilisables.


RE: Application de la 3D isométrique sur des tuiles hexagonales - jo_link_noir - 25-01-2009

Harpine, tu peux en faire ce que tu veux Smile


RE: Application de la 3D isométrique sur des tuiles hexagonales - jo_link_noir - 07-04-2009

Bonjour,
J'ai refait le code pour qu'il puisse s'utiliser avec n'importe quel taille d'image, de colonne et de ligne.
Y ajuste n, x, y, et L qui sont à modifier (l.126) et peut-être un décalage à effectué (l.195)
Par contre y a un petit décalage quand le tableau est trop, il ne trouve pas les coordonnées exacte. J'ai juste réajusté de quelques pixels mais faudrait le faire selon les valeurs en x et y, petit calcul que j'ai pas fait.

Code PHP :
<?php 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<
head>
<
title>carte hexagone</title>
<
meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<
meta lang="fr" name="description" content="trouver les coordonnées x/y avec la sourie sur une carte isométrique hexagonale" />
</
head>
<
body>
<
div id="carte" style="z-index:1;"></div>
<
div stle="position:fixed;z-index:90;">
<
div>X/Y réel: <span id="reel">? / ?</span></div>
<
div>X/Y modifier: <span id="modifier">? / ?</span></div>
<
div>X/Y contre iso: <span id="contreiso">? / ?</span></div>
<
div>Carte: <span id="info">-</span></div>
</
div>
<
div style="position:fixed;right:0px;top:0px;z-index:100;">
<
form onsubmit="return initCarte(this)">
<
p>
<
label for="ligne">Ligne : </label><input type="numeric" name="ligne" id="ligne"/><br />
<
label for="colonne">Colonne : </label><input type="numeric" name="colonne" id="colonne"/>
</
p>
<
p><input type="submit" /></p>
</
div>

<
script type="text/javascript"><!--
function
sindeg(deg)
{
return
Math.sin(deg/180*Math.PI);
}

function
angleRad(x,y)
{
return
Math.acos(x / Math.sqrt(x*x + y*y)) - Math.PI/4;
}

function
modulo(x,y)
{
return
Math.sqrt(x*x + y*y);
}

function
y_non_iso(x,y)
{
return
Math.floor(Math.sin(angleRad(x,y))*modulo(x,y));
}

function
x_non_iso(x,y)
{
return
Math.floor(Math.cos(angleRad(x,y))*modulo(x,y));
}


n = 98;
nbLignes = 3;
nbColonnes = 4;

function
creeCarte()
{
var
carte = '';

for (var
l=0; l<nbLignes; l++) {
for (var
c=0; c<nbColonnes; c++) {
var
X = c*(sindeg(75)+sindeg(45))*n - (l+Math.ceil(c/2))*(sindeg(15) + sindeg(75))*n + (nbLignes-1)*(sindeg(15)+sindeg(75))*n;
var
Y = (l+Math.ceil(c/2))*(sindeg(75)+sindeg(15))*n/2 + c*sindeg(13.5)*n;

carte += '<img src="../images/Hexagone_iso.png" style="position:absolute;left:'+X+'px;top:'+(Y-1)+'px;"/><span style="position:absolute;left:'+(X+85)+'px;top:'+(Y+40)+'px;">'+c+" / "+l+'</span>';
}
}
document.getElementById("carte").innerHTML = carte;
}

function
initCarte(frm)
{
nbLignes = parseInt(frm.elements["ligne"].value);
nbColonnes = parseInt(frm.elements["colonne"].value);
creeCarte();
return
false;
}

creeCarte();



// Variables de la gestion de l'evenement
var Mouse = {"x":0,"y":0};

// Demande de gestion de l'evenement à NetScape
if(navigator.appName.substring(0,3) == "Net") {
document.captureEvents(Event.MOUSEMOVE);
}

// Gestion de l'evenement
var OnMouseMoveEventHandler=function() {}
var
OnMouseMove = function (e)
{
Mouse.x = (navigator.appName.substring(0,3) == "Net") ? e.pageX : event.x+document.body.scrollLeft;
Mouse.y = (navigator.appName.substring(0,3) == "Net") ? e.pageY : event.y+document.body.scrollTop;
if (
Mouse.x < 0) {Mouse.x=0;}
if (
Mouse.y < 0) {Mouse.y=0;}
OnMouseMoveEventHandler(e)
}

try {
document.attachEvent("onmousemove", OnMouseMove, true);
} catch (
ex) {
document.addEventListener("mousemove", OnMouseMove, true);
}


/*
A partirdu tuto de Harparine
http://wiki.jeuweb.org/tutoprog/3d_iso_et_tuiles_hexagonales
*/
var moveHandler = function()
{
var
c= nbColonnes-1, l = nbLignes-1;
//Fonctionne pour les hexagones avec des trait perpendiculaire à l'axe y

//n = taille d'un segment
//x = position x de la case 1/0 = 150 (n*1.5)
//le même que dans le php (148)
//y = position y de la case 0/0 = 86.5 (sin(60) * n)
//L = (largeurImage - tailleSegmentX) / 2 |OU| 2n-x = 50
//c'est valeur sont à réajuster car les images peuvent ce superposer lors de leurs positionnement
var n=98, x=150, y=86.5, L=50;
var
X,Y,Xd,Yd;

document.getElementById("reel").innerHTML = Mouse.x+" / "+Mouse.y;

//on s'immule une contre isométrie des points
//les 2 calcules trouve les coordonnées du point d'origine (Xo=346 et Yo=204)
/*graphiquement
Xo = (Xmax+Xmin)/2
Yo = (Ymax+Ymin)/2
*/
/*Par calcul avec : c = nombreColonne -1 et l = nombreLigne - 1.
Xo = ceil(
(
n * (
c * (sin(75) + sin(45))
- ceil(c/2) * (sin(15) + sin(75))
+ l * (sin(15) + sin(75))
)
+ largeurImage
) / 2
- décalageX
)
Yo = ceil(
n * (
(l + ceil(c/2)) * (sin(75) + sin(15)) / 2
+ c * sin(13.5)
+ 1
) / 2
- décalageY
)
*/

var Xo = Math.ceil((n * (c * (sindeg(75) + sindeg(45)) - Math.ceil(c/2) * (sindeg(15) + sindeg(75)) + l * (sindeg(15) + sindeg(75))) + n+2*L) / 2);
var
Yo = Math.ceil(n * ((l+Math.ceil(c/2))*(sindeg(75)+sindeg(15)) / 2 + c*sindeg(13.5) + 1) / 2);
Mouse.x += Xo;
Mouse.y = (Mouse.y + Yo)*2;
var
x_contre_iso = x_non_iso(Mouse.x, Mouse.y);
var
y_contre_iso = y_non_iso(Mouse.x, Mouse.y);

//on réajuste les points pour que la carte isométrique et son point d'origine soit positionner sur celui d'une carte non isométrique (faut imaginer la carte non iso et iso positionner l'un sur l'autre mais avec le point haut-gauche du carrer qui les contient confondu... ><)
//trouver en comparant le même point sur les 2 cartes avec le curseur
/*graphiquement /!\ prendre le resultat de la sourie suivant :
document.getElementById("modifier").innerHTML = Math.floor(sindeg(angle)*module)+" / "+Math.floor(Math.cos(angle)*module);

Par position de sourie nettement plus rapide/pratique même si il peut y avoir quelques pixel de différence. Dans ce cas il suffi de savoir dans quel axe et donc ajouter à x et y le nombre en conséquence

Mouse.y = Math.floor(Math.cos(angle)*module) - sommet_le_plus_haut (ou point extreme droite de l'axe x /!\ à l'isométrie)
Mouse.x = Math.floor(Math.cos(angle)*module) - sommet_à_droite_du_plus_haut (ou point extreme gauche de l'axe y /!\ à l'isométrie)
*/
/*Par calcul. Math.floor(sindeg(Mangle)*Mmodule) et Math.floor(Math.cos(Mangle)*Mmodule) sont par raport au nombre de ligne et de colonne. Pas le peine de faire le calcule à chaque fois
Mx = n * (sindeg(15/180*Math.PI)+sindeg(75/180*Math.PI)) * (l + 1) + Xo;
My = Yo * 2 ;
Mangle = Math.acos(Mx / Math.sqrt(Mx*Mx + My*My)) - Math.PI/4;
Mmodule = Math.sqrt(Mx*Mx + My*My) - 10;
Mouse.y = Math.floor(sindeg(angle)*module) - Math.floor(sindeg(Mangle)*Mmodule);

Mx = n * (sindeg(15/180*Math.PI) + l * (sindeg(15/180*Math.PI)+sindeg(75/180*Math.PI))) + Xo;
My = (n * sindeg(15/180*Math.PI)/2 + 1 + Yo) * 2 ;
Mangle = Math.acos(Mx / Math.sqrt(Mx*Mx + My*My)) - Math.PI/4;
Mmodule = Math.sqrt(Mx*Mx + My*My);
Mouse.x = Math.floor(Math.cos(angle)*module) - Math.floor(Math.cos(Mangle)*Mmodule);
*/
document.getElementById("modifier").innerHTML = x_contre_iso+" / "+y_contre_iso;


Mouse.y = y_contre_iso - y_non_iso(n * (sindeg(15)+sindeg(75)) * (l + 1) + Xo, Yo * 2);
Mouse.x = x_contre_iso - x_non_iso(n * (sindeg(15) + l * (sindeg(15)+sindeg(75))) + Xo, (n * sindeg(15)/2 + 1 + Yo) * 2);

//décalage
Mouse.y += 2;
Mouse.x -= 1;

document.getElementById("contreiso").innerHTML = Math.floor(Mouse.x)+" / "+Math.floor(Mouse.y);

//calcule les positions aproximatif de la case (X ; Y)
//hexagone transformer en carré de même hauteur et de largeur du point le plus à gauche au point en haut à droite
//---------------------------------------------------------
//calcule les positions réel de la case (Xd ; Yd)
//distance du point par rapport à l'haxagone
X = Math.floor(Mouse.x/x);
Xd= n - (Mouse.x - X*x);
if(
X%2 == 1)
{
Y = Math.floor((Mouse.y - y)/(y*2));
Yd= Mouse.y - Y*(y*2) - (y*2);
}
else
{
Y = Math.floor(Mouse.y/(y*2));
Yd= Mouse.y - Y*(y*2) - y;
}

//le point est situer dans la partie du carré qui superpose l'hexagone (à ça gauche)
//et le point est à l'exterieur du cercle inscrit
//et on déplace le point sur l'axe x et on vérifie ça longueur (52/86.5 est la pente de x par y)
if(Xd >= L
&& y < Math.sqrt(Xd*Xd + Yd*Yd)
&&
n <= Xd + Math.abs(Yd)*L/y)
{
if(
X%2 == 1 && Yd>0) ++Y;
if(
X%2 == 0 && Yd<0) --Y;
--
X;
}

//curseur à l'exterieur de la carte
document.getElementById("info").innerHTML = X+" / "+Y+ ": "+(Y<3 && X<4 && Y>=0 && X>=0 ? "OUI" : "NON");
};

document.onmousemove = moveHandler;
--></
script>
</
body>
</
html>



RE: Application de la 3D isométrique sur des tuiles hexagonales - keke - 18-05-2009

(08-02-2008, 06:03 PM)barst a écrit : Voilà un bout de code que j'avais fait il y a quelque temp pour prendre une image 2D et générer 4 images en 3D isométrique (1 image par orientation : nord, est, sud, ouest)

Dans l'exemple :
$filename = nom de l'image 2D (chemin complet avec extension)
$name = nom de l'image 3D (juste le nom sans extension)
Code PHP :
<?php 
$sizes
= getimagesize($filename);
$h = intval(floor(sqrt((pow($sizes[0],2)+pow($sizes[1],2)))/2));
$tmp = imagecreate($sizes[0],$h );
$transparent = imagecolorallocatealpha ($tmp, 255, 255, 255, 127);
$aux = imagerotate(imagecreatefrompng($filename),-45,$transparent);
imagecopyresampled( $tmp, $aux, 0, 0, 0, 0, $sizes[0], $h, imagesx($aux), imagesy($aux) );
$aux = $tmp;
imagecolortransparent($aux,imagecolorat($aux,1,1));
imagepng($aux,$name.'_north.png');
$aux = imagerotate(imagecreatefrompng($filename),45,$transparent);
imagecopyresampled( $tmp, $aux, 0, 0, 0, 0, $sizes[0], $h, imagesx($aux), imagesy($aux) );
$aux = $tmp;
imagecolortransparent($aux,imagecolorat($aux,1,1));
imagepng($aux,$name.'_east.png');
$aux = imagerotate(imagecreatefrompng($filename),135,$transparent);
imagecopyresampled( $tmp, $aux, 0, 0, 0, 0, $sizes[0], $h, imagesx($aux), imagesy($aux) );
$aux = $tmp;
imagecolortransparent($aux,imagecolorat($aux,1,1));
imagepng($aux,$name.'_south.png');
$aux = imagerotate(imagecreatefrompng($filename),225,$transparent);
imagecopyresampled( $tmp, $aux, 0, 0, 0, 0, $sizes[0], $h, imagesx($aux), imagesy($aux) );
$aux = $tmp;
imagecolortransparent($aux,imagecolorat($aux,1,1));
imagepng($aux,$name.'_west.png');

Coucou Barst ^^,

Ce We, j'ai essayé ton code. Comme le résultat ne me satisfaisait pas, j'ai essayé de l'améliorer. Puis n'ayant plus beaucoup de temps devant moi, je l'ai envoyé sur mon serveur ... et là, on m'apprend que la fonction GD imagerotate n'est pas gérée chez moi (pourtant je suis en version PHP 5.n ^^) !

Bref, afin que ceux qui ont essayé ton programme ne soient pas déçus, je les encourage à tester ton programme sur leur serveur AVANT de l'adapter en locale ^^.

Sinon, C'est vrai que ta fonction peut-être vraiment utile si l'on souhaite migrer de 2D plat 2D iso ^^.

kéké qui souhaite carrément passer à la 3D iso !


RE: Application de la 3D isométrique sur des tuiles hexagonales - Pabsy - 08-01-2010

Bonjour, je vois que j'arrive un peu après la bataille, mais développant moi même un moteur graphique pour 3D isométrique à base hexagonale, je remercie Harpatine pour tous ses calculs.

Malheureusement, j'ai cru comprendre qu'il avait fait tout un tutoriel là dessus mais le sujet ayant été déplacé, les liens vers la page sont morts, ainsi que certaines images que ce sujet-ci contenait (notamment le dessin des tuiles de base et leurs dimensions).

Ce tutoriel existe toujours quelque part sur le serveur ou devrais-je me casser la tête pour l'adapter à mes proportions d'hexagones ?

Merci


RE: Application de la 3D isométrique sur des tuiles hexagonales - Anthor - 08-01-2010

Hélas non pas de sauvegarde du Wiki. Peut-être voir avec Harparine.