Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Les bases de l'affichage en HTML5 avec Tomahawk

Par thoutmosis (Legrand), le 02 août 2014

Voici le premier tutoriel concernant les bases de l'affichage en HTML5 avec le moteur “Tomahawk”. Tomahawk est un moteur d'affichage en 2d basé sur la norme HTML5 et plus spécifiquement sur la nouvelle balise canvas.

Il vous offre une couche d'abstraction simple, calquée sur le modèle de l'API flash Actionscript 3 d'Adobe, tout comme EaselJs. Ainsi si vous êtes déjà flasheurs, vous évoluerez un peu “comme à la maison”, pour les autres aucun problème, le moteur est simple d'utilisation et s'appréhende très facilement.

Vous pourrez ainsi développer rapidement des applications de tout types par exemple:

  • Des jeux ( Qui va nous réaliser le prochain Zelda ? )
  • Des RIA ( Les camemberts de statistiques les plus fous sont à votre portée )
  • Des applications d'éditions de texte ( et si on se recodait Open Office ? )
  • Des applications de dessin ( un petit paint en HTML5 ça vous tente ? ;) )

… Et bien d'autres encore !

A l'origine, le projet était surtout pédagogique, ce qui a donné naissance à une formation que je dispense à l'heure actuelle dans les centres mediabox. Au fur et à mesure, le projet a évolué, la version pédagogique s'est changée en version de production, des ajouts ont été faits, des tests ont été écrits, des applications, des jeux sont sortis et des commit ( beauuucoup de commit ) ont contribué à rendre le moteur de plus en plus robuste.

Aujourd'hui vous pouvez vous rendre sur le github du projet à l'adresse suivante https://github.com/thetinyspark/tomahawk et jeter un oeil aux exemples stockés dans le dossier éponyme. Une fois que vous avez téléchargé le zip, vous pouvez l'extraire dans un nouveau dossier et nous allons pouvoir démarrer notre premier projet !

Prérequis

Pour pouvoir suivre ce tutoriel vous devez déjà être à l'aise avec le langage Javascript, savoir créer des objets et les manipuler.

Préparation du projet

Le projet Tomahawk s'est construit autour d'une règle simple: Aucune dépendance à une librairie tierce requise, çàd que vous pouvez l'utiliser sans avoir besoin d'installer quoique ce soit d'autre. Cela implique également que le moteur est construit de sorte à ne pas empiéter sur l'espace réservé aux autres librairies. Pas de dépendance, pas de conflit, elle est pas belle la vie ?

Une fois le dossier dézippé vous devriez avoir une arborescence qui ressemble à ceci: (NB: l'arborescence peut légèrement changer entre les versions)

Comme vous pouvez le constater, il y a pas mal de choses laissez-moi vous guider.

  • Dans le dossier “doc” vous trouverez la documentation, au format jsdoc, de la librairie complète.
  • Dans le dossier “examples” vous trouverez quelques exemples d'utilisation de la librairie.
  • Dans le dossier “test” vous trouverez une suite ( non finie ) de tests unitaires, aucune librairie requise.
  • Dans le dossier “tomahawk” vous trouverez les sources qui m'ont servi à créer le projet, une classe par fichier.
  • Le fichier “tomahawk_engine.js” est le fichier qui regroupe l'ensemble des classes du projet en un seul fichier.
  • Le fichier “tomahawk_engine_minified.js” est la version compressée de “tomahawk_engine.js”.

Les autres fichiers peuvent être ignorés, ils ne sont pas importants. Ce qui va nous intéresser, vous vous en doutez, ce sont les fichiers “tomahawk_engine.js” et “tomahawk_engine_minified.js” qu'il va nous falloir inclure dans chacun de nos projets Tomahawk.

Avant de démarrer notre projet, nous allons commencer par introduire une notion essentielle: La DisplayList.

La notion de DisplayList

Tomahawk est un moteur 2d qui utilise une organisation arborescente de l'affichage, calquée sur celle de Flash, en gros il s'agit d'une liste d'affichage, ou DisplayList en anglais.

Commençons par introduire la notion de DisplayList, qu'est-ce qu'une DisplayList et à quoi cela sert-il ? La DisplayList ( traduire liste d'affichage ) est, comme son nom l'indique, une structure de données contenant l'ensemble des informations à afficher. Pour les développeurs actionscript cette notion est évidente car intrinsèque au langage, pour les développeurs web cela se rapproche beaucoup du DOM.

Il s'agit d'une structure arborescente possédant de par ce fait une racine et un nombre non fini de feuilles ou ramifications. Si on prend l'exemple du DOM, le code source suivant est un bel exemple de structure arborescente:

<div>
	<p>enfant numero 1</p>
	<p>enfant numero 2</p>
</div>

Ici la balise <div> est le parent des balises <p> contenues en son sein, dans un vocabulaire algorithmique, et plus particulièrement dans le cas des structures arborescentes on parle de noeuds ou de parents et de feuilles ou d'enfants

L'exemple plus haut est assez simple, mais une structure arborescente, de par sa nature, n'est jamais fini, comprendre par là que l'on peut toujours ajouter des enfants à parent.

Voici un schéma d'une autre structure, celle-ci part d'un noeud racine pour ensuite déployer ses enfants qui eux-même auront des enfants etc etc …

Pour en revenir à la DisplayList de Tomahawk, sa structure est similaire, çàd que nous partirons d'un objet d'affichage de départ pour ensuite progresser récursivement afin de parcourir chaque enfant de l'arbre. Chaque noeud au sein de la DisplayList de Tomahawk correspond à un objet de type DisplayObject ( ou un objet qui héritera de la classe DisplayObject ), je vous laisse jeter un oeil à la documentation de Tomahawk afin d'en savoir plus.

Afficher un Bitmap

Pour commencer, nous allons ouvrir le fichier “BitmapExample.html” qui se trouve dans le dossier “examples” et qui ressemble à ceci:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
	<title></title>
	<script type="text/javascript" src="tomahawk_engine.js"></script>
	<script type="text/javascript" src="BitmapExample.js"></script>
	<link rel="stylesheet" type="text/css" href="assets/style.css"/>
</head>
<body>
	<canvas id="tomahawk" width="800" height="600"></canvas>
	<img src="assets/perso1.png" id="perso" style="display: none;" />
</body>
</html>

Analysons ce fichier voulez-vous ? Il comporte quelques éléments importants notamment:

  • L'inclusion de la librairie tomahawk, maintenant nous pouvons utiliser tout le moteur sans restriction.
  • L'inclusion d'un fichier “BitmapExample.js” qui contient le code de notre exemple.
  • Une balise canvas qui fait 800px de largeur sur 600px de hauteur.
  • L'inclusion d'un fichier image dont l'id est “perso”.

Jetons un oeil du côté du fichier “BitmapExample.js” maintenant:

/**
 * ...
 * @author Thot
 */
 
function Main(){}
 
Main.prototype.init = function()
{
        //On récupère l'image du DOM, "perso", et on stocke une référence à cette image dans la variable textureData
	var textureData = document.getElementById("perso"); // gets a DOM image
 
        // On va chercher l'unique instance de Stage à l'aide de la méthode statique "getInstance" définie sur la classe
        // Stage. Le design pattern implémenté n'est pas un singleton mais un multiton.
	var stage = tomahawk_ns.Stage.getInstance(); // retrieve the stage instance
 
        // On retrouve notre object canvas
	var canvas = document.getElementById("tomahawk"); // gets the canvas element
 
	// creates a new texture
        // on crée un nouvel object Texture avec les dimensions de l'image
	var texture = new tomahawk_ns.Texture(textureData,[0,0,textureData.naturalWidth,textureData.naturalHeight],"mytexture");
 
	// creates a new bitmap instance
        // on crée un nouvel objet bitmap qui va dessiner notre texture à chaque frame
	var bmp = new tomahawk_ns.Bitmap(texture);
 
        // on modifie les propriétés de notre bitmap
	bmp.x = bmp.y = 50; // sets the bitmap coordinates
	bmp.pivotX = bmp.width >> 1;
	bmp.pivotY = bmp.height >> 1;
	bmp.scaleX = 2;
	bmp.scaleY = 2;
 
        // on initialise l'objet stage en lui passant en paramètre la référence à notre canvas
	stage.init(canvas); // initialize the stage
 
        // on ajoute au stage un enfant de type bitmap, celui que nous avons crée juste avant
	stage.addChild( bmp ); // add a child to the stage
};
 
 
window.onload = function()
{
/*
Ensuite nous démarrons la plateforme en utilisant le code suivant: "**Tomahawk.run()**;". L'appel à cette méthode statique de la classe Tomahawk, permet à la plateforme de résoudre les problématiques d'héritage inter-classes qui ont été enregistrés au sein de Tomahawk ( ce sera l'objet d'un prochain tutoriel ).
*/
	Tomahawk.run(); // runs the engine
 
/*
Au sein de notre fichier, une classe nommée "Main" est définie, on crée donc une nouvelle instance de Main et on appelle la méthode "init" de l'instance ainsi créée.
*/
	var main = new Main(); //creates a new Main instance
	main.init(); // init the main instance
};

En suivant les commentaires vous devriez pouvoir retrouver la logique applicative, cependant quelques petites choses sont à préciser notamment:

- Comme vous pouvez le constater, nous utilisons l’événement natif “onload” de l'objet “window” qui est envoyé par le navigateur lorsque TOUT les éléments sont chargés ET disponibles, comme le DOM, les images, le son etc… Par conséquent, nous pouvons utiliser notre image “perso1.png” dont l'id est “perso” afin de la dessiner au sein de notre canvas.

- Toutes les classes de la librairie sont définies au sein d'un ”namespace virtuel” nommé tomahawk_ns, en javascript, on émule ce mécanisme en créant un objet qui portera le nom de notre namespace. Toutes les classes sont ainsi disponibles à travers cet objet, ce qui fait que vous pouvez définir toutes les classes que vous voulez, elles n'entreront pas en collision avec une autre librairie qui pourrait éventuellement employer les mêmes noms de classes/fonctions.

- Nous retrouvons à un moment donnée une instance unique d'un objet de type Stage, il s'agit en fait de la racine de notre ”display list” qui par définition est donc unique. La classe Stage hérite de la classe DisplayObjectContainer qui elle-même hérite de la classe DisplayObject. Un DisplayObjectContainer est un DisplayObject qui peut contenir des enfants ( comme une <div></div> au sein du DOM ).

- Nous créons, à un moment donné, un objet de type tomahawk_ns.Texture, il s'agit d'un objet qui va nous permettre de stocker pas mal d'informations qui vont permettre à un autre objet de dessiner quelque chose à l'écran.

- Enfin nous créons un nouvel objet de type tomahawk_ns.Bitmap qui va utiliser l'objet de type texture en question afin de pouvoir dessiner notre image au sein du canvas. Cet objet peut être manipulé, on peut modifier sa position en x et y, son échelle en x, y ainsi que sa rotation, sa transparence etc etc… Cet objet de type Bitmap est un DisplayObject çàd que c'est un objet qui a pour vocation à être affiché au sein de la DisplayList, nous l'ajoutons en tant que premier enfant de notre racine, notre objet de type “Stage

En savoir plus

Je vous invite à jeter un oeil à la page dédiée au projet à l'adresse suivante: http://the-tiny-spark.com/tomahawk/ Vous pouvez également jeter un oeil au mediabook du projet “Comment créer un moteur d'affichage 2D en HTML5 canvas” à l'adresse suivante https://docs.google.com/document/d/1Ye1Ow72rHtskR3Lf_FdOPl4MsqWAl-rEsnt0K3QO05M/edit

Si vous souhaitez poursuivre votre apprentissage, la section “examples” comporte pas mal de code tout prêt dédié uniquement à l'auto-apprentissage. Vous pouvez couvrir l'ensemble des bases de Tomahawk.

Bon code !