Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Chapitre 2 : Dessiner en JavaScript avec la balise Canvas

Par gnicos (Nicolas Gauville), le 13 juillet 2012
Navigation rapide :

<< Chapitre 1 - Sommaire - Chapitre 3 >>

Dans ce chapitre, nous allons continuer notre apprentissage de la balise Canvas en s'intéressant notamment à comment on peu dessiner à l'intérieur en JavaScript.

Note à propos du dessin : Si vous souhaitez apprendre à dessiner les tuiles, vous pouvez vous référer à d'autres ressources sur MédiaBox :

- En Flash : j'ai rédigé un tutoriel ICI sur le sujet.

I. Dessiner dans un Canvas

Nous allons commencer par voir comment dessiner dans notre Canvas, Dans le chapitre précèdent, nous avons définit une variable pour accéder à notre Canvas, nous allons maintenant, via cette variable, commencer à dessiner.

Tout d'abord, deux types de formes sont possibles : “fill” et “stroke”. Les formes de type “fill” sont des formes pleines, à l'inverse des formes “stroke”, composées de contours uniquement.

A. Les rectangles

Les couleurs peuvent être définies de quatre façons, tout comme en CSS : par exemple, pour du bleu :

  • Code en base 16 : #0000FF
  • Paramètre RGB en base 10 : rgb ( 0, 0, 255 )
  • Paramètres RGB en base 10 + transparence (entre 0 et 1) rgba ( 0, 0, 255, 1 )
  • Nom de la couleur, en anglais : blue

La méthode “rgba” permettant d'utiliser des couleurs transparentes.

Pour dessiner un rectangle, nous allons ainsi pouvoir utiliser les méthodes fillRect et stokeRect. Ces deux méthodes comprennent quatre paramètres : la position du rectangle (x, y), et ses dimensions (largeur, hauteur). On peu par exemple faire ceci, pour obtenir un carré bleu avec des bords verts :

var gameview = document.getElementById('gameview');
var contexte = gameview.getContext('2d');
 
//On définit le style de remplissage (ici, du bleu)
contexte.fillStyle = "rgba(0,0,255,1)";
 
//On définit le style de traits (ici du vert)
contexte.strokeStyle = "rgba(0,255,0,1)";
 
//On déssine un carré
contexte.fillRect(200, 200, 200, 200);
 
contexte.strokeRect(200, 200, 200, 200);

D'autres formes sont bien évidement disponibles, et fonctionnent de la même façon.

B. Les arcs, les cercles

Pour dessiner un cercle, nous devons commencer par initier un tracé :

//On commencer par signaler le début d'un nouveau tracé
contexte.beginPath();

On utilise ensuite la fonction arc, qui accepte les paramètres suivants :

  • Position du centre du cercle en X
  • Position du centre du cercle en Y
  • Diamètre du cercle (en pixels)
  • Angle de départ de l'arc en Radians (pour un cercle, on prends donc 0).
  • Angle de fin (pour un cercle, 2PI radians, donc).
//On trace un cercle de 30px de diamètre, dont le centre est aux coordonnées (100,100).
contexte.arc(100, 100, 30, 0, Math.PI*2);

Ensuite, on doit définir le type de tracé (fill pour les formes pleines, strocke pour les contours). Pour cela, on utilise les fonctions “fill” et “strocke”, tout simplement. Biensur, on peu utiliser les deux en même temps.

contexte.fill();
contexte.stroke();

Enfin, il font signaler que nous avons terminé notre tracé, avec la fonction closePath :

contexte.closePath();

C. Les lignes, les formes "complexes"

Pour tracer des lignes, nous allons réutiliser les fonctions que nous venons de voir, en ajoutant deux nouvelles : moveTo et lineTo. Nous pouvons ainsi associer les fonctions moveTo, lineTo et arc pour dessiner, avant d'utiliser “fill” et/ou “strocke” pour tracer notre dessin.

Par exemple, si l'on veut un triangle :

contexte.beginPath();
contexte.moveTo(20, 320);
contexte.lineTo(170, 20);
contexte.lineTo(320, 320);
contexte.lineTo(20, 320);
contexte.fill();
contexte.stroke();

Nous pouvons également modifier les paramètres du tracé grâce aux deux propriétés suivantes :

contexte.lineWidth : correspond à l'épaisseur des lignes.

contexte.lineJoin : type de jointure entre deux ligne. Cette propriété peut être assignée à “bevel” (pour des jointures en biseau), ou “round” (arrondies).

D. Le texte

L'ajout de texte dans un Canvas se fait très simplement. Pour commencer on définit la taille et la police via le paramètre font :

contexte.font = "12px Arial Black";

Puis, on utilise la méthode “fillText”, qui prends trois paramètres : le texte, et la position (x puis y). Par exemple :

contexte.fillText("Bonjour !", 50, 50);

II. Dessin VS Images PNG

Lorsque nous allons réaliser notre jeu, nous allons évidemment devoir afficher nos tuiles à l'écran. Et pour cela, avec le Canvas, nous aurons deux possibilités : dessiner dans le canvas, ou utiliser des images PNG. En résumé, voici globalement les avantages et défauts des deux méthodes :

Méthode “dessin des tuiles” :

  • + Beaucoup plus léger (donc plus rapide à charger, notamment pour ceux qui ont un faible débit).
  • + Configurable facilement (on peu changer facilement les couleurs ou ce genre de choses via le code).
  • - Plus lent à l’exécution (même problème que pour les dessins vectoriels sur flash).
  • - Tous les logiciels de dessin ne sont pas utilisables, on ne pourra pas retoucher nos tuiles sur Photoshop par exemple.
  • - Impossible d'appliquer des effets importants (autre que les effets simples, et encore, ils sont lents à l’exécution).

Utilisation d'images :

  • + Permet d'utiliser n'importe quel logiciel de dessin.
  • + Permet la réalisation d'effets à souhaits
  • + Plus rapide à l’exécution
  • - Beaucoup plus lent à charger, surtout s'il y a beaucoup de tuiles
  • - Pas de configuration possible via javascript (ou très faible, peu exploitable).

Comme vous le voyez, chaque méthode à ses avantages. Le choix devra donc être fait en fonction du type de jeu à réaliser, savoir si les style de tuiles peu être réalisé en dessin ou non, savoir si les tuiles devront être configurables par le joueur par exemple (ce qui demanderais la création d'un grand nombre de PNG), etc.

Dans ce tutoriel, j'essaierai de vous montrer les deux méthodes, dans la mesure où vous pouvez avoir besoin de l'une comme de l'autre. De plus, nous allons ainsi développer un moteur qui saura s'adapter tout aussi bien à l'utilisation d'images que de dessins.

III. Le framework CreateJS

Dans la suite du tutoriel, après une longue réflexion sur le sujet, j'ai choisis d'utiliser le framework CreateJS. Cette partie va introduire son utilisation.

A. Pourquoi utiliser un framework ? Pourquoi CreateJS ?

L'utilisation de ce framework apporte un certain nombre d'avantage non négligeables, qui justifient son utilisation dans ce tutoriel. Voici les principaux avantages :

  1. + CreateJS propose une bibliothèque graphique (EaselJS) conséquente, qui permet de gérer les graphismes et dessins beaucoup plus aisément que ce que nous pouvons le faire avec les fonctions de base du canvas.
  2. + CreateJS intègre de nombreuses choses, comme un moteur de Tweens (TweenJS) (fonctions permettant de créer facilement des animations), des bibliothèques pour la gestion des chargement de fichiers (PreloadJS), ou encore la gestion de sons (SoundJS).
  3. + Les classes fournies par EaselJS fonctionnent de façon similaire à certaines classes AS3 (MovieClip, Stage, …).
  4. + Flash peut, à l'aide d'une extension, exporter des symboles en JavaScript en utilisant CreateJS.

Les deux derniers points sont évidement ceux qui ont motivé ma décision. D'un part parce que les cours sur l'ActionScript 3 font partie intégrante de MédiaBox, et qu'une grande partie d'entre vous sait donc probablement l'utiliser. Vous serez donc heureux d'apprendre qu'avec CreateJS, vous ne serez pas dépaysé. Ensuite, l'exportation des graphismes depuis Flash est très bien faite, le code obtenu est clair, etc.

B. Stucture de CreateJS

CreateJS est découpé en quatre bibliothèques, plus ou moins indépendantes :

  • - EaselJS
  • - SoundJS
  • - PreloadJS
  • - TweenJS

Pour l'instant, seules EaselJS et PreloadJS nous seront utiles. Nous pouvons également installer TweenJS qui pourra nous permettre d'ajouter des effets par la suite.

Dans le fichier HTML, entre les balises <head>, nous pouvons ajouter :

<script src="http://code.createjs.com/easeljs-0.4.1.min.js"></script>
<script src="http://code.createjs.com/preloadjs-0.1.0.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.2.0.min.js"></script>

C. Commençons à utiliser EaselJS

Pour commencer, nous allons instancier la classe Stage, et assigner son instance au Canvas :

var gameview = document.getElementById('gameview'), stage;
 
stage = new Stage(gameview);
stage.update();

Nous allons maintenant voir brièvement ce que nous allons pouvoir faire avec tout ça !

D. Fonctionnement global et documentation

Pour commencer, la documentation d'EaselJS est disponible ici : http://www.createjs.com/Docs/EaselJS/

Vous remarquerez, avec plaisir je pense, qu'un grand nombre de classes d'EaselJS fonctionnent de façon très similaires aux classes graphiques natives en ActionScript 3.

D'un point de vue graphique, vous remarquerez également que les méthodes de la classe Shape sont très proches de celles que nous avons vu précédemment pour dessiner dans le Canvas, mais il y en a tout de même plus, nous permettant de dessiner ainsi plus facilement encore.

Mais globalement, la gestion des graphismes est ce qui nous aidera le plus dans EaselJS.

E. Toolkit pour Flash CS6

Autre bonne nouvelle concernant EaselJS : Flash CS6 peut exporter des graphismes pour CreateJS via une extension. Nous allons rapidement regarder les fonctionnalités offertes.

Commencez par télécharger l'extension ici : http://www.adobe.com/fr/products/flash/flash-to-html5.html Une fois téléchargée, installez l'extension via Adobe Extension Manager CS6. Une fois fait, vous pourrez relancer Flash et afficher le menu de “Toolkit For CreateJS” via le menu Fenêtre > Autres Panneaux > Toolkit for CreateJS.

L'extension intègre automatiquement les fichiers nécessaires parmis les bibliothèques de CreateJS (par exemple, SoundJS sera ajouté seulement si vous utilisez des sons).

L'option “Compact Shapes” peut être intéressante. En effet, si vous exportez vos dessins pour les afficher simplement dans le Canvas ensuite, cette option permet de gagner beaucoup de place (plus de 50% en général). A l'inverse, la désactiver, sur des formes simples, peu permettre de rendre des graphiques “configurables”.

Lorsque vous utilisez ce toolkit dans un projet, trois méthodes sont possibles :

1. Utiliser directement les fichiers exportés depuis Flash. Dans ce cas la, vous pouvez par exemple rajouter un fichier .js dans lequel vous mettrez votre propre code, et vous pouvez désactiver l'option “Publish HTML” pour éviter d'avoir à modifier le fichier index à chaque fois.

2. Récupérer les graphiques exportés (dans le fichier JS généré par flash), et les réintroduire (et éventuellement modifier) dans le projet (se trouvant dans un autre dossier par exemple). Cette méthode à l'avantage d'avoir un code à notre gout, mais pose également un défaut : elle n'est pas pratique si l'on réédite régulièrement nos graphismes sur Flash.

3. Coder en JavaScript directement dans flash. Pour cela, il suffit de mettre le code JS dans la fenêtre “Action” (comme pour du code AS3), mais dans des commentaires. Par exemple :

//Code AS3
addChild ( monClip );
 
//Code JS
/* js
this.addChild ( this.monClip );
*/

Cette méthode à deux défauts : le code généré par flash ne sera pas toujours aussi clair que le votre, et il faudra exporter avec l'extension Toolkit for CreateJS à chaque fois que vous voudrez tester votre projet. Cependant, cette méthode peut s'avérer absolument géniale si vous devez développer un projet à la fois en HTML5/JS et en AS3. Vous pouvez, par exemple, prévoir plusieurs formats de sorties (Flash, AIR, AIR pour iOS/Android ou autre, et HTML/JS) combinés en un seul projet.

F. Concluons

Ces deux premiers chapitres n'étaient pas forcément les plus intéressants, mais il était important de poser les bases pour la suite du cours. Dans les prochains chapitres, nous allons attaquer le codage des principales classes du jeu, et nous commencerons alors à avoir un résultat.

Dans les prochains chapitres, nous allons réaliser un premier jeu simple. Les cours suivants aborderont des points particuliers décrivant entre autre les diverses méthodes pour réaliser l'un des éléments du jeu. Ils se baserons en partie sur les six chapitres précédents, mais pas les uns sur les autres (annexe a annexe). En effet, vous ne vous intéressez pas forcément à la totalité de ces fonctions, et ces cours ciblés vous permettrons ainsi d'accéder à ce qui vous intéresse directement.

Navigation rapide :

<< Chapitre 1 - Sommaire - Chapitre 3 >>