Main Menu
Depuis l’ouverture de ce blog nous nous intéressons à deux librairies distinctes pour la création d’un jeu :
- Box2d Web : le moteur physique du jeu qui permet de créer un environnement physique, de gérer les forces, collisions et déplacements d’objets dans un monde 2D. C’est-à-dire de faire en sorte que ça bouge de manière réaliste à l’écran,
- EaselJS : le moteur graphique du jeu qui permet de gérer le rendu graphique, d’afficher des images et de dessiner des formes dans un canvas HTML. C’est-à-dire d’afficher de jolies choses à l’écran.
Dans les précédents tutoriels nous avons étudié ces bibliothèques (surtout la première) de manière totalement indépendante. Dans ce tuto je vous propose enfin de répondre à la grande question qui nous intéresse tous : « Mais comment donc que l’on fait cohabiter Box2 Web et EaselJS ? ».
L’objectif est d’allier la simplicité d’Easel JS et la puissance de Box2d Web pour réaliser une première démo à la fois dynamique et visuellement présentable :
Résultat final
Le résultat final peut être observé ici.
Et, comme d’habitude, les sources sont à disposition et c’est par là.
Pré-requis
Attention ! Ce tutoriel n’a pas vocation à expliquer comment fonctionnent les librairies Box2d Web et EaselJS, mais uniquement la façon de les faire cohabiter.
Nous utiliserons ici des notions avancées de Box2d Web, telles que les liaisons (cf. ce tuto) ; et les fonctions de base d’EaselJS (que je présentais déjà dans ce tuto).
Settings
Librairies
Nous aurons besoin pour ce tutoriel des librairies suivantes :
Structure du projet
La structure du projet respecte celle des précédents tutoriels :
Nous avons donc :
- Les classiques fichiers
index.html
etstyle.css
, - Les librairies javascript utilisées et regroupées au sein d’un répertoire libs,
- Le répertoire img qui contient toutes les images utilisées,
- Le répertoire js, regroupant l’ensemble de nos fichiers javascript personnels :
- Le traditionnel fichier
gip.js
, le moteur du jeu, - Les classes utilitaires box2dUtils et easelJsUtils, dans les fichiers du même nom,
- Deux nouveaux fichiers
pig.js
etshortTree.js
qui nous servirons à créer de nouveaux objets graphiques dynamiques.
- Le traditionnel fichier
Attention ! Pour les fichiers box2dUtils.js
et easelJsUtils.js
, je vous conseille de réutiliser ceux des derniers tutos (respectivement ici et ici). Nous utiliserons dans ce tutoriel bon nombre des fonctions intégrées dans les classes utilitaires que nous avons créées et enrichies au cours des précédents tutos.
Play !
Préparer le terrain
Commençons par préparer l’environnement dans lequel nous allons travailler.
Fichier index.html
Dans un premier temps, éditons le fichier index.html
:
<!doctype html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Game in Progress - Box2d & EaselJS Tuto 1</title> <link rel="stylesheet" href="css/style.css" /> </head> <body> <div id="divCanvas"> <canvas width="800" height="600" id="gipCanvas"></canvas> <canvas width="800" height="600" id="box2dCanvas"></canvas> </div> <!-- Import JS --> <script src="libs/Box2dWeb-2.1.a.3.min.js"></script> <script src="libs/easeljs-0.7.1.min.js"></script> <script src="libs/jquery-1.9.0.min.js"></script> <!-- Classe utilitaire box2dWeb --> <script src="js/box2dutils.js"></script> <!-- Classe utilitaire easeljs --> <script src="js/easelJsUtils.js"></script> <!-- Moteur du jeu --> <script src="js/gip.js"></script> </body> </html>
Pour les besoins de ce tutoriel, et afin de bien comprendre ce qui se passe par la suite, nous créons deux canvas :
- Le premier, gipCanvas, sera utiliser pour le rendu visuel,
- Le second, box2dCanvas, servira pour le moteur physique.
Quant au reste, rien d’exceptionnel : on importe l’intégralité des fichiers css et js (librairies et fichiers personnels) dont nous aurons besoin.
Fichier css
Apportons ensuite quelques petites retouches au fichier style.css
:
/** Style appliqué sur la div contenant le canvas **/ #divCanvas { width: 800px; height: 600px; margin: auto; } /** Style du canvas "visuel" gip **/ #gipCanvas { background-color: #61B4CF; position: absolute; } /** Style du canvas "physique" box2d **/ #box2dCanvas { position: absolute; }
Rien d’extraordinaire ici non plus. On notera juste que les deux canvas sont déclarés en position: absolute afin qu’ils se superposent dans la div centrée au milieu de la page.
Préparer l’environnement physique
Maintenant que nous avons tout ce qu’il nous faut pour travailler sereinement, commençons par créer l’environnement physique. Nous allons travailler ici exclusivement dans le fichier gip.js
(le moteur du jeu).
Commençons par y déclarer les variables suivantes :
// Box2d Web var box2dCanvas; // canvas box2d var box2dUtils; // classe utilitaire box2d var context; // contexte 2d var SCALE = 30; // échelle var world; // world box2d var canvasWidth, canvasHeight; // dimensions du canvas
On retrouve les variables habituelles des tutos Box2dWeb : le canvas utilisés et ses différentes propriétés (les dimensions, le contexte 2D), une échelle, la classe utilitaire Box2dUtils et le monde box2d qui incarne l’environnement physique.
Puis ajoutons les fonctions suivantes :
// Initialisation $(document).ready(function() { init(); }); // Fonction d'initialisation this.init = function() { prepareBox2d(); // préparer l'environnement physique }; // Préparer l'environnement physique this.prepareBox2d = function() { box2dCanvas = $('#box2dCanvas').get(0); canvasWidth = parseInt(box2dCanvas.width); canvasHeight = parseInt(box2dCanvas.height); canvasPosition = $(box2dCanvas).position(); context = box2dCanvas.getContext('2d'); box2dUtils = new Box2dUtils(SCALE); world = box2dUtils.createWorld(context); // box2DWorld setWorldBounds(); // définir les limites de l'environnement }; // Créer les limites de l'environnement this.setWorldBounds = function() { // Créer le "sol" et le "plafond" de notre environnement physique ground = box2dUtils.createBox(world, 400, canvasHeight - 10, 400, 10, null, true, 'ground'); ceiling = box2dUtils.createBox(world, 400, -5, 400, 1, null, true, 'ceiling'); // Créer les "murs" de notre environnement physique leftWall = box2dUtils.createBox(world, -5, canvasHeight, 1, canvasHeight, null, true, 'leftWall'); leftWall = box2dUtils.createBox(world, canvasWidth + 5, canvasHeight, 1, canvasHeight, null, true, 'leftWall'); };
Si vous avez suivi les précédents tutoriels consacrés à Box2d Web, tout cela est sans secret pour vous. Nous procédons de la manière habituel :
- La fonction init est lancée au chargement de la page et se charge d’initialiser l’environnement,
- La fonction prepareBox2d récupère les informations propres au canvas box2d et se charge de préparer l’environnement physique :
- On instancie la classe utilitaire Box2dUtils, puis on crée l’environnement 2d via la méthode createWorld en lui spécifiant un contexte et une échelle,
- On définie ensuite les limites de l’environnement via l’appel à la fonction setWorldBounds
- La fonction setWorldBounds crée les premiers éléments physiques statiques de notre monde : les murs, le sol et le plafond qui servent à délimiter l’espace de jeu.
Tentons maintenant d’ajouter des éléments physiques dynamiques (mobiles). Pour ce faire, ajoutons la fonction suivante au fichier :
// Test d'ajout d'éléments "Ball" this.addBalls = function() { // Créer 30 éléments "Ball" placés aléatoirement dans l'environnement for (var i=0; i<30; i++) { box2dUtils.createBall(world, Math.random() * canvasWidth, Math.random() * canvasHeight - 400 / SCALE, 30, false, 'ball'); } };
Puis appelons là dans la fonction init :
// Fonction d'initialisation this.init = function() { prepareBox2d(); // préparer l'environnement physique addBalls(); // Ajout d'éléments physiques dynamiques };
La fonction addBalls se contente de créer 30 éléments « Balls » placés aléatoirement dans le canvas (ces éléments sont créés via la méthode createBall de notre classe utilitaire).
Si l’on teste maintenant notre code, on remarquera qu’il ne se passe pas grand chose. Et pour cause, notre environnement 2D est à priori correctement initialisé, mais il n’est jamais rafraîchi, et l’affichage n’est jamais mis à jour.
Souvenez-vous, dès le premier tutoriel, nous avions mis en place une « fonction magique » update chargée d’effectuer les calculs physiques et de mettre à jour l’affichage. A l’époque nous utilisions la fonction setInterval de l’objet window pour l’appeler de façon régulière.
Mais dans le dernier tuto, consacré à EaselJS, nous avons vu qu’il existait un objet Ticker dédier à ce genre de chose. Pourquoi ne pas, dans ce cas, en profiter et l’utiliser pour faire le boulot ?
C’est l’occasion pour nous d’intégrer quelques premiers éléments EaselJS à notre code. Dans un premier temps, déclarons une variable Ticker en début de fichier :
// EaselJS var Ticker = createjs.Ticker;
Puis ajoutons les fonction suivantes :
// Démarrer le ticker this.startTicker = function(fps) { Ticker.setFPS(fps); Ticker.addEventListener("tick", tick); }; // Mise à jour de l'environnement this.tick = function() { world.Step(1 / 15, 10, 10); world.DrawDebugData(); world.ClearForces(); };
Et enfin, ajoutons l’appel à la fonction startTicker en fin de notre fonction init :
// Fonction d'initialisation this.init = function() { prepareBox2d(); // préparer l'environnement physique addBalls(); // ajout d'éléments physiques dynamiques startTicker(30); // lancer le ticker };
Le principe de fonctionnement est strictement identique à celui que nous avions mis en place dans les précédents tutos :
- La fonction startTicker instancie un Ticker EaselJS, chargé d’effectuer les appels à la fonction tick à intrvalles réguliers (en fonction de la fréquence d’appel spécifiée),
- La fonction tick remplace notre ancienne fonction update et se charge des calculs physiques et de la mise à jour de l’affichage.
Voyons alors ce que ça donne en testant notre code dès à présent. Si tout va bien, vous devriez obtenir un résultat proche de celui-ci.
Bon, j’en conviens, rien d’exceptionnel pour le moment. Si ce n’est que l’on peut déjà trouver satisfaction à avoir réussi à faire fonctionner ensemble différents éléments provenant à la fois de Box2dWeb et d’EaselJS.
Le retour du cochon
Je sais parfaitement ce que vous vous dites arrivés à ce point : « Ok, c’est bien beau tout ça, mais pour le moment j’ai quand même un peu l’impression qu’on a pas avancé des masses… Quand est-ce qu’on fait des trucs jolis, avec des cochons et tout et tout ? » Et bien réjouissez-vous, car nous allons maintenant entrer dans le vif du sujet et voir comment remplacer ces horribles ronds roses tout moches par de superbes suidés tout mignons !
Fichier pig.js
Commençons par créer un nouveau fichier pig.js
dans le répertoire js
. Ce fichier contient la définition de la classe Pig représentant l’objet « Cochon ». Affectons lui un « constructeur » et initialisons son prototype :
(function(){ /** * Constructeur */ Pig = function(body, stage, scale) { this.body = body; // Body box2d this.stage = stage; // Stage EaselJS this.scale = scale; // Echelle this.skin = null; // Représentation graphique this.init(); // Initialiser le cochon }; /** * Classe Pig */ Pig.prototype = {}; }());
Pour le moment, le protoype reste vide, nous allons y revenir juste après. Penchons-nous tout d’abord sur le constructeur. Ce dernier prend trois paramètres en entrée :
- body : un objet Body (au sens Box2d Web du terme) qui représente la composante physique du cochon,
- stage : le Stage EaselJS dans lequel sera affiché le cochon,
- scale : l’échelle utilisée dans notre environnement.
La fonction se contente d’initialiser les différentes propriétés de l’objet avec les valeurs passées, puis d’initialiser la propriété « skin » (représentant la composante graphique du cochon). Elle appelle ensuite la méthode init que nous pouvons ajouter dès à présent dans le prototype de la classe Pig :
(function(){ init: function() { var bitmap = new createjs.Bitmap("img/pig.png"); // image associée // Redimensionner l'image bitmap.scaleX = 0.8; bitmap.scaleY = 0.6; // Repositionner le centre de l'image bitmap.regX = 45; bitmap.regY = 50; // Ajouter l'image au Stage this.stage.addChild(bitmap); // Appliquer la représentation graphique à l'objet this.skin = bitmap; }
Cette méthode permet d’initialiser un objet Pig. On effectue les actions suivantes :
- On instancie un objet Bitmap en utilisant la classe Bitmap de createJS, et en lui spécifiant l’image utilisée,
- On redimensionne l’image en largeur et en hauteur,
- On redéfinit le centre de l’image via les propriétés regX et refY. Ceci est obligatoire car Box2dWeb et EaselJS ne fonctionnent pas de la même manière. En effet, le premier crée un élément en plaçant directement son centre aux coordonnées X et Y fournies, tandis que le second utilise ces coordonnées pour définir le coin supérieur gauche de l’objet à dessiner. On fait donc en sorte que les deux bibliothèques se comprennent en plaçant les coordonnées au centre de l’objet,
- Enfin, on ajoute le Bitmap au Stage, puis on le conserve en l’affectant à la propriété skin de l’objet.
Fichier box2dUtils.js
Comme nous l’avons vu, l’objet « Pig » nécessite une propriété physique Body qui doit être créée par Box2d Web. Ajoutons alors la méthode createPig à notre classe utilitaire Box2dUtils :
(function(){ createPig : function(world, stage, x, y) { var body = this.createBall(world, x, y, 30, false, 'pig'); return new Pig(body, stage, this.SCALE); }
Cette fonction est si simple qu’elle se passe presque de commentaire. Elle réalise les actions suivantes :
- Crée un objet « Ball » qui servira de Body au cochon,
- Crée et retourne une nouvelle instance de la classe Pig, en lui passant le Body créé précédemment en paramètre.
Fichier gip.js
Voyons maintenant comment utiliser notre nouvelle classe Pig. Bien entendu, ça se passe dans gip.js
.
Commençons par déclarer un ensemble de nouvelles variables :
var gipCanvas; // canvas easeljs var stage; // stage easeljs var pigs = [];
Les deux premières variables sont consacrées à l’utilisation de la bibliothèque EaselJS. La troisième est un tableau qui servira par la suite à conserver les cochons que nous allons créer.
Puis ajoutons la fonction suivante :
// Préparer l'environnement graphique this.prepareStage = function() { // récupérer le canvas GIP gipCanvas = $('#gipCanvas').get(0); // créer le Stage stage = new createjs.Stage(gipCanvas); };
Si vous avez suivi le premier tutoriel consacré à EaselJS, aucun mystère pour vous ici. Sinon je vous invite à le faire. Cela sera également nécessaire pour la suite.
Pour faire simple, cette fonction permet de récupérer le canvas « GIP » utilisé pour l’affichage et de créer le Stage dans lequel EaselJS va travailler.
N’oublions pas, évidemment, d’appeler cette nouvelle fonction à l’initialisation de la page :
// Fonction d'initialisation this.init = function() { prepareStage(); // préparer l'environnement graphique prepareBox2d(); // préparer l'environnement physique addBalls(); // ajout d'éléments physiques dynamiques startTicker(30); // lancer le ticker };
Modifions maintenant la fonction addBalls créée précédemment. Nous la renommerons pour l’occasion addPigs, et lui apporterons les modifications suivantes :
// Ajout des cochons this.addPigs = function() { // Créer 30 "Pigs" placés aléatoirement dans l'environnement for (var i=0; i<30; i++) { var pig = box2dUtils.createPig(world, stage, Math.random() * canvasWidth, Math.random() * canvasHeight - 400 / SCALE); pigs.push(pig); // conserver les cochons dans un tableau } };
Pas de grand bouleversement cependant, nous nous contentons d’appeler la méthode createPig de box2dUtils en lieu et place de createBall. On en profite aussi pour stocker les cochons dans le tableau préalablement initialisé (ceci nous servira plus tard).
Enfin, modifions la fonction « tick » :
// Mise à jour de l'environnement this.tick = function() { // box2d world.Step(1 / 15, 10, 10); world.DrawDebugData(); world.ClearForces(); // easelJS stage.update(); };
On ajoute ici l’appel à la méthode update du stage. Cette dernière fera le nécessaire pour mettre à jour l’affichage des composants EaselJS dans le canvas.
Testons et rectifions le tir
Avant de lancer le test, vérifiez la présence du fichier pig.png
dans votre répertoire img
et pensez bien à importer le fichier pig.js
dans votre index.html
. Ensuite, vous devriez pouvoir observer comme moi le résultat suivant, et constater que… ça ne marche pas !
Pourtant, on ne semble pas loin de la solution. En effet, les cochons semblent bien ajoutés : on observe les Body (les objets Balls associés, qui eux fonctionnent à merveille) et un Bitmap dans le coin supérieur gauche du canvas.
Alors comment expliquer ce phénomène ? Et bien c’est en fait très simple. Il faut bien comprendre que, si Box2dWeb est capable de gérer lui même le comportement des éléments associés à son environnement physique (world), il n’en vas pas de même pour EaselJS. Lui se contente en effet d’afficher des éléments dans le Stage. Mais nous devons lui fournir les indications nécessaires à cet affichage. Il faut donc lui indiquer que les éléments graphiques ont bougé afin qu’il puisse effectuer correctement le rendu dans le canvas.
Fichier gip.js
Pour ce faire, il faut que l’on soit en mesure de modifier les propriétés des cochons à chaque mise à jour de l’affichage. Modifions pour cela la fonction tick du fichier gip.js
:
// Mise à jour de l'environnement this.tick = function() { // Mettre à jour les cochons for (var i=0; i < pigs.length; i++) { pigs[i].update(); } // box2d world.Step(1 / 15, 10, 10); world.DrawDebugData(); world.ClearForces(); // easelJS stage.update(); };
A chaque « tick » on parcourt désormais chaque cochon présent dans le tableau. Puis, pour chacun d’entre eux, on appelle sa fonction update chargée de mettre à jour ses propriétés.
Fichier pig.js
Puis, ajoutons cette fameuse méthode update au prototype de Pig dans le fichier pig.js
:
update: function() { // Redéfinir l'orientation this.skin.rotation = this.body.GetBody().GetAngle() * (180 / Math.PI); // Repositionner l'objet this.skin.x = this.body.GetBody().GetWorldCenter().x * this.scale; this.skin.y = this.body.GetBody().GetWorldCenter().y * this.scale; }
Cette méthode sera appelée à chaque mise à jour de l’affichage. Elle permet de redéfinir l’orientation (ou inclinaison) et la position de la skin (c’est-à-dire du Bitmap) en fonction de l’orientation et de la position du Body. Autrement dit, à chaque « tick », on récupère les informations physiques de l’objet (via son Body) puis on les applique à sa composante graphique pour modifier l’affichage en conséquence.
Et voilà, nous pouvons maintenant tester de nouveau et, normalement, ces quelques modifications ont permis de corriger le problème. Vous devriez être en mesure d’obtenir ce résultat.
Pour aller plus loin
L’objectif du tutoriel est maintenant atteint. Mais il est possible d’aller un peu plus loin en utilisant ce que nous avons appris lors des précédents tutos. Ainsi, je vous invite à expérimenter et tester par vous-mêmes l’ajout d’autres éléments graphiques ou de composantes physiques pour enrichir la petite démo que nous venons de mettre en place.
Les paragraphes suivants décrivent les ajouts qui ont été effectués pour parvenir au résultat final présenté au début de cet article. Je ne rentrerai pas dans les détails puisqu’il s’agit de notions ou fonctionnalités que nous avons déjà abordées. Je vous donnerai cependant les références aux tutoriels correspondant, et la consultation des sources devrait permettre de répondre à vos questions.
Planter le décor : ajout d’éléments graphiques
Dans un premier temps, on peut améliorer le visuel en ajoutant de nouveaux éléments graphiques et créer un décor.
J’ai réutilisé les fonctions existantes de la classe easelJsUtils (cf. EaselJS – Tuto 1 : Dessine moi un menu) pour :
- Dessiner les formes d’arrière plan (cercles et rectangles) pour habiller un peu le canvas et éviter que l’écran ne soit trop vide,
- Dessiner le sol sur lequel rebondissent les cochons,
- Ajouter des nuages qui se déplacent dans le ciel pour rendre l’ensemble un peu plus animé.
Collisions et liaisons : ajout d’éléments physique
Dans un seconde temps, il peut être intéressant de rajouter un peu de physique à l’ensemble pour obtenir quelque chose de plus dynamique et interactif. C’est également l’occasion de voir si tout ce qu’on a vu jusque là concernant box2d Web fonctionne toujours bien.
Ajout des buissons
On peut commencer par ajouter des éléments physiques statiques avec lesquels les cochons vont entrer en collisions. Pour ce faire, j’ai créé une nouvelle classe ShorTree très proche de la classe Pig existante :
/** Constructeur */ ShortTree = function(body, stage, x, y, scale) { this.body = body; // Body box2d this.skin = null; // Représentation graphique this.stage = stage; // Stage EaselJS this.scale = scale; // Echelle this.x = x; // Position X this.y = y; // Position y this.init(); // Initialiser le short tree }; /** Classe ShortTree*/ ShortTree.prototype = { init: function() { var bitmap = new createjs.Bitmap("img/shortTree.png"); // image associée // Positionner l'image bitmap.x = this.x; bitmap.y = this.y; // Repositionner le centre de l'image bitmap.regX = 50; bitmap.regY = 102; // Ajouter l'image au Stage this.stage.addChild(bitmap); // Appliquer la représentation graphique à l'objet this.skin = bitmap; } };
Cette dernière ne nécessite pas de méthode update. En effet, il s’agit d’un objet statique. Sa position et son orientation n’évolue pas dans le temps, il n’est donc pas nécessaire de mettre à jour l’affichage pour cet élément.
Interagir avec les cochons
Pour finir, on peut ajouter un peu d’interactivité en permettant à l’utilisateur de manipuler les cochons avec la souris. Pour ce faire, rien de plus simple. Il suffit de mettre en place une liaison de type MouseJoint, comme nous l’avons vu dans Box2d Web – Tuto 5 : liaisons dangereuses – Part 1. La classe box2dUtils possède déjà toutes les fonctions nécessaires.
Le mot de la fin
Avant de conclure, apportons une petite précision concernant l’utilisations des canvas de ce tutoriel. Nous avons en effet utilisé ici deux canvas différents (un pour le rendu graphique, l’autre pour le rendu physique). Cela présente un double intérêt :
- Un intérêt pédagogique premièrement. En effet, cela permet de bien comprendre que les deux aspects (physique et graphique) sont dissociés. Et que chaque librairie travaille de manière indépendante, en réalisant uniquement la tâche pour laquelle elle est prévue,
- Un intérêt pratique ensuite. En effet, cela permet de débugger plus facilement, en offrant la possibilité d’afficher en simultanée les composantes graphiques et les composantes physiques (via le debug de box2d Web).
Mais il est évidemment possible de n’utiliser qu’un seul et même canvas. Pour cela, il suffira d’adapter l’initialisation de l’environnement dans gip.js
et d’utiliser le même canvas (et son contexte) pour créer à la fois le Stage d’EaselJs et le b2World de box2d Web.
Game Over
Success
C’est la fin de ce tuto. Nous sommes parvenus à faire cohabiter Box2d Web et EaselJs, et ainsi à réaliser un environnement à la fois dynamique et chatoyant. Comme nous l’avons vu, ce n’était pas si compliqué. Et pourtant, cela ouvre la voie à de nombreuses possibilités ! A nous maintenant d’exploiter tout ça et, avec un peu d’imagination, de créer des univers plus complexes propres à la réalisation d’un jeu.
Comme d’habitude, je vous redonne le lien vers le résultat final, et vers les sources correspondantes.
Next level
Pour le prochain tutoriel, je ne suis pas encore bien décidé. Il y a tellement de choses à voir ! Je pense toutefois que nous irons faire un tour du côté d’EaselJs pour voir comment manipuler les Sprites et commencer à se pencher sur des composants graphiques un peu plus évolués.
L’étape déterminante du tutoriel que j’attendais depuis longtemps 🙂
Merci beaucoup, le code est très clair, bien documenté : tout simplement génial !
Merci beaucoup ! Ca fait toujours plaisir 🙂
Bravo pour ce tutorial, j’ai une question comment attacher une image au player, si tu pouvais m’éclairé ce serait génial, bonne continuation et merci d’avance !!
Salut David,
Désolé pour cette réponse tardive, mais je n’ai malheureusement pas beaucoup de temps à consacrer à ce projet en ce moment.
La réponse à ta question est EaselJS Spritesheet.
Deux tutos sont en cours de rédaction sur le sujet : le premier pour apprendre à manipuler les sprites, le second pour associer les sprites au Player.
J’espère pouvoir les publier prochainement.
En attendant, n’hésite pas à consulter la doc EaselJS sur le sujet. Elle est toujours très claire et les démos sont bien faites.
Bon courage et à bientôt !
Merci beaucoup Maxime ! J’attend ça avec impatience !
Pingback: EaselJS – Tuto 2 : sprite(no bull)sheets | Game in Progress
ddsf
Oups.. pardon pour mon précédent commentaire. Un grand merci à toi pour les tutoriels, j’ai commencé à apprendre le javascript il y a environ une semaine puis je suis tombé sur ton merveilleux site. Les explications sont claires, la rédaction est bonne, il n’y a ni trop peu ni trop d’explications, du beau travail en somme ! J’aimerais cependant ajouter quelques petites choses, j’ai voulu me lancer un peu plus après avoir fini ton tutoriels EaselJs/Box2d et je me suis rendu compte de quelques petits soucis :
– Lorsque l’on souhaite associer une shape avec un body comme dans ce tutoriel, dans la fonction easelJsUtils.createRoundRect on donne les coordonnées à la methode createjs.Graphics.drawRoundRect or lorsqu’on souhaite accéder aux coordonnées de cette shape, on obtient (0,0) ce qui provoque des différences de coordonnées entre la shape et le body. J’ai donc associé les coordonnées à la shape directement (avec shape.x et shape.y) et non plus à l’objet createjs.Graphics.
– Mon deuxième souci est du même ordre que le premier, lors de la création d’un body avec box2dUtils.createBox en spécifiant l’angle voulu, lorsqu’on souhaite accéder à cet angle avec body.getBody().getAngle(), l’angle obtenu ne correspond pas avec l’angle donné en paramètre en effet lors de la création de ce body on associe l’angle à sa fixture avec fixDef.shape.SetAsOrientedBox. J’ai donc associé l’angle directement au bodyDef (avec bodyDef.angle).
PS: Le premier problème n’apparaissait pas dans le dernier tutoriel grâce à l’utilisation de bitmaps.
Je signale ces problèmes pour ceux qui souhaiterait continuer après ce tutoriel, car il donne vraiment envie de s’y mettre.
Bon courage pour la suite, j’ai hâte de lire le prochain tutoriel ! 🙂