Licence CC BY-NC-SA

Dessine-moi un mouton !

Dernière mise à jour :

D'accord les enfants, j'ai compris, on passe à la pratique !

Bon, le mouton attendra, mais on va commencer par quelque chose de simple : un fond coloré (avec un dégradé, quand même) et un bouton (qui permettra de lancer le jeu en lui-même).

On va donc commencer par une page d'intro assez classique, sur laquelle on va dessiner doucement des petites choses basiques.

Créer une scène

Le point de départ du jeu, c'est bien évidemment les scènes : vous pouvez les afficher et les cacher à volonté, mais surtout vous pouvez les créer comme bon vous semble et même les superposer !

On va donc commencer par afficher une scène qui nous servira d'écran de lancement, sur laquelle on va travailler tout au long du chapitre :

1
2
3
Q.scene('startGame', function(stage) { // On crée une nouvelle scène que l'on nomme. Une fois affichée la fonction sera appelée, avec en paramètre notre objet scène (dont on récupèrera quelques infos et auquel on balancera quelques objets)
    console.log('Écran de lancement affiché');
});

Ensuite on va demander à Quintus de l'afficher dès que possible :

1
Q.stageScene('startGame', 0); // On affiche notre scène au rang 0, soit tout en bas de la pile (pensez à des calques, comme sous votre logiciel de dessin préféré ou à un z-index en CSS)

Voilà, vous avez donc une scène (vierge pour l'instant) d'affiché sur votre canvas. Maintenant on va voir comment la remplir, histoire de lui donner des couleurs…

Dessiner un fond coloré

Pour dessiner un simple rectangle jaune, on va commencer par créer un sprite de la taille que l'on veut (ici la taille du canvas) et lui attribuer un type UI (plus d'infos là-dessus dans la gestion des collisions) :

1
var sprite_bg = new Q.Sprite({ x: 0, y: 0, w: Q.width, h: Q.height, type: Q.SPRITE_UI });

Maintenant que notre sprite est créé, il faut indiquer au canvas ce que l'on veut y dessiner (un rectangle jaune pour l'instant) :

1
2
3
4
sprite_bg.draw = function(ctx) { // Au moment de dessiner le sprite, on récupère le contexte 2D du canvas pour dessiner librement
    ctx.fillStyle = '#e0b232'; // On veut du jaune
    ctx.fillRect(this.p.x, this.p.y, this.p.w, this.p.h); // On dessine un rectangle de la taille du sprite
}

Le contexte 2D du canvas est un objet qui nous permet de travailler sur le canvas en y dessinant des éléments. Comme il s'agit d'un contexte 2D, les éléments dessinés ne peuvent donc pas être en 3D (qui ne sera pas abordée dans ce tuto car elle n'est pas encore gérée par Quintus).

Mais jusqu'ici rien n'indique ce que l'on veut faire avec ce sprite. Il faut donc l'ajouter à notre scène :

1
stage.insert(sprite_bg);

Et voilà ! Vous avez maintenant un beau fond jaune !

Ajouter un dégradé

Maintenant que l'on a un fond uni, ce serait peut-être pas mal d'y dessiner un dégradé, non ?

Et comme un veut que notre dégradé soit par-dessus notre fond jaune, il suffit de le dessiner juste après, en reprenant notre méthode .draw() :

1
2
3
4
5
var degrade = ctx.createRadialGradient(Q.width/2, Q.height/2, 0, Q.width/2, Q.height/2, Q.width/2); // On crée un dégradé radial qui commence du centre du sprite et qui s'étend sur la moitié de la taille de ce même sprite
degrade.addColorStop(0, '#ffffff'); // Le centre sera blanc
degrade.addColorStop(1, 'rgba(255, 255, 255, 0)'); // La fin sera transparente
ctx.fillStyle = degrade; // On veut dessiner notre dégradé
ctx.fillRect(0, 0, Q.width, Q.height); // On dessine le dégradé par-dessus le fond jaune

En ajoutant ce code à la fin de la méthode vue un peu plus tôt, vous devriez voir apparaître un dégradé qui part du blanc (au centre) vers le jaune (ou plutôt du transparent, vu qu'on utilise notre fond jaune).

Un peu de texte

Pour ajouter du texte, c'est très simple, il existe un élément Text que l'on peut placer automatiquement en fonction de son centre et qui peut être personnalisé (couleur, taille…).

Comme il s'agit d'un descendant de l'élément Sprite et que vous savez déjà ajouter un sprite à la scène, on va faire d'une pierre deux coups :

1
2
3
4
5
6
7
8
9
var title = stage.insert(new Q.UI.Text({
    x: Q.width/2,
    y: 50,
    label: 'Mon super jeu',
    align: 'center',
    family: 'Comic Sans MS, Comis Sans, cursive', // Oui, du Comic Sans ! Pourquoi pas ?
    size: 48, // C'est un titre, donc c'est gros
    color: '#aa4242' // Un rouge foncé, comme un bon verre de rouge… (hips !)
})); // On insère un titre sous forme de texte en haut, centré

Vous voyez donc que stage.insert() nous renvoie l'élément ajouté : ici notre objet texte.

Ajouter des boutons

Parce que c'est assez pratique d'avoir des boutons dans un jeu (surtout sur un écran de lancement), on va voir comment en créer.

Mais, plus intéressant encore, on va apprendre comment grouper des éléments ensemble (et ça ne fonctionne pas qu'avec les boutons) au moyen d'un Container :

1
2
3
4
5
6
var container = stage.insert(new Q.UI.Container({ // On crée un conteneur
    x: Q.width/2, // On le centre en largeur
    y: Q.height/2, // On le centre en hauter
    fill: 'rgba(0, 0, 0, 0.5)', // On applique un fond noir semi-transparent
    radius: 5 // Des bordures arrondies de 5 pixels pour faire joli
}));

Et voilà, vous savez grouper des éléments ! Non, je rigole, pour ça il manque un détail : le contenu.

On va donc se dépêcher de créer un bouton :

1
var button = container.insert(new Q.UI.Button({ x: 0, y: 0, fill: '#f7f7f7', label: 'Jouer', highlight: '#ffffff', radius: 2 })); // On insère un bouton dans notre conteneur, avec un fond blanc cassé, qui devient blanc au clic, en haut du conteneur

Avoir un bouton, c'est bien gentil, mais il faut peut-être qu'il soit utile ! Donc, on va faire en sorte de pouvoir cliquer dessus. Vous en dites quoi ?

1
2
3
4
5
button.on('click', function() { // On place un écouteur sur le bouton pour gérer le clic
    Q.clearStages(); // On vide les scènes affichées, pour repartir sur un canvas vierge
    console.log('Bouton cliqué, lancement du jeu…'); // Regardez votre console ;)
    Q.stageScene('game', 0); // On affiche une autre scène (qui sera crée dans la partie 3) au rang 0, soit tout en bas dans la pile des calques
});

Et maintenant, il manque un seul petit détail pour que notre conteneur soit à la bonne taille :

1
container.fit(10); // On adapte la taille du conteneur à son contenu (le bouton), avec un padding (marge interne) de 10 pixels

Et voilà, vous avez maintenant un beau bouton au centre de votre scène !

Je vous laisse le plaisir d'en ajouter d'autres (avec la même méthode) pour le fun… ;)

Attention tout de même : utilisez la méthode container.fit() une fois tous les boutons ajoutés, ce serait dommage de faire des calculs pour rien ou d'obtenir un résultat étrange.

Et maintenant… le mouton !

Maintenant que vous avez compris comment on ajoute des éléments de base sur la scène, on va apprendre à ajouter des images.

On va donc commencer par un mouton. Et pas n'importe quel mouton : Raymond le Super Mouton !

Dites bonjour à Raymond

Pour commencer, on va demander à la librairie de charger l'image dont on a besoin (celle affichée juste au-dessus, que j'ai nommée raymond.png et qui est rangée dans le dossier des images). Et comme on ne veut pas afficher notre écran avant que l'image soit chargée, on va remplacer la ligne qui servait à afficher notre scène au passage :

1
2
3
Q.load(['raymond.png'], function() { // Quintus détecte tout seul si l'on veut charger une image, un son ou tout autre fichier : il suffit d'indiquer son nom avec l'extension
    Q.stageScene('startGame', 0); // On affiche notre scène
});

J'en profite pour vous informer que vous pouvez suivre l'avancement du changement : Quintus calcule automatiquement le pourcentage.

1
2
3
4
5
6
7
Q.load(['raymond.png' /* vous pouvez aussi ajouter des assets ici, à la suite du tableau, pour en charger plusieurs */ ], function() {
    Q.stageScene('startGame', 0);
}, {
    progressCallback: function(loaded, total) {
        console.log('Chargement : ' + Math.floor(loaded/total*100) + '%'); // On affiche le pourcentage dans la console
    }
});

Maintenant que notre image est en mémoire et que notre scène est affichée au bon moment, il n'y a plus qu'à afficher l'image. Je vous conseille de l'afficher juste après le dégradé de fond et avant le titre (même si l'afficher après ne changera pas grand chose, je vous l'accorde, mais au moins avant le conteneur si vous voulez pouvoir accéder au bouton).

1
2
var img_bg = new Q.Sprite({ x: Q.width/2, y: Q.height/2, w: Q.width, h: Q.height, tileW: Q.width, tileH: Q.width, asset: 'raymond.png'}); // On ajoute notre image en spécifiant l'asset à utiliser, les dimensions à lui donner et la partie de l'image à utiliser (ici 600x800, soit la taille du canvas)
stage.insert(img_bg); // Ne pas oublier d'insérer l'image (à noter que vous pouvez tout faire en une seule ligne, comme déjà vu plus tôt)

Bonus : un mouton qui bouge !

Comme vous avez été sages, je vais vous apprendre à animer un Sprite en utilisant la librairie Tween incluse dans Quintus !

Pour commencer, on va ajouter le composant à notre Sprite du mouton :

1
img_bg.add('tween');

Ensuite, on va créer une fonction pour animer notre élément, qui sera appelée en boucle :

1
2
3
function moveSheep() {
    this.animate({ y: this.p.cy-50 }, 1.5, Q.Easing.Quadratic.InOut, {}).chain({ y: this.p.cy }, 1.5, Q.Easing.Quadratic.InOut, { callback: moveSheep });
}

Pour mieux comprendre, voilà ce que l'on fait : on récupère notre sprite (this — vous devriez être familier avec ce mot-clé si vous avez fait un minimum d'objet), puis on l'anime pour le faire monter (en utilisant la position verticale de son centre) de 50 pixels en 1.5 seconde avec un effet d'easing (transition avec un rendu plus naturel car utilisant quelques principes de physique).

Ensuite, avec la méthode chain() on fait l'inverse pour qu'il retrouve sa position initiale une fois la première animation terminée.

Le dernier paramètre permet de définir une méthode de callback qui sera appelée une fois l'animation terminée. On va donc réutiliser notre fonction moveSheep:)

Il ne nous reste plus qu'à appeler notre fonction pour que notre Raymond national soit animé :

1
moveSheep.apply(img_bg);

Et voilà, votre mouton lévite tout seul !


Alors, il est pas beau ce mouton ⁈ :D