HTML c’est le langage du web qui est né dans les années 90 et qui a subi de nombreuses évolutions au cours du temps. Je ne vais pas vous en faire l’historique mais seulement vous montrer comment utiliser ses dernières possibilités avec la version 5.

Dans ce chapitre je vais présenter l’élément canvas et la librairie Pixi.js, le chargement des images et leur transformation en textures utilisables, la création de sprites et leur manipulation. On verra enfin les structures de base du code pour l’animation.

Canvas
Les créateurs de jeux ont été les premiers à comprendre l’intérêt du HTML5, essentiellement avec l’arrivée de l’élément canvas qui permet de créer des graphismes dynamiques. Pour comprendre de quoi il s’agit prenons un exemple :

<!DOCTYPE HTML>
<html>
<head>
<title>Cours pixi</title>
<meta charset="UTF-8">
<style>
canvas {
margin: 0 auto;
display: block;
}
</style>
</head>
<body>
<canvas id="moncanvas" width="200" height="250"></canvas>
<script>
var moncanvas = document.getElementById('moncanvas'),
ctx = moncanvas.getContext('2d');
ctx.fillStyle = 'cyan';
ctx.strokeStyle = 'blue';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.arc(50, 50, 35, 0, Math.PI * 2, true);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(150, 50, 25, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.fillStyle = 'red';
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(75, 150);
ctx.lineTo(125, 150);
ctx.lineTo(100, 100);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.fillStyle = 'chartreuse';
ctx.strokeStyle = 'green';
ctx.fillRect(40, 180, 120, 40);
ctx.strokeRect(40, 180, 120, 40);
</script>
</body>
</html>

figure 1

L’intégration dans une page HTML est des plus simples :

<canvas id="moncanvas" width="200" height="250"></canvas>
On utilise la balise canvas et on définit les dimensions en pixels, ce qui a pour effet de créer sur la page une zone où on va dessiner.

Je ne vais pas entrer dans le détail de ce code parce que nous n’aurons pas à utiliser directement canvas. Cet exemple a pour seul objectif de vous montrer qu’on peut facilement dessiner avec lui. Sachez aussi qu’on peut tout aussi facilement modifier dynamiquement ce qu’on dessine et vous commencerez à avoir une idée de ce qu’il est possible de réaliser ainsi.

Il est nécessaire par contre de connaître le système de coordonnées utilisé. L’origine se situe en haut à gauche :

Chaque point est ainsi défini par ses coordonnées x et y.

P5js

P5js est une librairie JavaScript qui gère le canvas à votre place et il sait parfaitement bien le faire ! Vous trouverez cette librairie sur le site https://p5js.org/ avec des exemples et sa documentation. 

Avant d'entrer dans le vif du sujet, mettons en place notre environnement de travail :

Télécharger ici les fichiers de l'activité.

Celui-ci a la structure suivante : 

 

 

Vous obtenez plusieurs dossiers, et les librairies p5js se trouve dans le répertoire lib.

La structure des fichiers index.html et script.js sont les suivants :

index.html
 
<link rel="stylesheet" href="/css/style.css">
<script src="/lib/p5.js"></script>
<script src="/lib/p5.play.js"></script>
<script src="/js/script.js"></script>

 

script.js
 

setup()

draw() 

 

Voici la prestation minimale dans le fichier index.html pour utilise p5js :

 

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>p5js Sin</title>
<link rel="stylesheet" href="/css/style.css">
<script src="/lib/p5.js"></script>
<script src="/lib/p5.play.js"></script>
<script src="/js/script.js"></script>
</head>
<body>
</body>
</html>

Dans la page web index.html, on n'a juste à charger le css et les scripts.

Le script avec lequel vous travaillerez est scripts.js :

function setup() {
createCanvas(400, 400);//creer un canvas sur la page html

}//fin procédure setup

function draw() {
background(220,220,220);//couleur arriere plan
fill('cyan');//couleur interieur
strokeWeight(5);//largeur contour
stroke(0,0,255);//couleur contour
ellipse(200,200,100,50);//dessine une ellipse

}//fin procédure draw

Ce script se compose obligatoirement de :

  • setup() -> initialisation (se lance au démarrage)
  • createCanvas(largeur, hauteur) pour créer un canvas sur la page html;
  • draw()  -> redessine indéfiniment le canvas 

 

Le résultat de tout cela est l’affichage d’une ellipse rouge de manière simple (appuyer sur le bouton Run) :

img05

Maintenant, nous avons tout ce qu’il nous faut pour refaire la figure 1 de manière simple en modifiant script.js !

Les procédures que vous aurez à utiliser pour réaliser la figure 1 sont les suivantes :

  • fill(Rouge,Vert,Bleu); //couleur de la figure (Rouge, vert et bleu varient entre 0 et 255);
  • stroke(Rouge,Vert,Bleu); //couleur du contour de la figure
  • strokeWeight(epaisseur) ; //epaisseur du contour de la figure
  • rect(x,y,largeur,hauteur);  //dessine un rectangle
  • triangle(x1,y1,x2,y2,x3,y3);  //dessine un triangle
  • ellipse(x,y,largeur,hauteur);  //dessine une ellipse 

 Maintenant, vous n'aurez plus cas modifier le fichier js/script.js pour réaliser les activités demandées.

 

Par ailleurs, le code avec p5js pour obtenir la figure 1 est les suivant :

function setup() {
createCanvas(400, 400);
}

function draw() {
background(220);
fill('cyan');
stroke(0,0,255);
strokeWeight(5);
ellipse(50, 50, 70, 70 );
ellipse(150, 50, 50, 50 );
fill('red');
triangle(100, 100,75, 150,125, 150);
fill(255,255,0);
stroke(0,255,0);
rect(40, 180, 120, 40);
}

Le code est plus simple avec l’utilisation de méthodes spécifiques pour dessiner cercles et rectangles. Mais on va voir que ce n’est pas vraiment là que p5js va se révéler performant ! 

On voit que travailler avec p5js, consiste à créer des objets (triangle, rectangle, ...) dans le fichier script.js pour qu'ils affichent sur la page web index.html.

Mais que va-t-on mettre dans le conteneur ?

On a vu un exemple avec des objets graphiques construits. Mais ce qu’on va surtout y placer ce sont des sprites.

Sprite

Un sprite est un constituant essentiel des jeux vidéo. ce sont des éléments graphiques qu’on peut manipuler : taille, position, teinte…

Pour créer un sprite il nous faut une image au format png ou jpg (jpeg). Prenons un exemple :

//déclaration des variables
var sin;
var sinImg;

//chargement des images
function preload() {
sinimg = loadImage('assets/sin.png');
}
//initialisation et creation du sprite et du canvas
function setup() {
createCanvas(400, 400);
sin = createSprite(width/2, height/2);
sin.addImage(sinimg);
}//fin setup

function draw() {
background(255);
//deplace le sprite en fontion des coodonnées de la souris
sin.position.x = mouseX;
sin.position.y = mouseY;
//rotation du sprite lorsque l'on appuie sur un bouton de la souris
if (mouseIsPressed) {
sin.rotation += 2;
}
//dessine les sprites
drawSprites();
}//fin draw

Explications du code

On charge le ou les’images dans la procédure preload  :

function preload() {
sinimg = loadImage('assets/sin.png');
}

Une fois que les images sont chargées, la procédure setup est appelée pour créer le canvas et le sprite :

function setup() {
createCanvas(400, 400);
sin = createSprite(width/2, height/2);
sin.addImage(sinimg);
}//fin setup


Il suffit ensuite de mettre le sprite dans le draw pour l'animer sur le canvas :

function draw() {
background(255);
//deplace le sprite en fontion des coodonnées de la souris
sin.position.x = mouseX;
sin.position.y = mouseY;
//rotation du sprite lorsque l'on appuie sur un bouton de la souris
if (mouseIsPressed) {
sin.rotation += 2;
}
//dessine les sprites
drawSprites();
}//fin draw

 

Attention, il faut mettre la procédure drawSprites() dans le draw pour que les sprites soient dessinés.

img06


Position, taille et rotation

Une fois qu’on a un sprite on peut le manipuler. En particulier on peut le positionner, changer sa taille ou sa rotation.

Position
La position d’un sprite est définie par ses propriétés x et y :

function setup() {
...
sprite.position.x = 40;
sprite.position.y = 60;
...
}
img07

Ce qui peut aussi s’écrire avec cette simple ligne :

sprite.position.set(40, 60);
Le point d’origine du sprite est fonction de ce que vous avez mis dans createSprite(width/2, height/2). Avec les paramètres width/2 et height/2, il se trouve au milieu du sprite.

Taille
Mon sprite a pour dimensions 48 x 48. Pour changer ces dimensions il suffit de modifier les propriétés width et height :

sprite.width = 30;
sprite.height = 60;
img08

Une autre façon de procéder est d’utiliser la propriété scale qui a la valeur 1 par défaut :

sprite.scale.x = 1.2;
sprite.scale.y = 0.8;
img09

C’est surtout cette propriété qu’on va utiliser, plutôt que la précédente. La valeur est un pourcentage des dimensions du sprite, de 0 (0%) à n (n * 100%). Dans le cas ci-dessus on a donc 120% et 80%.

Ce qui peut aussi s’écrire avec une seule ligne :

sprite.scale.set(1.5, 0.8);
Rotation
Essayons maintenant de faire tourner le sprite :

sprite.rotation = 0.5;
img10

J’ai parlé plus haut du point de référence du sprite qui se situe dans la partie supérieure gauche, la rotation s’effectue autour de ce point.

La valeur est en radians, donc 0.5 correspond en gros à 28 degrés.

Pour mémoire :

radians = degres * (Math.PI / 180);
degres = radians * (180 / Math.PI);
On peut changer la position du point de référence :

sprite.anchor.x = 0.5;
sprite.anchor.y = 0.5;
sprite.rotation = 0.5;
img11

Les valeurs vont de 0 (origine) à 1 (côté opposé). Ici avec la valeur 0.5 on est pile au milieu.

Ce qui peut aussi s’écrire avec une seule ligne :

sprite.anchor.set(0.5, 0.5);
Action !
Pour le moment notre sprite ne bouge pas beaucoup ! Le rendu est effectué une fois pour toutes et plus rien ne change. Evidemment pour faire de l’animation on a besoin de rafraîchir régulièrement l’affichage. On va donc créer une boucle infinie. regardez cet exemple :

<script>
var renderer = PIXI.autoDetectRenderer();
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();
PIXI.loader
.add('img/image.png')
.once('complete', setup)
.load();
var sprite;
function setup() {
sprite = new PIXI.Sprite(PIXI.loader.resources['img/image.png'].texture);
sprite.x = 40;
sprite.y = 60;
sprite.anchor.set(0.5, 0.5);
stage.addChild(sprite);
gameLoop();
}
function gameLoop(){
requestAnimationFrame(gameLoop);
sprite.rotation += 0.01;
renderer.render(stage);
}
</script>
La nouveauté par rapport à ce qu’on a vu ci-dessus est la création d’une fonction récursive gameLoop . Comme j’ai prévu de changer la valeur de la rotation en l’incrémentant de 0.01 radian à chaque fois on va avoir une rotation régulière du sprite :

img12

On a ici les bases de notre moteur de jeu. En gros :

on crée un canvas (renderer),

on ajoute le canvas à la page (appendChild),

on crée un conteneur (stage),

on charge les ressources (loader),

on initialise les sprites (setup) et on les met dans le conteneur (addChild),

on crée une boucle infinie pour faire les changements à l’affichage.

Les bases sont là mais on a encore du chemin à parcourir !

 

En poursuivant votre navigation sur mon site, vous acceptez l’utilisation des Cookies et autres traceurs  pour réaliser des statistiques de visites et enregistrer sur votre machine vos activités pédagogiques. En savoir plus.