Darkoneko's Weblog

Yesterday, today, and no future / time waits for no one

Archive for juin 2013

[html5] carte 3 – hexagones et repère carthésien

Posted by DarkoNeko sur dimanche 30 juin 2013

Ce billet fait parti de la série « bidouillons avec HTML5« .

Mon précédent article a vu la création d’une carte à cases hexagonales. Aujourd’hui vous allons voir, en pratique, comment ajouter quelquechose dans cette carte.

Système de coordonnées ?

En programmation, les données d’une carte sont typiquement stockées dans un tableau à deux dimensions, chaque case du tableau correspondant à une case de la carte. Ça fonctionne très bien avec des cases carrées, mais comment faire avec une carte hexagonale ? (mes coupains twittos se souviendrons de mon raclage de cerveau sur le sujet)

À ma grande surprise, cela reste similaire. C’est toujours un système de coordonnées cartésiennes, sauf qu’il n’est pas orthonormé : au lieu d’avoir un axe horizontal, l’axe des X est parallèle avec les rangées d’hexagones. Ce qui nous donne :

hexagon-mapx

hexagon-map5
Pour les curieux, le code utilisé pour générer l’image des coordonnées est disponible ici (trop long pour être sur la page), et une animation de l’algo est visible là.

Position d’une case

Nous disposons maintenant un système de coordonnées pour les cases. Voyons maintenant comment faire une translation de ce système de coordonnées vers celui du canvas.

  • La position d’une case est ici définie par les coordonnées  du centre de celle ci.
  • Le système de coordonnées cartésiennes utilisé pour la carte sera ci dessous  appelé « plan hexagonal ».
  • Le système de coordonnées orthonormé utilisé par le canvas sera ci dessous appelé le « plan canvas ». Le point d’origine du canvas est en haut à gauche, ce qui fait que l’axe des Y est inversé.
  • « A » désigne ici la longueur d’un côté d’un hexagone.

hexagon-translation-canvas2         hexagon-angles

Écart vertical

Les axes Y du plan hexagonal (en vert) et du  plan canvas sont parallèles, donc rien de sorcier.
Les coordonnées « plan hexagonal » [1;0] et [0;0] sont séparées par une distance canvas de [ 2 * A * cos(30°) , 0].

Écart horizontal

Là par contre, ça coince un peu. L’axe X du canvas est horizontal, alors que celui du plan hexagonal (en rouge) non.
Quelle distance sépare les coordonnées « plan hexagonal » [0;0] et [0;1], en équivalent canvas ?

  • y : A * cos(30°)
  • x : A + A * sin(30°)

Pratiquons

Code

//ici le code traçant les hexagones et les lignes de repère *snip*
(...)
//point d'origine du plan canvas, defini manuellement
var origin_y = 5 * cos_unit; // 3eme bloc en partant du haut (donc 2.5 block de haut pour être au milieu)
var origin_x = sin_unit + unit/2; //centre du 1er bloc en partant de la gauche

pinceau.beginPath();
pinceau.font = '12pt Calibri';
pinceau.textAlign = 'center';
pinceau.fillStyle = 'green';

var coord = coordinates_hexa_to_canvas(0, 0 )
pinceau.fillText("0+0", coord.x, coord.y); //du texte, mais ça pourrait être une image ou autre.

coord = coordinates_hexa_to_canvas(1, 2 )
pinceau.fillText("y1;x2", coord.x, coord.y);

coord = coordinates_hexa_to_canvas(3, 2 )
pinceau.fillText("y3;x2", coord.x, coord.y);

coord = coordinates_hexa_to_canvas(4, 4)
pinceau.fillText("y4;x4", coord.x, coord.y);

function coordinates_hexa_to_canvas(wanted_y, wanted_x ) {
   //variables "globales" utilisées : cos_unit, sin_unit, unit, origin_y, origin_x
  var coordinates = [];
   //vertical part. canvas system has Y inverted, so goes down as hexa coordinates go up.
   coordinates.y = origin_y - (wanted_y * (2 * cos_unit));
   //"horizontal" part
   coordinates.y += (wanted_x * cos_unit);
   coordinates.x = origin_x + (wanted_x * (unit + sin_unit));

   return coordinates;
}

(code complet ici)

Affichage

hexagon-map-translation

Et voilou !

Posted in bidouillons avec html5 | Tagué: , , , , | Commentaires fermés sur [html5] carte 3 – hexagones et repère carthésien

[html5] carte 2 – carte hexagonale

Posted by DarkoNeko sur samedi 29 juin 2013

Ce billet fait parti de la série « bidouillons avec HTML5« .

Suite à mon précédent article, je passe maintenant aux cases hexagonales.
La base HTML reste la même :

<!DOCTYPE html5>
<html>
<body>
<canvas id ="canvas1" width="400" height="300" style="border:5px solid black;">
</canvas>
</body>
</html>

Dessine moi un hexagone

Mathématiquement

hexagoneBon pour commencer, ça se dessine comment exactement, un hexagone ?
N’oubliez pas que sur un canvas, l’origine [0;0] est en haut à gauche. L’axe vertical est inversé, donc « y » est à son minimum au point d’origine.

Trait par trait (d’une longueur A), d’en haut à gauche et dans le sens des aiguilles d’une montre, ça donne ça :

  • Position de départ : [x, y]
  • Trait horizontal du haut : [+A, +0]
  • diagonale côté haut droit : [+A*sin(30°), +A*cos(30°)]
  • diagonale côté bas droit : [-A*sin(30°), +A*cos(30°)]
  • Trait horizontal du bas : [-A, -0]
  • diagonale côté bas gauche : [-A*sin(30°), -A*cos(30°)]
  • diagonale côté haut gauche : [+A*sin(30°), -A*cos(30°)]

Et niveau code ?

Notez que contrairement à la liste (ou la position est indiquée incrémentalement, par rapport à celle de la fin du trait précédent), le code ci dessous garde tout du long la position de départ comme référentiel :

<script language="javascript" type="text/javascript">
var c1=document.getElementById("canvas1");
var pinceau =c1.getContext("2d");

initial_h = 100; //position verticale de base
initial_w = 100; //position horizontale de base

unit = 50; //longueur d'un coté de l'hexagone
//pour ne pas avoir à le recalculer à chaque fois
sin_unit = unit * Math.sin(30*Math.PI/180); 
cos_unit = unit * Math.cos(30*Math.PI/180);

pinceau.moveTo(initial_w                  , initial_h); //point de départ
pinceau.lineTo(initial_w + unit           , initial_h);
pinceau.lineTo(initial_w + unit + sin_unit, initial_h + cos_unit);
pinceau.lineTo(initial_w + unit           , initial_h + 2 * cos_unit);
pinceau.lineTo(initial_w                  , initial_h + 2 * cos_unit);
pinceau.lineTo(initial_w - sin_unit       , initial_h + cos_unit);
pinceau.lineTo(initial_w                  , initial_h); //retour au point de départ
pinceau.stroke();
</script>

canvas2-1

Comme sur des roulettes ! Passons au remplissage

Tracer la carte

Tracer chaque hexagone de la carte étant fastidieux et inefficace, j’ai décidé de tracer les diagonales par colonnes, puis d’ajouter les traits horizontaux manquants.

Code

<script language="javascript" type="text/javascript">
var c1=document.getElementById("canvas1");
var pinceau=c1.getContext("2d");

var unit = 40;
var sin_unit = unit * Math.sin(30*Math.PI/180);
var cos_unit = unit * Math.cos(30*Math.PI/180);

//trace the diagonals
var count = 0;

for(var w = 0 ; w < c1.width ; w += unit + sin_unit) {
   if( count % 2 == 0) {
      pinceau.moveTo(w , 0); //point de depart
      for(var h = 0 ; h < c1.height ; h += 2 * cos_unit) {
         pinceau.lineTo(w + sin_unit , h + cos_unit); /* \ */
         pinceau.lineTo(w, h + 2 * cos_unit);        /* / */
      }
   } else {
      pinceau.moveTo(w + sin_unit, 0); //point de depart
      for(var h = 0 ; h < c1.height ; h += 2 * cos_unit) {
         pinceau.lineTo(w, h + cos_unit);               /* / */
         pinceau.lineTo(w + sin_unit, h + 2 * cos_unit); /* \ */
      }
   }
   count++;
}

//trace the lines
count = 0;

for(var w = 0 ; w < c1.width ; w += unit + sin_unit) {
   if( count % 2 == 0) {
      for(var h = 0 ; h < c1.height ; h += 2 * cos_unit) {
         pinceau.moveTo(w + sin_unit, h + cos_unit);
         pinceau.lineTo(w + sin_unit + unit , h + cos_unit);
      }
   } else {
      for(var h = cos_unit ; h < c1.height ; h += 2 * cos_unit) {
         pinceau.moveTo(w + sin_unit, h + cos_unit); 
         pinceau.lineTo(w + sin_unit + unit, h + cos_unit);
      }
   }
   count++;
}
pinceau.stroke();
</script>

Visuellement

Étape 1 :
canvas2-3b
Étape 2 :
canvas2-4

Posted in bidouillons avec html5 | Tagué: , , , | Commentaires fermés sur [html5] carte 2 – carte hexagonale

[html5] carte 1 – base et quadrillage

Posted by DarkoNeko sur jeudi 27 juin 2013

Ce billet débute la série « bidouillons avec HTML5« .

Mais le HTML5 ça ajoute quoi par rapport à HTML en fait ? *ouvre un tutorial*
Ok, donc ya une balise <canvas> et on peut gribouiller des trucs dedans. Commençons par ça.

Ça tombe bien, je m’amuse ces temps ci à réfléchir aux algos utilisés dans les jeux au tour par tour, notamment ceux utilisant une carte avec des cases hexagonales (tels que Battle Isle et Wesnoth). Traçons une carte ! Je garde les hexagones pour plus tard, voyons déjà si j’arrive à faire des cases carrées.

Tout d’abord, squelette de page avec un canvas de 400 de large pour 300 de haut.

<!DOCTYPE html5>
 <html>
 <body>
     <canvas id="canvas1" width="400" height="300" style="border:5px solid black;"></canvas>
 </body>
 </html>

canvas1

Jusque là, rien de sorcier. Il manque un certain nombre de trucs pour que ça soit propre (comme avoir le CSS et le JS dans une page à part, indiquer le le charset, etc.), mais ça suffira pour l’exercice.

Voyons le gribouillage maintenant.
« HTML5 » gère le dessin sur canvas via des méthodes JavaScript spécifiques. en ce qui me concerne :

  • x.moveTo(x, y) permet de positionner le curseur/pinceau
  • x.lineTo(x,y) permet de tracer un trait entre la position actuelle et celle spécifiée en paramètre.
  • x.stroke() finalise le ou les tracés.

Sachant que le point d’origine [0;0] du canvas se trouve en haut à gauche, tentons une première ligne 50 pixels plus bas.

<script language="javascript" type="text/javascript">
var c1=document.getElementById("canvas1");
var pinceau=c1.getContext("2d");

pinceau.moveTo(0, 50); 
pinceau.lineTo(c1.width, 50); 
pinceau.stroke();
</script>

canvas1-2

Magnifique !
Avec un soupçon d’algorithmie, traçons maintenant le reste de la grille.

<script language="javascript" type="text/javascript">
var c1=document.getElementById("canvas1");
var pinceau=c1.getContext("2d");

var ecart = 50; //largeur d'un côté des cases
//lignes
for(var h = ecart ; h < c1.height ; h += ecart) {
   pinceau.moveTo(0, h); //déplacer le pinceau à (x,y) sans tracer
   pinceau.lineTo(c1.width, h); //tracer jusqu'à (x,y)
}
//colonnes
for(var w = ecart ; w < c1.width ; w += ecart) {
   pinceau.moveTo(w, 0);
   pinceau.lineTo(w, c1.height);
}
pinceau.stroke();
</script>

canvas1-3

Et voilou ! Bien sur, le but à terme sera de remplir ces cases avec des textures de terrain et/ou de combattants ! Mais ça sera pour plus tard.
Prochain billet, encore une carte vide, mais cette fois avec des cases hexagonales. Ça s’annonce plus tendu :)

Posted in bidouillons avec html5 | Tagué: , , , | 1 Comment »

le HTML5, c’est fun

Posted by DarkoNeko sur mercredi 26 juin 2013

IdeaAloha !

Je me suis mis récemment au HTML5 (utile dans ma branche de métier), et me suis dit que ça serait cool de partager ça ici.
Et puis, ça fera toujours un peu d’activité sur ce blog.

Ces prochains jours/semaines, je vais donc poster des bout de code/algo et en expliquer les grandes lignes. Pas vraiment un tutoriel, mais si vous maîtrisez un peu HTML et JavaScript, vous devriez comprendre sans trop de souci :)

À bientôt donc.

Posted in bidouillons avec html5 | Tagué: , , , | 1 Comment »

Station spatiale internationale

Posted by DarkoNeko sur mercredi 12 juin 2013

Quelques petits trucs concernant la Station spatiale internationale (ISS)  que j’ai découvert récemment :

Position de l’ISS

Sur ce site, mis à jour en temps réel à partir de données de la NASA.

ISS1a
ISS1b

Caméra

Avec vue du sol depuis  l’ISS par défaut ; le canal est aussi utilisée pour des « animations » réalisées par l’équipage et montrer leur vie de tous les jours

ISS2

Voili voilou.

Posted in divers | Tagué: , , | Commentaires fermés sur Station spatiale internationale