Voilà, c'est ce que je voulais dire avec les "diagonales".
Cependant, le module que je fais sera capable d'interpreter une même carte (liste de x,y) de plusieurs manières (pour l'instant hexa2D, ensuite hexa2Diso, puis ensuite je rajouterai carré ect...)
Avancement : Zoom réglé (les textures ne sont plus des background mais des images...) Cependant je suis en train d'empiler des div pour chaque cases... Est-ce vraiment bon ?
Vous pouvez donc à présent rajouter un argument "zoom" sur la barre d'adresse (avec zoom=50 la tuile de base)
[cache]
[/cache]Cependant, le module que je fais sera capable d'interpreter une même carte (liste de x,y) de plusieurs manières (pour l'instant hexa2D, ensuite hexa2Diso, puis ensuite je rajouterai carré ect...)
Avancement : Zoom réglé (les textures ne sont plus des background mais des images...) Cependant je suis en train d'empiler des div pour chaque cases... Est-ce vraiment bon ?
Vous pouvez donc à présent rajouter un argument "zoom" sur la barre d'adresse (avec zoom=50 la tuile de base)
[cache]
Code PHP :
<?php
class carte
{
//----- Variables
// Infos carte
var $nom;
var $tailleX;
var $tailleY;
// Contenu carte
var $cases;
//----- Constantes
//----- Methodes
function __construct() {}
// Charge une carte deja enregistree
function loadCarte($id)
{
$donnees = ''; // On recupere les donnees
$this->nom = $donnees['nom'];
$this->tailleX = $donnees['tailleX'];
$this->tailleY = $donnees['tailleY'];
$this->cases = $donnees['cases'];
}
// Creer une carte vierge
function nouvelleCarte()
{
$this->nom = 'Nouvelle carte';
$this->tailleX = 1;
$this->tailleY = 1;
$this->cases = '';
}
// Enregistre la carte dans la BDD
function saveCarte($id)
{}
// Genere un hexagone parfait via GD
private function _Hexagone($n)
{
$points = array( $n/2 , 0,
3*$n/2 , 0,
2*$n , $n*0.86,
3*$n/2 , 2*$n*0.86-1,
$n/2 , 2*$n*0.86-1,
0 , $n*0.86);
header ("Content-type: image/png");
$tailleX = 2*$n;
$tailleY = 0.86*2*$n;
$image = imagecreate($tailleX,$tailleY);
$couleur = imagecolorallocate($image, 255, 255, 255);
imagecolortransparent($image, $couleur);
$noir = imagecolorallocate($image, 0, 0, 0);
ImagePolygon ($image, $points, 6, $noir);
return imagepng($image);
}
// Affiche la carte
function afficherCarte($x_centre,$y_centre,$x_taille=0,$y_taille=0,$n=50)
{
// Taille d'affichage par défaut
if($x_taille == 0) $x_taille=$this->tailleX;
if($y_taille == 0) $y_taille=$this->tailleY;
// Définition des x;y de début et fin d'affichage
$x_debut = $x_centre - floor($x_taille/2);
$y_debut = $y_centre - floor($y_taille/2);
$x_fin = $x_centre + floor(($x_taille+1)/2);
$y_fin = $y_centre + floor(($y_taille+1)/2);
// Vérification des débordements et recentrage
if($x_debut < 0) // Si on déborde sur la gauche
{
$x_fin -= $x_debut;
$x_debut = 0;
}
if($x_fin >= $this->tailleX) // Si on déborde sur la droite
{
$x_debut -= ($x_fin - $this->tailleX);
$x_fin = $this->tailleX;
}
if($y_debut < 0) // Si on déborde sur le haut
{
$y_fin -= $y_debut;
$y_debut = 0;
}
if($y_fin >= $this->tailleY) // Si on déborde sur le bas
{
$y_debut -= ($y_fin - $this->tailleY);
$y_fin = $this->tailleY;
}
// Génération du code HTML
$aff = '<div style="position: absolute;">';
for($y=$y_debut;$y<$y_fin;$y++) // Chaque ligne
{
for($x=$x_debut;$x<$x_fin;$x++) // Chaque colonne
{
$aff .= $this->creerCase($x,$y,$n,$x_debut,$y_debut);
}
}
$aff .= '</div>';
return $aff;
}
// Creer la case (x,y) avec un hexa de coté n et en prenant en compte le decalage
private function creerCase($x,$y,$n,$x_decalage=0,$y_decalage=0)
{
// Calcul de la position de la case
$posX = ($x-$x_decalage)*1.5*$n;
$posY = ($y-$y_decalage)*0.86*2*$n + ($x%2)*0.86*$n -1*($y-$y_decalage);
// Calcul des dimensions de la case
$l = 2*$n;
$h = 0.86*2*$n;
// Récupération des informations utiles
$adj = $this->_getAdjacentes($x,$y);
$hexa = $this->_getHexa($x,$y);
$texture = $this->_getTexture($x,$y);
// Sous couche (Texture)
$aff = '<div style="width:'. $l .'px; height:' . $h . 'px;'; // < Taille de la case
$aff .= 'position:absolute; top:'.$posY.'px;left:'.$posX.'px;'; // Position de la case
$aff .= ''; // Autre style
$aff .= 'background-color: none; ">'; // Fond de la case >
$aff .= '<img src="textures/'.$texture.'.png" alt="texture" width="'. $l .'" height="' . $h . '"/>'; // Contenu
$aff .= '</div>'; // <>
// Infos
$aff .= '<div style="width:'. $l .'px; height:' . $h . 'px;'; // < Taille de la case
$aff .= 'position:absolute; top:'.$posY.'px;left:'.$posX.'px;'; // Position de la case
$aff .= 'text-align: center;'; // Autre style
$aff .= 'background-color: none;">'; // Fond de la case >
$aff .= '(' . $x . ':' . $y . ')'; // Contenu
$aff .= '</div>'; // <>
// Sur couche (Hexa)
$aff .= '<map name="case_hexa_'.$x.'_'.$y.'">
<area shape="poly" coords="'. ($n/2) .','. 0 .','. (3*$n/2) .','. 0 .','. (2*$n) .','. ($n*0.86) .','. (3*$n/2) .','. (2*$n*0.86-1) .','. ($n/2) .','. (2*$n*0.86-1) .','. 0 .','. ($n*0.86) .'" href="#'.$x.':'.$y.'">
</map>';
$aff .= '<div style="width:'. $l .'px; height:' . $h . 'px;'; // < Taille de la case
$aff .= 'position:absolute; top:'.$posY.'px;left:'.$posX.'px;'; // Position de la case
$aff .= ''; // Autre style
$aff .= 'background-color: none; ">'; // Fond de la case >
if(!is_file('hexas/'.$hexa.'.png')) $hexa = 'hexa-0';
$aff .= '<img usemap="#case_hexa_'.$x.'_'.$y.'" src="hexas/'.$hexa.'.png" alt="hexa" width="'. $l .'" height="' . $h . '"/>'; // Contenu
$aff .= '</div>'; // <>
return $aff;
}
// Récupère les infos des cases adjacentes à la case (x,y) et retourne les infos completes
private function _getAdjacentes($x,$y)
{
$p = $x%2; // Parité de X
// Coordonnées des cases adjacentes
$adj = array( 'n' => array( 'x' => $x , 'y' => $y-1 ),
'ne' => array( 'x' => $x+1 , 'y' => $y-1+$p ),
'se' => array( 'x' => $x+1 , 'y' => $y+$p ),
's' => array( 'x' => $x , 'y' => $y+1 ),
'so' => array( 'x' => $x-1 , 'y' => $y+$p ),
'no' => array( 'x' => $x-1 , 'y' => $y-1+$p ));
// Infos des cases adjacentes
$adj2 = array();
foreach($adj as $k => $v) // Pour chaque case adjacente
{
if(isset($this->cases[$v['x']][$v['y']]))
$adj2[$k] = $this->cases[$v['x']][$v['y']];
else // Si la case n'existe pas on la considère de niveau 0 par défaut (bords de carte)
$adj2[$k] = array('altitude' => 0, 'type' => 'defaut', 'texture' => 'defaut');
}
return $adj2;
}
// Retourne le nombre de cases adjacentes à (x,y) d'altitude z
private function _nbrAdjAlt($x,$y,$z)
{
$adj = $this->_getAdjacentes($x,$y);
$nbr = 0;
foreach($adj as $k => $v)
{
if($v['altitude']==$z)
$nbr += 1;
}
return $nbr;
}
// Retourne l'hexa (structure) a afficher
private function _getHexa($x,$y)
{
$type = $this->cases[$x][$y]['type'];
$alt = $this->cases[$x][$y]['altitude'];
if($alt == 1)
{
return 'hexa-5';
}
if($type == 'defaut')
{
$nbradj = $this->_nbrAdjAlt($x,$y,1);
$adj = $this->_getAdjacentes($x,$y);
$return = 'hexa-'.$nbradj;
foreach($adj as $k => $v)
{
if($v['altitude']==1) $return .= '-'.$k;
}
return $return;
}
}
// Retourne la texture a afficher
private function _getTexture($x,$y)
{
$texture = $this->cases[$x][$y]['texture'];
if($texture == 'herbe') return 'herbe';
elseif($texture == 'eau') return 'eau';
elseif($texture == 'defaut')
{
return 'herbe';
}
}
}
Je suis sûr qu'il y a moyen de se passer de la methode _nbrAdjAlt mais je ne sais pas comment le faire efficacement :/