Créer des jeux avec Phaser version 040614 Brouillon David Roche Lycée G Fichet, Bonneville (74)



Documents pareils
Création d'un questionnaire (sondage)

VOS PREMIERS PAS AVEC TRACENPOCHE

Choisir entre le détourage plume et le détourage par les couches.

Les calques supplémentaires. avec Magix Designer 10 et autres versions

Création d'un site dynamique en PHP avec Dreamweaver et MySQL

DETERMINER LA LARGEUR DE PAGE D'UN SITE et LES RESOLUTIONS d'ecran

Créer un sondage en ligne

1. Introduction Création d'une macro autonome Exécuter la macro pas à pas Modifier une macro... 5

Premiers pas sur e-lyco

Microsoft Live Messenger

Introduction à Expression Web 2

pcon.planner 6 Préparer et présenter une implantation en toute simplicité

Initiation à html et à la création d'un site web

GUIDE D UTILISATION CRÉER SON SITE WEB - PROJET RESCOL

Date de diffusion : Rédigé par : Version : Mars 2008 APEM 1.4. Sig-Artisanat : Guide de l'utilisateur 2 / 24

2- Relation entre Writer et Calc dans le mailing

Création de maquette web

1 sur 5 10/06/14 13:10

Freeway 7. Nouvelles fonctionnalités

Utiliser CHAMILO pour le travail collaboratif

Votre site Internet avec FrontPage Express en 1 heure chrono

Pluridisciplinarité. Classe de BTS DATR

Création de site Internet avec Jimdo

Notice pour Visiteur du Site Perso

Manuel d utilisation NETexcom

BADPLUS V5 MANUEL D'UTILISATION. Imports de données joueurs à partir de la base fédérale en ligne Poona. Stéphan KIEFFER - Dominique BOSSERT

PHPWEBSITE -Tutoriel image

Automatisation d'une Facture 4. Liste Déroulante Remises Case à cocher Calculs

Petit guide à l'usage des profs pour la rédaction de pages pour le site Drupal du département

Edutab. gestion centralisée de tablettes Android

Dans la série. présentés par le site FRAMASOFT

Chapitre 4 Pierre, papier, ciseaux

Éditeur WordPress. Illustration 1. Kerniolen Pluneret Tel : Mob : info@formation-auray.fr

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

les Formulaires / Sous-Formulaires Présentation Créer un formulaire à partir d une table...3

Télécharger et Installer OpenOffice.org sous Windows

KompoZer. Composition du site : _ une page d'accueil : index.html. _ une page pour la théorie : theorie.html. _ une page pour les photos : photos.

Comment créer un diagramme de Gantt avec OpenOffice.org

Comment utiliser sa messagerie laposte.net

DÉCOUVERTE DE CAPTURE ONE

inviu routes Installation et création d'un ENAiKOON ID

1. Installation du Module

Utilisation d'un réseau avec IACA

Compte-rendu de projet de Système de gestion de base de données

Travaux pratiques avec RapidMiner

Notre projet est de réaliser un document

Google Tag Manager. «Vous ne verrez plus l'analytics de la même manière» par Ronan CHARDONNEAU

Capture Pro Software. Démarrage. A-61640_fr

Comment faire pour créer ses propres pages html?

Riddle Blocks. Jeu sous Android. - Yann Bertrand. Membres de l'équipe : - Clément Guihéneuf TS5. - Guillaume Renotton TS4

OpenOffice.org Présentation - Débuter. Distribué par Le projet OpenOffice.org

PREINSCRIPTION EN LIGNE

Optimiser pour les appareils mobiles

Septembre 2012 Document rédigé avec epsilonwriter

Utilisation du visualiseur Avermedia

Module ebay pour PrestaShop Guide du vendeur

Publipostage avec Open Office Writer et Open Office Calc

RapidMiner. Data Mining. 1 Introduction. 2 Prise en main. Master Maths Finances 2010/ Présentation. 1.2 Ressources

1 / Introduction. 2 / Gestion des comptes cpanel. Guide débuter avec WHM. 2.1Créer un package. 2.2Créer un compte cpanel

Créer un diaporama avec Open Office. Sommaire

Stockage du fichier dans une table mysql:

Utiliser le logiciel CALIBRE pour gérer vos documents et les convertir au format epub

Tutoriel : Feuille de style externe

Protosafe : un service en ligne d archivage de données médicales

Débuter avec OOo Base

Manuel d utilisation JeResilieMonContrat.com. pour l agent

SOMMAIRE 1 INTRODUCTION 4 2 GUIDE D UTILISATION ET TUTORIAUX VIDEOS EN LIGNE 4 3 CONTACTER VOTRE SUPPORT 4 4 RACCOURCIS CLAVIER 5

PROPOSITION DE RÉVISION DU CODE 6 Logiciel de vérification du non-roulement continu

Chapitre 1. Prise en main

Distinguer entre «Enregistrer» et «Sauvegarder»

Trier les ventes (sales order) avec Vtiger CRM

Comment bien démarrer avec. NetAirClub GUIDE ADMINISTRATEUR V1.5. Table des matières

Comment Définir une Plage de données Pour Utiliser Fonctions de Filtres et de Tris

Installation locale de JOOMLA SEPIA

Administration du site (Back Office)

PERF:C'est une page réservée aux vitesses de décollages (V1; VR;V2) où l'on entre manuellement, les indications sur les vitesses de sorties de volets

CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE

Dispositif Technique

Les Imprimantes EOLE 2.3. Documentation sous licence Creative Commons by-nc-sa - EOLE (http ://eole.orion.education.fr) révisé : Janvier 2014

Dessiner dans Galaad FRANÇOIS PALLUT

EXTRANET STUDENT. Qu'est ce que Claroline?

@telier d'initiation

Cours Apl 11 - Introduction à la gestion des écrans

PowerPoint offre trois modes d affichage principaux : le mode Normal, le mode Trieuse de diapositives et le mode Diaporama

TBI-DIRECT. Bridgit. Pour le partage de votre bureau. Écrit par : TBI Direct.

Comment Utiliser les Versions, les Modification, les Comparaisons, Dans les Documents

TABLEAU CROISE DYNAMIQUE

Personnalisation Fiche Annuaire

Utilisation de l éditeur.

Tutoriel d'utilisation du logiciel Thunderbird version 2.0

TUTORIEL IMPRESS. Ouvrir Impress cocher «présentation vierge», «suivant» cocher «écran», «suivant» cocher «standard», «créer»

SOMMAIRE AIDE À LA CRÉATION D UN INDEX SOUS WORD. Service général des publications Université Lumière Lyon 2 Janvier 2007

Avec PICASA. Partager ses photos. Avant de commencer. Picasa sur son ordinateur. Premier démarrage

Interface PC Vivago Ultra. Pro. Guide d'utilisation

Initiation à linfographie

TRAVAUX DIRIGES D'INFORMATIQUE INITIATION A LA MANIPULATION DE WINDOWS 98

Paginer les données côté serveur, mettre en cache côté client

Transcription:

Créer des jeux avec Phaser version 040614 Brouillon David Roche Lycée G Fichet, Bonneville (74)

Ce texte est sous licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International. Pour accéder à une copie de cette licence, merci de vous rendre à l'adresse suivante http://creativecommons.org/licenses/bysa/4.0/ ou envoyez un courrier à Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. Le titulaire des droits autorise toute utilisation de l œuvre originale (y compris à des fins commerciales) ainsi que la création d œuvres dérivées, à condition qu elles soient distribuées sous une licence identique à celle qui régit l œuvre originale.

À noter : La mise en œuvre de ces différentes activités demande des connaissances de base en programmation (il faut être un minimum "à l'aise" avec JavaScript). A l'origine ces activités sont destinées à des élèves de seconde ayant une pratique récente et limitée de la programmation, ne vous attendez donc pas à des "envolés techniques". L'idée n'est pas de former des développeurs professionnels, mais juste d'initier des élèves à une activité que je trouve très enrichissante. Ce document n'a pas la prétention d'être "la bible" de Phaser, j'ai essayé d'amener progressivement les élèves à s'approprier les notions de base nécessaires à la création d'un "petit jeu". Tous les exemples ont été testés "en local" avec Firefox (version 18.0.1). Pour les autres navigateurs, des problèmes sont toujours possibles "en local" notamment à cause de la "same origin policy".

1ère partie : les bases

Activité 1 Pour commencer Phaser? Qu'est ce que c'est? Phaser (site officiel : http://phaser.io/) est une bibliothèque JavaScript développée par Richard Davey. Elle permet une utilisation simplifiée de la balise HTML5 canvas (dessin, création de jeu, manipulation des pixels d'une image...). Pour en savoir plus sur la balise canvas, n'hésitez pas à consulter le site de Mozilla : site Mozilla. Comment utiliser Phaser? Phaser n'est pas un "logiciel", vous allez donc produire du code (en JavaScript). Votre code va nécessairement être appelé par une page HTML. À faire vous-même 1 Dans un dossier "Phaser", que vous aurez créé au préalable dans votre dossier personnel, créez les dossiers et fichier suivants : À faire vous-même 2 Vous allez maintenant télécharger la bibliothèque phaser en vous rendant sur le site : https://github.com/photonstorm/phaser Une fois sur le site, cliquez sur le bouton "Download ZIP".

"Dézipper" le fichier phaser-master.zip que vous venez de télécharger. Vous devriez alors vous retrouver avec un dossier phaser-master qui contient les dossiers et fichiers suivants : Dans le dossier "build", vous devriez trouver le fichier "phaser.min.js". Placez ce fichier dans le dossier "lib" que vous avez créé dans le "À faire vous-même 1". À faire vous-même 3 Afin d'avoir les différents éléments au centre de l'écran, nous allons créer un fichier "style.css" (ce fichier est à placer dans le dossier css que vous avez préalablement créé). Ce fichier est basique, mais vous pourrez évidemment l'enrichir comme bon vous semble. style.css h1{ text-align:center; #content{ margin:0 auto; width:800px; À faire vous-même 4 Créez un fichier (pour l'instant) vide que vous nommerez "script.js" et placez-le dans le dossier "javascript" que vous avez créé précédemment. À faire vous-même 5 Intéressons-nous au contenu du fichier index.html : Cette page HTML devra définir une balise div (qui "contiendra" la fenêtre du jeu) et lancer les

scripts JavaScript ("phaser.min.js" et "script.js"). Voici le code HTML minimum nécessaire à la bonne utilisation Phaser : code HTML de base (index.html) : <!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>titre de la page</title> <link rel="stylesheet" href="css/style.css"> <script src="lib/phaser.min.js"></script> </head> <body> <h1>phaser</h1> <div id='content'></div> </body> <script src="javascript/script.js"></script> </html> Quelques remarques sur ce code : Le "DOCTYPE" vous montre que nous sommes bien en HTML5. Nous "utilisons" bien le fichier "style.css" : "<link rel="stylesheet" href="css/style.css">" (remarquez que nous avons bien indiqué que notre fichier "style.css" se trouve dans le dossier "css" : "css/style.css"). Nous appelons bien les 2 fichiers JavaScript "<script src="lib/phaser.min.js"></script>" et "<script src="javascript/script.js">". Nous créons une balise div "<div id='content'></div>" qui contiendra la fenêtre de jeu. La structure que nous venons de mettre en place (dossier "phaser") pourra être "copier-coller" à chaque fois que vous commencerez à coder un nouvel exemple. Dans la suite, seul le fichier "script.js" sera modifié. Premier code À faire vous-même 6 Placez le code ci-dessous dans le fichier script.js et testez le programme en ouvrant le fichier index.html avec votre navigateur. var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ function create(){ function update(){ Comme vous pouvez le constater, il ne se passe pas grand-chose : le titre défini dans le fichier index.html (Phaser) est bien présent à l'écran. De plus nous avons un "beau" carré noir qui s'affiche juste en dessous de ce titre (si ce n'est pas le cas, il se pourrait que vous ayez fait une erreur quelque part, reprenez le processus depuis le début afin de vérifier que vous n'avez rien oublié). Pourtant la structure de base d'un projet Phaser est déjà présente, reprenons le contenu du fichier script.js ligne par ligne : "var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); "

Nous définissons un objet game à l'aide du constructeur Phaser.Game. Ce constructeur prend 5 paramètres : "800" correspond à la largeur de fenêtre de jeu "600" correspond à la hauteur de fenêtre de jeu "Phaser.AUTO" il existe plusieurs méthodes d'affichage, nous "demandons" ici à Phaser d'en choisir une pour nous (il prendra la méthode la plus approprier à notre environnement), vous n'aurez sans doute jamais à modifier ce paramètre. "'content'" correspond à l'identifiant (id) de la balise div que nous avons mise en place (voir le fichier index.html), je vous rappelle que c'est cette balise div qui va accueillir la "fenêtre de jeu". "{preload: preload, create: create,update:update" ce dernier paramètre est un objet JavaScript qui contient le nom des fonctions de bases utilisées dans Phaser, ici aussi, vous ne devriez pas avoir à modifier cet argument. Nous définissons ensuite 3 fonctions qui sont, comme dit plus haut, les fonctions de base de Phaser : "function preload" dans cette fonction nous nous occuperons des éléments devant être "chargés" avant le début du jeu, par exemple les images ou les sons. "function create" tout les éléments du jeu seront créés dans cette fonction. "function update" il existe un élément très important dans la création des jeux vidéo : le nombre d'images par seconde (Frame per second en anglais soit, FPS). En effet, un jeu vidéo est une suite d'images fixes affichées à une cadence plus ou moins élevée (comme le cinéma). Si la cadence d'affichage de ces images est supérieure ou égale à environ 30 images par seconde, cela donnera "l'illusion du mouvement" (pour le cinéma c'est 24 images par seconde). La fonction update sera appelée à chaque fois qu'une nouvelle image sera affichée. Par exemple si nous avons 30 images par seconde, la fonction update sera exécutée toutes les 0,033 seconde (1/30 = 0,033). Il se peut que pour l'instant tout cela ne soit pas très clair pour vous, mais nous verrons dans la prochaine activité des exemples qui, je pense, clarifieront les choses.

Activité 2 Afficher un sprite D'après Wikipédia : Sprite est un mot anglais possédant plusieurs significations. Il est notamment employé dans les domaines de l'infographie et du jeu vidéo, où sprite désigne une image en deux dimensions qui peut être déplacée par rapport au fond de l'écran. Commençons simple, affichons un sprite : À faire vous-même 7 Saisissez le code suivant dans le fichier script.js et testez cet exemple var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.image('smiley','asset/smiley.png'); function create(){ monsprite=game.add.sprite(0,0,'smiley'); function update(){ Nous avons uniquement ajouté 2 lignes : "game.load.image('smiley','asset/smiley.png'); " nous commençons par charger une image que nous nommons "smiley", cette image doit se trouver dans le dossier "asset" et se nomme "smiley.png". Comme vous pouvez le constater, cette ligne se trouve bien dans la fonction "preload" ce qui nous assure que la suite du programme ne sera pas exécutée avant que l'image soit complètement chargée. "monsprite=game.add.sprite(0,0,'smiley');" nous créons un objet de type sprite à l'aide de la méthode "game.add.sprite". Cette méthode prend 3 paramètres : la coordonnée x du sprite, la coordonnée y du spirite (vous devez savoir que l'origine du repère se trouve en haut et à gauche de la fenêtre de jeu) et le nom de l'image utilisée (ici "smiley"). Cet objet sprite est "rangé" dans la variable "monsprite".

À faire vous-même 8 Modifier les valeurs des paramètres "coordonnée x du sprite et "coordonnée y du sprite" afin de placer l'image au centre de la fenêtre de jeu. Vous avez peut-être remarqué que si vous choisissez 400 pour la coordonnée x et 300 pour la coordonnée y, le sprite n'est pas au centre de l'écran alors qu'il devrait l'être. Pourquoi? Par défaut "coordonnée x du sprite" et "coordonnée y du sprite" sont les coordonnées du coin "hautgauche" du sprite. Pour que ce soit le centre du sprite qui soit pris en compte et non plus le coin "haut-gauche", il suffit d'ajouter la ligne suivante : monsprite.anchor.setto (0.5,0.5) ; À faire vous-même 9 Modifier le code précédent pour que le sprite s'affiche au centre de l'écran. Il est possible de modifier les coordonnées du sprite après sa création. Si le sprite est créé aux coordonnées (0,0) ("monsprite=game.add.sprite(0,0,'smiley');"), vous pouvez, par la suite, modifier sa position comme bon vous semble, par exemple vous placerez le sprite "monsprite" aux coordonnées (200,150), simplement en écrivant : "monsprite.x=200" et "monsprite.y=150" N.B. Nous utilisons les attributs x et y de l'objet "monsprite". À faire vous-même 10 Modifier le code précédent afin de créer un sprite aux coordonnées (0,0). Une fois ce sprit créé, il vous faudra le déplacer aux coordonnées (200,150). Nous venons de voir 2 attributs d'un objet de type sprite (x et y). Il existe un autre attribut extrêmement intéressant, l'attribut angle. Comme vous vous en doutez sans doute, cet attribut angle nous permettra de faire faire à notre sprite des rotations : "monsprite.angle=45" fera tourner le sprite de 45 Mais une question doit tout de suite vous venir à l'esprit : Où se trouve l'axe de rotation? La réponse est simple : par défaut, dans le coin "haut-gauche" du sprite. Si vous désirez avoir l'axe de rotation au centre du sprite (faire faire au sprite des rotations sur lui même), il vous faudra, ici aussi, ajouter la ligne : "monsprite.anchor.setto(0.5,0.5) ;" (inutile de l'ajouter 2 fois, une seule fois suffit).

À faire vous-même 11 Écrire un programme permettant d'afficher un sprite. Faites faire à ce sprite une rotation de 45, dans un premier temps avec l'axe de rotation placé dans le coin "haut-gauche" du sprite, puis dans un deuxième temps avec l'axe de rotation placé au centre du sprite. À faire vous-même 12 Modifier le code que vous venez d'écrire pour que le sprite ait des coordonnées et un angle de rotation aléatoires (le sprite devra "rester" dans la fenêtre de jeu et l'angle de rotation devra être compris entre 0 et 90 degrés) Pour vous aider : la méthode "Math.random()" renvoie un nombre aléatoire compris entre 0 et 1 (comment obtenir un nombre aléatoire compris entre 0 et 800?). La méthode "Math.floor()" retourne le plus grand entier inférieur ou égal à la valeur donnée en paramètre, exemple, "Math.floor(2.9)" renvoie 2. J'ajoute que les coordonnées et l'angle doivent être des entiers.

Activité 3 Déplacer un sprite Pour l'instant, tout cela est un peu "statique". Dans cette activité, nous allons donc apprendre à déplacer notre sprite. Dans un premier temps le sprite va traverser l'écran de gauche à droite. Comment déplacer le sprite? À faire vous-même 13 Écrire un programme permettant de déplacer le sprite horizontalement de la gauche vers la droite. Pour vous aider : Déplacer le sprite, c'est modifier ses coordonnées à chaque nouvelle image. Par exemple, la coordonnée x du sprite peut augmenter de 2 pixels à chaque image. Cet exemple étant relativement difficile et tellement important pour la suite qu exceptionnellement je vous donne ci-dessous la solution : var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.image('smiley','asset/smiley.png'); function create(){ monsprite=game.add.sprite(0,0,'smiley'); monsprite.anchor.setto (0.5,0.5) ; monsprite.x=10; monsprite.y=300; function update(){ monsprite.x=monsprite.x+2; À faire vous-même 14 Modifier le programme pour que le sprite donne l'impression de rouler À faire vous-même 15 Modifier le programme pour que le sprite ne disparaisse pas quand il arrive au bord de la fenêtre de jeu. Il doit "rebondir" sur les bords. À faire vous-même 16 Le smiley doit maintenant se déplacer en "diagonale" (modification des coordonnées x et de y). Il doit toujours "rebondir" sur le bord de la fenêtre de jeu (de façon réaliste).

Activité 4 Gestion du clavier Le but de cette activité est de permettre à l'utilisateur d'interagir avec le programme par l'intermédiaire du clavier. Avec Phaser il est très facile de détecter quand une touche est "enfoncée" : La méthode "isdown" renvoie true si la touche passée en paramètre de la méthode "isdown" est enfoncée :) "game.input.keyboard.isdown(phaser.keyboard.a)" renvoie true si la touche A est enfoncée (et false si la touche A n'est pas enfoncée). À faire vous-même 17 Testez et analysez le programme suivant : var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.image('smiley','asset/smiley.png'); function create(){ monsprite=game.add.sprite(0,0,'smiley'); monsprite.anchor.setto (0.5,0.5) ; monsprite.x=400; monsprite.y=300; function update(){ if (game.input.keyboard.isdown(phaser.keyboard.a)==true){ monsprite.angle=monsprite.angle+5 Comme vous pouvez le constater, le sprite tourne quand la touche A est enfoncée. Notez que le "if" qui teste si la touche A est enfoncée se trouve dans la fonction "update" : il faut que "le test de l'appui sur la touche A" soit effectué à chaque image. Pour tester les flèches du clavier : flèche droite : "Phaser.Keyboard.RIGHT" flèche gauche : "Phaser.Keyboard.LEFT" flèche haut : "Phaser.Keyboard.UP" flèche bas: "Phaser.Keyboard.DOWN"

À faire vous-même 18 Faire les modifications nécessaires pour permettre à l'utilisateur de déplacer le smiley dans les 4 directions (gauche, droite, haut et bas) à l'aide des flèches du clavier. N.B. il est évidemment possible d'utiliser les touches correspondants à des chiffres, par exemple la touche 1 s'écrira : "Phaser.Keyboard.ONE". À faire vous-même 19 Il y aura à l'écran 2 sprites (2 smileys) : un contrôlé par le joueur (touches clavier) et un qui décrira une trajectoire rectiligne uniforme. Le joueur devra "attraper" le plus rapidement possible le 2e smiley (l'ennemi). Pour vous aider : on pourra considérer que l'ennemi est "capturé" si la distance entre les centres des smileys est inférieure à une certaine valeur que vous devrez déterminer. Si le centre de l'objet1 a pour coordonnées x1,y1 et que l'objet2 a pour coordonnées x2,y2, d'après le théorème de Pythagore, la distance entre les centres d est égale à (x2 x1) 2 +( y2 y1) 2

Activité 5 Gestion de la souris Après le clavier, occupons-nous de la souris. Il est très simple de rendre un sprite "cliquable". Si nous nommons notre sprite "monsprite", il suffit d'écrire : monsprite.inputenabled=true ; Ensuite pour que le sprite "réagisse" au clic de souris, il faudra écrire : monsprite.events.oninputdown.add(mafonction, this) ; Nous mettons en place ici la notion d'événement : le sprite est "surveillé" en permanence (inutile de mettre cette ligne dans la fonction update). Le "oninputdown" correspond au clic de souris. En cas de clic de souris sur le sprite "monsprite", la fonction "mafonction" sera exécutée (1 er paramètre de la méthode "add"). Le second paramètre de la méthode "add", this, correspond à l'objet qui a "subi" le clic, c'est à dire "monsprite", mais cela n'a pas une grande importance pour nous (du moins pour l'instant). À faire vous-même 20 Analysez le programme et essayez de prévoir ce qui se passera quand l'utilisateur cliquera sur le sprite "monsprite". var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.image('smiley','asset/smiley.png'); function create(){ monsprite=game.add.sprite(400,300,'smiley'); monsprite.anchor.setto (0.5,0.5); monsprite.inputenabled=true; monsprite.events.oninputdown.add(monclic,this); function monclic(){ alert ("Cela fonctionne! :-)") function update(){ Vérifiez que l'hypothèse que vous avez émise ci-dessus est valable en testant le programme.

À faire vous-même 21 Sachant qu'il est possible de "tuer" un sprite (le faire disparaître) grâce à la méthode kill() (pour "tuer" le sprite "monsprite" on écrira "monsprite.kill()"), sachant qu'il est possible de "ramener à la vie" un sprite préalablement tué à l'aide de la méthode revive() ("monsprite.revive()") et sachant enfin qu'il est possible de connaître l'état actuel d'un sprite avec le paramètre "alive" (si "monsprite.alive" est égal à true alors le sprite est "vivant", si "monsprite.alive" est égal à false alors le sprite est (actuellement) "mort", écrivez un programme qui : - affichera un sprite au centre de l'écran - en cas de clic sur ce sprite le fera disparaître - en cas d'appui sur la touche A le fera réapparaître à une position aléatoire Il est possible grâce à la souris de déplacer le sprite dans la fenêtre de jeu (faire ce que l'on appelle un "drag and drop") en cliquant sur le sprite, en maintenant le clic pendant le déplacement et en relâchant le clic une fois la nouvelle position atteinte. Pour cela il suffit d'ajouter 2 lignes : "monsprite.inputenabled=true; " (comme pour le clic de souris) "monsprite.input.enabledrag(true); " À faire vous-même 22 Écrivez un programme qui affichera un sprite au centre de l'écran. Ce sprite devra être "déplaçable" par "drag and drop".

2 e partie : pour aller plus loin...

Activité 6 Animation des sprites Beaucoup de jeux utilisent des sprites animés pour créer les animations des personnages. Avec ou sans Phaser, la technique d'animation est toujours la même. Nous utiliserons le principe du dessin animé : faire défiler des images fixes. Voici les séries d'images fixes que nous allons utiliser dans ce chapitre. Comme vous pouvez le constater, cette image au format png, va nous permettre de gérer plusieurs animations. Par exemple, si nous prenons les 6 premières représentations de Sonic (en partant en haut à gauche), il est évident que leur enchaînement rapide à l'écran donnera l'impression que Sonic est en train de marcher vers la droite. Sans Phaser, le code à écrire pour mettre en place cette animation serait relativement long. Avec Phaser, c'est un jeu d'enfant. Pour commencer, nous allons (par la pensée) découper notre image.png (que nous appellerons désormais "spritesheet") en petites vignettes de 48 pixels de large et 48 pixels de haut. À l'aide d'un logiciel de dessin standard, vérifiez que chaque petite vignette contient bien un dessin de Sonic. Ces vignettes vont être ensuite numérotées en partant d'en haut à gauche. Par exemple, la première vignette de la deuxième ligne portera le numéro 11 (la première vignette de la première ligne porte le numéro zéro).

À faire vous-même 23 Saisissez, analysez et testez ce code afin de comprendre l'utilisation des sprites animés (n'oubliez pas de placer le fichier "sonicsprites.png" dans le dossier asset). var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.spritesheet('spritesonic','asset/sonicsprites.png',48,48); function create(){ sonic=game.add.sprite(400,300,'spritesonic'); sonic.anchor.setto (0.5,0.5); sonic.animations.add('marche',[0,1,2,3,4,5],10,true); sonic.play('marche'); function update(){ Remarques sur ce code : Dans la fonction "preload", nous ne chargeons plus une image, mais un spritesheet (série d'image composant les différentes animations) : "game.load.spritesheet('spritesonic','asset/sonicsprites.png',48,48); " le premier paramètre "'spritesonic'" est le nom du spritesheet, le second "'asset/sonicsprites.png'" correspond au chemin vers le fichier "sonicsprites.png", ensuite nous avons la largeur des vignettes "48" et enfin la hauteur des vignettes "48". "sonic=game.add.sprite(400,300,'spritesonic');" rien de nouveau, nous créons un sprite comme dans les exemples précédents. "sonic.animations.add('marche',[0,1,2,3,4,5],10,true); " cette ligne nous permet de créer une animation, voici les différents paramètres de la fonction add : "'marche'" : le nom de l'animation "[0,1,2,3,4,5]" : tableau contenant les index de position des images composant l'animation. Notre animation "'marche'" sera composée des 6 premières vignettes du spritesheet. "10" : vitesse de l'animation => nous aurons ici 10 images par seconde. "true" : l'animation sera jouée en boucle (mettre à false si vous voulez que l'animation ne soit jouée qu'une fois). "sonic.play('marche'); " : permets de jouer l'animation À faire vous-même 24 Sachant qu'il est possible : d'afficher une image fixe issue spritesheet : "sonic.frame=6;" affichera l'image n 6 (attention, rappelez-vous que la première image du spritesheet a le numéro 0) de stopper toutes les animations en cours avec "sonic.animations.stop();" Écrivez un programme permettant de mettre en place plusieurs animations. L'utilisateur pourra changer d'animation. Par exemple : la touche A permettra de "jouer" l'animation "marche" (image 0 à 5), la touche B lancera l'animation "attente" (image 7 à 10), la touche C arrêtera les animations et affichera une image fixe (image 6). Au lancement du programme, l'image fixe n 6 sera affichée. Et si maintenant nous voulons faire courir Sonic de la droite vers la gauche? Visiblement, nous n'avons pas les vignettes adaptées! Phaser propose une solution relativement simple : "retourner" le sprite

À faire vous-même 25 Saisissez, analysez et testez ce code var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.spritesheet('spritesonic','asset/sonicsprites.png',48,48); function create(){ sonic=game.add.sprite(400,300,'spritesonic'); sonic.anchor.setto (0.5,0.5); sonic.animations.add('marche',[0,1,2,3,4,5],10,true); sonic.frame=6; function anim(){ if (game.input.keyboard.isdown(phaser.keyboard.left)){ sonic.scale.x=-1; sonic.play('marche'); else if (game.input.keyboard.isdown(phaser.keyboard.right)){ sonic.scale.x=1; sonic.play('marche'); function update(){ anim(); Commentaires sur le code : nous créons une animation "marche" : "sonic.animations.add('marche', [0,1,2,3,4,5],10,true);" au lancement du programme, l'image n 6 est affichée (image fixe) : "sonic.frame=6; " à chaque image, nous appelons la fonction "anim" contenu de la fonction "anim" : en cas d'appui sur la flèche gauche, nous "inversons" le sprite ("sonic.scale.x=-1; ") et nous lançons l'animation marche. Le raisonnement est identique en cas d'appui sur la flèche droite : le sprite est "remis à l'endroit" ("sonic.scale.x=1; "). À faire vous-même 26 Sonic doit pouvoir se déplacer vers la droite et vers la gauche (utilisation des flèches du clavier). L'animation devra être adaptée à la situation (marche vers la gauche, marche vers la droite, attente en regardant vers la gauche, attente en regardant vers la droite)

Activité 7 Un peu de physique... Il existe beaucoup de bibliothèques JavaScript permettant de créer des jeu (ou simulation) en 2D, mais la bibliothèque Phaser possède un avantage énorme par rapport à beaucoup de ses "concurrentes" : elle intègre un moteur physique. Un moteur physique va vous permettre de gérer facilement, et surtout de manière réaliste, différents aspects : la vitesse d'un sprite, l'accélération d'un sprite, la gravitation, les collisions et les rebonds (cette liste est loin d'être exhaustive). Dans un premier temps, il faut préciser le moteur physique qui sera utilisé (Phaser en propose plusieurs, mais nous n'étudierons qu'un) : "game.physics.startsystem(phaser.physics.arcade) ;" Si nous voulons que le moteur physique prenne en charge un sprite (monsprite par exemple), il faudra écrire : "game.physics.enable(monsprite,phaser.physics.arcade);". Repartons d'un exemple simple : À faire vous-même 27 Saisissez, analysez et testez ce code var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.image('smiley','asset/smiley.png'); function create(){ game.physics.startsystem(phaser.physics.arcade); monsprite=game.add.sprite(400,300,'smiley'); monsprite.anchor.setto (0.5,0.5); game.physics.enable(monsprite,phaser.physics.arcade); monsprite.body.velocity.x=40; function update(){ Plusieurs remarques sur ce programme : Vous noterez la présence des 2 lignes évoquées ci-dessus : "game.physics.startsystem(phaser.physics.arcade); " qui active le moteur physique pour le "jeu en général" et "game.physics.enable(monsprite,phaser.physics.arcade); " qui active le moteur physique pour le sprite "monsprite" en particulier. "monsprite.body.velocity.x=40;" : au moment de sa création (puisque nous sommes dans la fonction "create"), le sprite se voit attribuer une vitesse selon l'axe x de 40 pixels par seconde. J'attire votre attention sur deux aspects : "monsprite" possède un nouvel attribut que n'avions pas encore rencontré : "body" : en fait, tout ce qui touche à la physique ne concernera jamais directement l'objet

"monsprite", mais son attribut "body". La fonction update est vide, il n'est plus utile d'incrémenter à chaque image la coordonnée x du sprite. Comme "monsprite" possède, dès sa création, une vitesse selon x et que le principe de l'inertie nous apprend qu'un objet préalablement en mouvement rectiligne uniforme restera en mouvement rectiligne uniforme tant que les forces qui s'exercent sur lui se compensent, le résultat obtenu est tout à fait logique. À faire vous-même 28 Sachant qu'il existe aussi un paramètre "monsprite.body.velocity.y", modifier le programme précédent pour que le sprite se déplace en diagonale. N.B. Il est aussi possible de modifier la vitesse de rotation du sprite : "monsprite.body.angularvelocity" Pour l'instant le sprite quitte l'écran, mais il est possible de rendre les bords de la fenêtre de jeu "imperméable" au sprite "monsprite" en ajoutant la ligne suivante : "monsprite.body.collideworldbounds = true ;" À faire vous-même 29 Modifier le code précédent pour que le sprite ne sorte plus de l'écran. Comme vous pouvez le constater le sprite se coince au bord de l'écran, il est possible de lui "donner" la capacité de rebondir en ajoutant la ligne : "monsprite.body.bounce.set(1)" le 1 du "set(1)" correspond à ce que l'on appelle en physique un choc élastique (le choc s'effectue sans perte d énergie). Si vous diminuez cette valeur, à chaque choc contre les "parois" le smiley perdra un peu d'énergie et finira par s arrêter. Un "set(0)" correspond à la situation vu précédemment : le smiley se bloque contre les parois dès le premier choc. Il est possible de différencier l'élasticité du choc selon x et selon y, pour cela il suffira par exemple d'écrire : "monsprite.body.bounce.x=0.5" et "monsprite.body.bounce.y=0.7" À faire vous-même 30 Modifier le code précédent pour que le sprite rebondisse sur les bords (vous essayerez avec plusieurs valeurs "d'élasticités du choc"). Une des choses les plus compliquées à gérer dans un jeu est la détection des collisions. Ici aussi, le moteur physique de Phaser va vous êtes d'un grand secours. Imaginons 2 sprites : "joueur" et "ennemi", pour gérer les collisions entre ces 2 sprites, il suffira d'écrire : "game.physics.arcade.collide(joueur, ennemi, mafonction);" Je pense que vous aurez compris par vous même que "mafonction" est la fonction qui sera appelée en cas de collision entre les sprites "joueur" et "ennemi". "mafonction" pourra prendre 2 paramètres : les 2 sprites concernés par la collision. Attention : la collision devant être testé à chaque image la méthode "game.physics.arcade.collide" vu ci-dessus devra se trouver dans la fonction "update".

À faire vous-même 31 Nous allons reprendre un "jeu" déjà programmé auparavant : Il y aura à l'écran 2 sprites (2 smileys) : un contrôlé par le joueur (touches clavier) et un qui décrira une trajectoire rectiligne uniforme (rebond sur les bords). Le joueur devra "attraper" le plus rapidement possible le 2e smiley (l'ennemi). Dans cette deuxième version, il faudra utiliser tout ce que nous venons de voir : vitesse, collision et rebonds contre les bords. "Interdit" d'utiliser l'incrémentation des coordonnées ("joueur.x=joueur.x+2;"). Je précise aussi que la capture de "l'ennemi" devra entraîner l'explosion de ce dernier. Pour ce faire vous pourrez utiliser le spritesheet suivant : pour info : taille des vignettes 64x64 Il est possible de gérer les collisions sans utiliser la fonction "mafonction" : "game.physics.arcade.collide(joueur,ennemi);" si nos 2 sprites se nomment "joueur" et "ennemi". Il est même possible de modifier la masse des sprites avec l'attribut "ennemi.body.mass" À faire vous-même 32 Saisissez, analysez et testez ce code (n'hésitez pas à modifier la masse des sprites) var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.image('smiley','asset/smiley.png'); function create(){ game.physics.startsystem(phaser.physics.arcade); joueur=game.add.sprite(400,300,'smiley'); joueur.anchor.setto (0.5,0.5); game.physics.enable(joueur,phaser.physics.arcade); joueur.body.collideworldbounds = true ; joueur.body.bounce.set(0.5); joueur.body.mass=100; ennemi=game.add.sprite(20,300,'smiley'); ennemi.anchor.setto (0.5,0.5); game.physics.enable(ennemi,phaser.physics.arcade); ennemi.body.collideworldbounds = true ; ennemi.body.velocity.x=300; ennemi.body.velocity.y=0; ennemi.body.bounce.set(0.5); ennemi.body.mass=10; function update(){ game.physics.arcade.collide(joueur,ennemi);

Pour terminer avec cette partie, vous devez savoir que le moteur physique gère aussi très bien la gravitation. Pour qu'un sprite "subisse" la gravité, vous devez ajouter la ligne suivante : "monsprite.body.gravity.set(0,50);" le sprite "monsprite" subira la gravitation, les 2 paramètres "(0,50)" correspondent aux coordonnées du vecteur intensité de la pesanteur. Si vous n'êtes pas familier avec la notion de "vecteur intensité de la pesanteur", vous devez juste comprendre que le premier paramètre devra rester à zéro si vous voulez que votre sprite tombe verticalement. Plus le deuxième paramètre est grand, plus le sprite tombera "vite". À faire vous-même 33 Créez un programme permettant d'afficher un sprite en haut de la fenêtre de jeu. Ce sprite devra être sensible à la gravitation (et donc tomber) et devra rebondir sur le "sol" (bas de la fenêtre de jeu). À faire vous-même 34 Écrivez un programme permettant d'afficher un sprite. Ce sprite sera positionné sur le "sol" (bas de la fenêtre de jeu). Un appui sur la flèche "HAUT" du clavier devra le faire "sauter". Le saut devra être réaliste : impossible de déclencher un nouveau saut tant que le sprite n'est pas revenu au sol.

Activité 8 Les groupes Vous aurez sans doute, un jour ou l'autre, besoin d'afficher plusieurs sprites "identiques" (même comportement d'un point de vue physique, mais n'ayant pas forcement les mêmes coordonnées d'origines). Afin de vous permettre de gérer facilement cette multitude sprites, Phaser propose la notion de groupe. À faire vous-même 35 Saisissez, analysez et testez ce code var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.image('smiley','asset/smiley.png'); function create(){ mongroupe=game.add.group(); for (var i=0;i<10;i++){ mongroupe.create(750*math.random(), 550*Math.random(),'smiley'); function update(){ Analyse du code : "mongroupe=game.add.group(); " crée un nouveau groupe "mongroupe.create(750*math.random(), 550*Math.random(),'smiley'); " ajoute un smiley au groupe. Le premier paramètre de la méthode "create" correspond à la coordonnée x du nouveau sprite, le deuxième à la coordonnée y du sprite nouvellement créé, enfin, le troisième correspond à l'image à associer au sprite. Il est évidemment possible d'utiliser le moteur physique avec les éléments d'un groupe. À faire vous-même 36 Saisissez, analysez et testez ce code var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.image('smiley','asset/smiley.png'); function create(){ game.physics.startsystem(phaser.physics.arcade); mongroupe=game.add.group(); for (var i=0;i<10;i++){ s=mongroupe.create(750*math.random(), 550*Math.random(),'smiley'); game.physics.enable(s,phaser.physics.arcade); s.body.gravity.set(0,100);

s.body.collideworldbounds=true; s.body.bounce.set(0.5); function update(){ Analyse du code : nous utilisons, à l'intérieur de la boucle "for", une variable "s". Cette variable nous permet d'activer le moteur physique pour tous les sprites du groupe comme nous l'aurions fait pour un seul sprite. Il est aussi possible de gérer les collisions entre membres du même groupe en ajoutant : "game.physics.arcade.collide(mongroupe);" avec "mongroupe" le nom du groupe concerné. Notez qu'il possible, ici aussi, d'ajouter une fonction qui sera appelée en cas de collision. À faire vous-même 37 Saisissez, analysez et testez ce code var game = new Phaser.Game(800,600,Phaser.AUTO,'content',{preload: preload, create: create,update:update); function preload(){ game.load.image('smiley','asset/smiley.png'); function create(){ game.physics.startsystem(phaser.physics.arcade); mongroupe=game.add.group(); for (var i=0;i<10;i++){ s=mongroupe.create(750*math.random(), 550*Math.random(),'smiley'); game.physics.enable(s,phaser.physics.arcade); s.body.gravity.set(0,100); s.body.collideworldbounds=true; s.body.bounce.set(0.8); function update(){ game.physics.arcade.collide(mongroupe); Enfin il est possible de gérer les collisions entre les membres d'un groupe et un sprite : "game.physics.arcade.collide (joueur,groupeennemi, mafonction);" : la fonction "mafonction" sera exécutée à chaque fois qu'une collision entre le sprite "joueur" et un des sprites membres du groupe "groupeennemi" aura lieu. À faire vous-même 38 Modifier le "jeu" programmer précédemment (À faire vous-même 31) pour avoir, non plus un ennemi à capturer, mais dix.

Activité 9 Pour aller encore plus loin... Nous n'avons vu qu'une infime partie des possibilités de Phaser. Je vous conseille, pour poursuivre seul votre découverte de cette fabuleuse bibliothèque deux liens : la documentation officielle qui, même si elle est austère, vous sera d'une grande aide : http://docs.phaser.io/ le deuxième lien que je trouve très intéressant, vous présentera des dizaines d'exemples de programmes illustrant à chaque fois une des nombreuses caractéristiques de Phaser (vous trouverez même des petits jeux complets avec leurs codes commentés). Je pense que l'étude de ces exemples vous fera très rapidement progresser : http://examples.phaser.io/index.html Je signale également que l'auteur de la bibliothèque envisage la publication d'un livre consacré au développement de jeu avec Phaser (en anglais évidemment), mais au jour où j'écris ces lignes, je n'ai pas plus d'information à vous fournir à ce sujet.