Jeux en tiles avec Flash
Introduction
Voici un tutorial ayant comme sujet la création de jeux basés sur des tiles (tile-based game) avec Macromedia Flash.
Ce tutorial est fortement basé sur les tutoriaux de OutsideOfSociety, faits par Klas Kroon.
Il est nécessaire d’avoir un minimum de connaissances en Action Script et avec Macromedia Flash pour suivre ces tutoriaux. Il se peut qu’ils soient durs à comprendre si vous n’avez jamais fait de jeux avec Flash avant.
J’ai utilisé Flash 5 pour créer le code et les fichiers sources principalement car j'y suis habitué et que je travaille plus vite avec. Le code et les fichiers sources fonctionnent bien avec Flash MX (version 6), aussi, vous ne devriez pas avoir de problèmes avec. Par contre à partir de Flash MX2004 (version 7) et le nouvel Action Script 2, le code n’est plus compatible et vous risquez d'obtenir des erreurs. Ca peut fonctionner quand même mais généralement si vous souhaitez vraiment utiliser l’Action Script 2, vous devrez réécrire le code. Bien entendu, le principe reste le même donc vous pouvez tout de même suivre ces tutoriaux.
Les exemples, le code, et les fichiers sources présentés ici sont utilisables librement en respectant la licence CC ( Creative Commons License ).
J’espère que vous trouverez quelque chose d’utile ici.
Pourquoi des tiles ?
Avant de plonger dans le codage du jeu, parlons un peu des jeux basés sur les tiles. Après tout, pourquoi voudrions nous utiliser des tiles ? Est-ce que les jeux à base de tiles sont plus facile à faire ou peut-être qu’ils sont plus complexes que les autres jeux ? Est-ce que Flash est bon pour les jeux utilisant un système de tiles ?
Les tiles sont déjà utilisées depuis un long moment pour faire des jeux, ils datent d'une époque où l'on ne mesurait pas la vitesse des ordinateurs en GHz et la mémoire en centaines de Mo. La lenteur et la quantité limitée de mémoire signifiaient que les créateurs de jeux devaient utiliser leur cerveau et trouver des méthodes intelligentes pour améliorer les graphismes des jeux et augmenter leur vitesse.
Si vous voulez mettre un joli fond dans votre jeu mais que l’image est trop large et rend le jeu très lent, que faire ? Découper l’image en tiles !

Dans cette image, vous pouvez voir que certaines parties sont exactement identiques. 1 est identique à 2, 3 est identique à 4 et les parties 5, 6 et 7 sont également identiques entre elles. Si vous découpez l’image et que vous réutilisez les mêmes parties à des endroits différents, vous venez de créer des tiles… L’image au complet est beaucoup plus lourde que les tiles.
Les autres points intéressants des tiles est, si vous aviez à remplacer des parties de l’arrière plan, que vous n’avez pas à redessiner tout : vous pouvez remplacer uniquement une tile. Vous pouvez également utiliser une tile avec une autre. Par exemple, vous pourriez utiliser une tile avec de l’herbe et une autre, sur l’herbe, avec des fleurs. Vous pouvez donc prendre la même herbe de fond et dessiner seulement les fleurs.
Flash et les tiles
Comme nous le savons tous, Flash est vectoriel, donc les fichiers Flash sont légers et nous pouvons les redimensionner. Alors pourquoi donc utiliser des tiles pour créer un jeu? Et bien vous pouvez facilement créer des jeux Flash qui ne soient pas basés sur les tiles, mais quand votre zone de jeu devient trop grande et que vous voulez plus de détails, vous pourriez rencontrer des ennuis. Certaines choses sont beaucoup plus faciles à faire dans les jeux à base de tiles (vue isométrique, trouver des trajets et gestion de la profondeur moins gourmande en ressources). N’oubliez pas, les jeux basés sur les tiles ont été les plus répandus pendant longtemps et beaucoup de la théorie est également utilisable avec Flash.
Le coté triste de ces jeux en Flash est que nous ne pouvons pas bénéficier beaucoup des dessins ou des parties chronologiques, notre jeu est fait en actionscript et nous avons juste un groupe de code pour créer, déplacer et modifier les images dans le niveau.
C’est aussi une bonne idée d’utiliser des images bitmap en tant que tiles graphiques. Nous pourrions tout dessiner dans Flash et avoir des graphismes vectoriels, mais quand le jeu tourne, le player flash doit calculer les vecteurs à l’écran et nous ne voulons pas quelque que quelque chose ralentisse notre jeu. Les bitmaps ont un meilleur rendu et sont généralement plus jolis. Si vous voulez importer des tiles en bitmap dans Flash, il est préférable d’enregistrer les images en fichiers GIF avec un fond transparent (pour les objets).
Assez de bla-bla ennuyeux, faisons quelque chose...
Tout d’abord, nous allons voir comment stocker nos cartes de tiles.
Format de la carte
Nous allons conserver nos cartes dans un joli format que Flash fournit : les tableaux. Si vous ne savez pas ce qu’est un tableau, ouvrez l’aide Flash et lisez-y ce que c'est avant de commencer.
Tableau à deux dimensions
Nous avons besoin d’un tableau bidimensionnel pour notre carte. Non, ce n’est pas quelque chose qui vient d’une autre dimension : c’est seulement un tableau qui contient un tableau pour chaque élément. Confus ? Voyez ce qui suit.
Prenons le tableau simple et normal suivant:
Code :
Vous pouvez obtenir la valeur du premier élément avec myArray[0], qui vaut "a", du second avec myArray[1] , qui vaut "b", et ainsi de suite.
Maintenant la partie subtile ! Qu’est ce qu’il en est si nous ne voulons pas mettre "a", "b" et "c" dans un tableau mais que nous voulons mettre d’autres tableaux ? Oui, nous pouvons le faire, par exemple comme ceci :
Code :
Cette fois nous avons déclaré un tableau myArray et chaque élément qu’il contient est aussi un tableau. Donc, la valeur du premier élément myArray[a] est a et a est un tableau ["a1", "a2", "a3"], le second élément a comme valeur ["b1", "b2", "b3"]. Si vous écrivez :
Code :
alors myVar a comme valeur ["c1", "c2", "c3"].
D’accord, vous pourriez vous dire : et alors ? Nous ne devons pas nous arrêter là. Si vous écrivez myVar=myArray[2][0]; vous obtiendrez le premier élément du troisième élément dans myArray "c1".
Exerçons nous plus. myVar=myArray[0][1] prend le premier élément de myArray (a) et le second élément de celui-ci ("a2").
myVar=myArray[1][0] renvoit la valeur "b1".
Vous comprenez le principe ?
Créer la carte
Nous devons d’abord écrire le tableau de la carte qui va contenir les informations de chaque tile :
Code :
Comme vous pouvez voir, notre carte a 6 lignes et 8 colonnes. Si notre héros démarrait depuis le coin supérieur gauche, il pourrait se déplacer de 8 cases à droite et de 6 vers le bas avant de sortir de la carte et de pénétrer dans un endroit inconnu.
Mais quelques personnes se seront déjà posées la question suivante : "Qu’est ce que signifient ces nombres dans le tableau de notre carte ?". Et bien nous utiliserons un peu de POO (ce sont des objets, mais ne vous enfuiez pas, ils ne sont pas aussi effrayants qu’ils le paraissent) pour créer les tiles et les gérer dans notre jeu. Nous déclarons d’abord plusieurs tiles, ils sont comme des modèles pour les autres tiles que nous avons réellement mis dans notre jeu. Après, nous allons faire une boucle pour parcourir le tableau de la carte et récupérer les nombres à chaque position.
Si par exemple nous obtenons le nombre 1, nous créons ensuite un nouveau tile depuis le modèle Tile1. Après, dans le jeu, nous allons contrôler les propriétés de cet objet tile. Il peut avoir plusieurs propriétés, la plupart des tiles basiques n'ayant que 2 propriétés : la collision et l’affichage.
La collision est une propriété qui nous montre si un personnage peut marcher sur ce tile (alors nous paramétrons walkable=true –walkable est l’équivalent pour collision en anglais et true signifie vrai en anglais - ) ou non (false – faux - ). Nous n’utilisons pas hitTest car hitTest est lent et ce n’est pas propre de l’utiliser avec un jeu en tiles.
L’ affichage est une propriété qui nous dit quelle est l’image que nous devons afficher à cet endroit. Elle est utilisée pour placer les tiles à l’écran. Comme nous utilisons la même représentation à l’écran pour chaque tile qui sont qualifiés par le même nombre, tous les tiles 1 afficherons la même image par défaut. Nous y reviendrons plus en détail dans la section sur la création des tiles.
Si nous déclarons le tile suivant :
Code :
Alors nous faisons un objet similaire à chaque fois qu’il y a 1 dans le tableau de la carte (Tile1), nous pouvons aussi dire que ce tile n’est pas accessible (walkable=false) et dans ce tile, l’image à afficher est la frame 2.
Les cartes plus en détail
Il se peut que vous vous demandiez pourquoi exactement est-ce que nous avons choisi ce type de format de cartes. Je ne peux pas dire que c’est absolument la meilleure façon de voir les choses, je ne peux pas dire non plus que ce format est plus rapide ni qu’il crée des fichiers plus légers. Je peux seulement dire qu’après deux ans passés à utiliser ce système, j’ai trouvé que ce format répondait parfaitement à mes besoins. Jetons un coup d’oeil aux autres façons de procéder pour enregistrer les données de vos cartes.
La méthode de Jailbitch
Les tutoriaux originaux de OutsideOfSociety utilisent un format de carte très simple. Ils sauvegardent la même rangée dans un tableau bidimensionnel et chaque nombre nous donne le nombre de la case à afficher. Chaque fois que vous voulez vérifier si la tile suivante est accessible (ou un objet à ramasser, une porte ou tout autre chose), vous devez rechercher le nombre du tableau de la carte.
Quand vous cherchez les collisions, vous déterminez la section des cases qui correspondant aux murs (ou aux objets à ramasser, aux portes,…). Vous pouvez par exemple dire que tous les tiles de 0 à 100 sont des tiles parcourables, que ceux de 101 à 200 sont des murs et que les tiles plus supérieures à 200 sont des tiles spéciaux.
Quand vous avez peu de types de tiles différents et qu’ils ne changeront pas beaucoup, c’est une façon de voir les choses facile et bonne.
Un arbre dans le désert
Certaines cartes ont beaucoup de tiles différents et d’autres en ont moins. Imaginons le désert dans lequel il n’y a rien pendant des kilomètres et des kilomètres si ce n’est du sable, si vous êtes chanceux, vous pourriez voir quelques oasis. C’est pareil pour la mer, il y a de l’eau, de l’eau et encore de l’eau et finalement une petite île.
Si votre carte est composée en majorité d’une même sorte de tiles (sable) et que vous avez seulement quelques petits changements (arbres), alors utiliser un tableau bidimensionnel n’est pas un bon choix. Vous garderiez trop d’informations inutiles : des nombreuses rangées de zéros avant qu’une autre case apparaisse. Il serait mieux de déclarer dans cette case tous les objets qui ne sont pas du sable séparément et laisser tout ce qui reste comme du sable.
Supposons que vous avez une carte de 100x100 et que vous avez 3 arbres dedans, vous pourriez écrire :
Code :
Quand vous créez votre carte, vous consultez le tableau des arbres, vous placez les arbres et vous considérez que les autres tiles qui doivent être affiché sont du sable. C’est beaucoup plus simple que d’écrire le tableau bidimensionnel de 100x100.
Bien sur, cette méthode perd beaucoup de sa vitesse quand vous faites plus d’objets (arbres, buissons, herbe, pierres, eau) et il se peut qu’il devienne difficile de se rappeler quels tiles sont placés et où.
Petit, moyen, énorme
Si vous utilisez flash MX ou ultérieur, vous avez probablement entendu parlé des raccourcis XML magiques. C’est un format similaire au HTML qui permet de déclarer de nombreuses choses. Vous pouvez utiliser XML pour stocker les données de vos cartes. L’explication suivante sur la structure du format XML est basée sur le livre de Jobe Makar, "Macromedia Flash MX Game Design Demystified".
Regardons un exemple simple d’une carte en XML :
Code :
Nous avons déclaré une carte de 3 sur 3. Il y a tout d’abord un en-tête "map", il y a ensuite 3 balises "row" et chacun d’eux a 3 balises "cell".
Pour charger les cartes depuis des fichiers externes, XML peut être une bonne solution car la plupart de l’analyse de fichiers XML peut être faite avec Flash MX qui possède des fonctions adéquates. Charger des tableaux à 2 dimensions depuis des fichiers textes n’est pas aussi facile car vous obtenez toujours des chaînes de caractères obtenues à partir des variables et vous devez convertir la chaîne en tableau, ce qui est très lent.
Vous pouvez aussi voir les désavantages du XML : il en résulte des fichiers beaucoup plus lourds et il nécessite Flash 6 Player pour fonctionner.
Tous les exemples qui suivent utilisent des tableaux bidimensionnels pour stocker les informations des cartes et utilisent des objets pour représenter les tiles à l’écran comme expliqué dans le chapitre "Format de la carte".
Créer des tiles
Comme vous avez vu au chapitre "Format de la carte", notre carte sera conservée dans un tableau à 2 dimensions. Nous allons maintenant afficher les tiles à l’écran, les placer à la bonne place et afficher la bonne image.
Commençons pas déclarer quelques objets et variables :
Code :
Nous avons donc notre carte dans la variable myMap. La ligne qui suit la déclaration de la carte déclare un objet appelé "game". Nous utiliserons cette objet pour conserver tout ce qui est nécessaire. Nous pourrions le conserver dans le _root ou partout ailleurs mais c’est plus clair de mettre le contenu à un endroit pour toujours savoir où il est.
Remarquez aussi que nous donnons à cet objet game deux propriétés tileW=30 et tileH=30. Ils spécifient la largeur et la hauteur de tous nos tiles. Les tiles ne doivent pas obligatoirement être des carrés, vous pourriez aussi utiliser des rectangles. Si nous le voulons, nous pouvons connaître la largeur et la hauteur de n’importe quel tile en écrivant :
Code :
Et quand nous voulons changer la taille des tiles, nous devons juste changer des nombres dans une ligne.
Après nous configurons les propriétés des tiles dans notre objet game.
Code :
La première ligne game.Tile0= function () {} déclare une nouvelle instance. Quand nous obtenons 0 depuis le tableau de la carte, nous utiliserons Tile0 comme modèle pour créer un nouvel objet tile à cet endroit.
Les deux lignes suivantes donnent à l’objet Tile0 et à chaque objet créé avec le modèle Tile0 des propriétés. Nous paramétrerons chaque objet comme ayant la propriété walkable=true (ce qui signifie qu’on peut marche dessus) et frame=1 (ça affichera l’image 1 depuis les tiles attachés au clip).
Afficher ma carte
Etes-vous prêt pour créer des tiles ? Nous allons faire la fonction buildMap qui gérer tout le placement des tiles. Si vous voulez créer plus de niveaux, vous pouvez utiliser la même fonction avec différents tableaux.
La fonction buildMap sera structurée comme ceci :
- attacher la container du MovieClip
- faire une boucle pour parcourir le tableau de la carte
- créer un nouvel objet pour chaque tile
- attacher tous les clips des tiles
- placer les tiles au bon endroit
- afficher la bonne image pour chaque tile
Voici le code équivalent :
Code :
La première ligne déclare la fonction et nous paramétrons également l’argument de la fonction pour être la variable de la carte. Quand nous appelons la fonction, nous lui passerons le tableau de la carte. La variable de la carte sera donc un tableau bidimensionnel.
La ligne suivante attache le container du clip au niveau :
Code :
Vous allez avoir besoin d’un clip vide (qui ne contient pas de graphiques) dans la librairie. Clic droit sur ce clip dans la bibliothèque, choisir "Liaison" puis "exporter ce symbole dans la première image" et écrire "empty" dans la boîte d’identification. Maintenant la commande attachMovie sera accessible depuis le clip avec un lien du nom "empty" dans la bibliothèque. Ca fera ensuite une nouvelle instance de ce clip dans le niveau et donnera le nom « tiles » au nouveau clip. Ce clip conservera tous les tiles que nous plaçons dans le niveau. Ce qui est bien quand on utilise un conteneur vidéo c’est que quand on veut enlever nos tiles (comme à la fin du jeu), nous devons juste enlever le MovieClip "tiles" et tous les tiles disparaîtrons. Si vous attachez tous les tiles directement dans le niveau _root et que vous allez à l’image suivante (comme l’écran de fin du jeu) alors les tiles ne disparaîtrons pas et vous devez tous les effacer en actionscript.
Une fois que nous avons un MovieClip pour tous les tiles, nous faisons aussi un lien de celui vers notre objet game.clip = _root.tiles. Maintenant quand nous avons besoin d’accéder au tiles du clip, nous pouvons utiliser game.clip. Cela permet, si nous avions jamais besoin de placer des tiles quelque part d’autre de simple renommer cette ligne et de ne pas devoir plonger dans le code.
Après nous faisons deux nouvelles variable mapWidth et mapHaight. C’est celles que nous allons utiliser dans la boucle pour parcourir le tableau de la carte. mapWidth a la valeur de la longueur du premier élément dans le tableau map[0].length. Allez revoir le chapitre "Format de la carte" si vous avez oublié à quoi ressemble le tableau de la carte. Le premier élément du tableau est un autre tableau [1, 1, 1, 1, 1, 1, 1, 1] et mapWidth aura la valeur de sa longueur ou du nombre d’éléments. Nous savons maintenant quel sera la largeur de notre carte.
C’est le même procédé pour mapHeight : elle aura la valeur de map.length, le nombre de lignes dans le tableau. Ce qui correspond au nombre de ligne que nous devons créer.
Notre parcourons le tableau grâce à ces lignes :
Code :
Nous initialisons la variable i à 0 et nous l’incrémentons de 1 à chaque tour tant que i vaut moins que la hauteur de la carte. La variable j boucle de 0 jusqu’à la largeur de notre carte.
La variable "name" de la ligne var name = "t_"+i+"_"+j nous donne le nom du nouvel objet tile. Si i=0 et j=1 alors name = "t_0_1" et si i=34 et j=78 alors name aura "t_34_78" comme valeur.
Maintenant nous créons l’objet tile :
Code :
Du coté gauche, game[name] indiquera que le nouvel objet tile est placé dans l’objet game comme tous. La valeur de map[i ][j] nous donne le nombre du tableau de la carte qui dépend des valeurs de i et j ? Nous utilisons ensuite le mot clé "new" pour créer un nouvel objet tile depuis le modèle que nous avons déclaré plus tôt. Nous avons désormais un nouvel objet dans l’objet game qui représente le tile courant.
Dans les lignes qui suivent, nous attachons un nouveau MovieClip au niveau et nous utilisons game.clip[name] pour y accéder. Le clip sera placé à la bonne position x/y en utilisant les variables j et i multipliées par la largeur et par la hauteur de tiles. Comme notre nouvel objet tile hérite eds propiétés de "frame" depuis le modèle, nous l’utilisons pour allez à la bonne image avec la commande gotoAndStop.
Quand nous voulons créer des tiles la carte, nous pouvons appeler la fonction buildMap comme ceci :
Code :
Vous pouvez télécharger la source .fla avec tout le code et la configuration de la vidéo ici .
Plus sur les tiles
Depuis que nous avons paramétré nos tiles en tant qu’objets, nous pouvons aussi utiliser quelques avantages fournit par les objets. Ce qui est bien avec les objets (a part qu’il sont mignons, doux et aimés par tout le monde) est la façon avec laquelle ils héritent des propriétés de chacun d’entre eux. Avec un peu de chance vous venez de lire le chapitre précédent et vous avez remarqué comment nous écrivions les propriétés des tiles :
Code :
Cela nous permet d’écrire les propriétés de chaque type de tile seulement une fois et pas à chaque fois qu’un nous tile est créé. De la même façon, nous pouvons faire évoluer la logique et nous préserver de devoir écrire tous les différents types de tile.
Déclarons la classe générale Tile :
Code :
Nous supposons ici que tous les tiles du jeu ne sont pas parcourables (walkable=false) par défaut et qu’ils affichent l’image 20. Bien sur de nombreux tiles sont en fait parcourable ou peuvent être contournés et ils peuvent aussi afficher d’autres images (ce n’est pas parce que l’image 20 à un problème avec cela, c’est une belle image en pleine forme). Ces problèmes peuvent paraître accablant mais ne vous faite pas de soucis, soyez heureux : nous pouvons faire en sorte que ce système fonctionne mieux.
Créons quelques types de tile :
Code :
En utilisant cette ingénieuse petite chose appellée "__proto__", nous n’avons pas à écrire toutes les mêmes propriétés encore et encore, nos tiles récupérerons toutes les choses importantes depuis la classe TileClass. Donc quand nous devons créer un nouveau tile :
Code :
Tous les tiles créés par après depuis le modèle Tile2 héritent des propriétés walkable=false et frame=20 de TileClass. C’est fort gentil de leur part, n’est-ce pas ? Mais l’amusement n’est pas encore là, nous pouvons aussi changer les propriétés des tiles obtenues depuis TileClass. Vous ne me croyez pas ? C’est vrai ! Regardez :
Code :
Tile0 a walkable=false depuis TileClass mais nous avons depuis déclaré un nouveau prototype walkable=true pour celui-ci. L’ancienne propriété est remplacée et tous les tiles faits avec Tile0 sont désormais parcourables.
Nous avons aussi déclaré une nouvelle image pour Tile0, il n’affichera pas une fois de plus la 20 mais à la place l’image 1.
Tous ceci est peut être un peu beaucoup à l’heure actuelle car nous avons seulement quelques tiles et peu de propriétés mais si vous voulez faire un jeu avec de nombreux types de tiles, possédant chacun beaucoup de propriétés, et que vous deviez tout taper, ça deviendrait vite lassant.
Le héros
Aucun jeu ne peut exister sans le héros. Le héros va sauver le monde et la princesse et va chasser les méchants. Nous allons donc ajouter le héros. Il ne va pas encore sauver le monde, il ne fera rien d’utile mais le voici :
Le héros est un carré rouge . Quoi ? Il ne paraît pas puissant ? Vous pouvez dessiner votre propre héros. Son MovieClip est dans la bibliothèque nommée "char" et il a aussi été exporter en tant que "char". Vous ne pouvez pas créer le MovieClip du héros plus large que les tiles.
Remarquer aussi que son MovieClip (carré rouge) est enregistré via son point central et que les clips vidéos des tiles sont enregistrés via le point supérieur gauche.

Vous voulez du code ? Ajoutez cette ligne après la définition des tiles :
Code :
Ce code déclare un nouvel objet "char". Il va contenir toutes les informations sur notre personnage : comment il bouge, comment il se sent, ce qu’il mange.
Nous donnons à ce moment à seulement deux propriétés à l’objet : xtile et ytile. Ceux-ci nous donnent le tile sur lequel notre héros se trouve. Quand il se déplace, nous mettons à jour ces deux propriétés et nous sauvons toujours quel tile est en dessous du héros. Par exemple, quand xtile=2 et ytile=1, cela signifie que le héros se trouve sur le tile "t_1_2". Quand vous regardez la vidéo d’exemple, vous voyez que le héros se trouve sur le tile se situe à 3 cases à droite et 1 case en bas du coin supérieur gauche de notre jeu. Toutes les tiles commencent à être comptés à partir de 0.
Nous ajouterons plus de propriétés au héros plus tard.
Pour placer le clip du héros dans le niveau, ajoutez les lignes suivantes à la fonction buildMap après les boucles for.
Code :
La première ligne attache un nouveau MovieClip de la bibliothèque dans game.clip (vous vous rappellez que nous sauvegardons le chemin pour _root.tiles comme game.clip dans le dernier chapitre) et donne le nom "char".
Après nous enregistrons le chemin du MovieClip char dans l’objet char. A chaque fois que nous voulons accéder au clip, nous pouvons simplement utiliser char.clip à la place de taper le nom complet du chemin du clip _root.tiles.char. Cela nous permet également de ne pas devoir parcourir tout le code pour modifier le nom si nous devons déplacer le clip vidé à un autre endroit.
Nous allons ensuite calculer deux propriétés dans l’objet char : x et y. Vous pouvez vous demander pourquoi est ce que nous avons besoin de plus de propriétés alors que nous avons déjà xtile et ytile. Rappelez-vous, les propriétés xtile et ytile compte le nombre de tiles et pas véritablement des pixels. Les propriétés x et y vont contenir les coordonnées des pixels du MovieClip du personnage. C‘est une bonne idée d’avoir les coordonnées dans des variables avant de placer le MovieClip, vous pourriez avoir besoin de changer de position parce que le héro a heurté le mur ou perdu l’équilibre et c’est plus facile de changer les variables que les propriétés _x/_y.
Nous allons calculer la position actuelle de notre héros en multipliant le nombre de la tile sur lequel il se trouve par la largeur des tiles et ajouter la moitié de la taille d’une tile pour placer le personnage au centre de la tile. Nous aurons donc char.xtile * game.tileW qui nous donnera le nombre de tiles à l’horizontal multiplié par la largeur de la tile venant de notre objet game.
Ensuite nous sauvegardons la moitié du la largeur et de la hauteur du MovieClip de notre héros dans l’objet char. Ils deviendront très utiles quand nous calculerons où sont les limites du héros. Notez que vous pouvez créer vos propres limites, vous n’êtes pas obligé d’utiliser la largeur et la hauteur du clip vidéo. Certains héros peuvent avoir une longue touffe de cheveux qui peuvent se heurter aux murs. Dans ce cas, déclarez vos propres variables pour la hauteur et la largeur.
Les deux dernières lignes placent le clip du personnage, char.clip, aux coordonnées que nous avons calculé plus tôt en tant que x et y.
Ecrit par Quintoff
Voici un tutorial ayant comme sujet la création de jeux basés sur des tiles (tile-based game) avec Macromedia Flash.
Ce tutorial est fortement basé sur les tutoriaux de OutsideOfSociety, faits par Klas Kroon.
Il est nécessaire d’avoir un minimum de connaissances en Action Script et avec Macromedia Flash pour suivre ces tutoriaux. Il se peut qu’ils soient durs à comprendre si vous n’avez jamais fait de jeux avec Flash avant.
J’ai utilisé Flash 5 pour créer le code et les fichiers sources principalement car j'y suis habitué et que je travaille plus vite avec. Le code et les fichiers sources fonctionnent bien avec Flash MX (version 6), aussi, vous ne devriez pas avoir de problèmes avec. Par contre à partir de Flash MX2004 (version 7) et le nouvel Action Script 2, le code n’est plus compatible et vous risquez d'obtenir des erreurs. Ca peut fonctionner quand même mais généralement si vous souhaitez vraiment utiliser l’Action Script 2, vous devrez réécrire le code. Bien entendu, le principe reste le même donc vous pouvez tout de même suivre ces tutoriaux.
Les exemples, le code, et les fichiers sources présentés ici sont utilisables librement en respectant la licence CC ( Creative Commons License ).
J’espère que vous trouverez quelque chose d’utile ici.
________________________________________________________________
Pourquoi des tiles ?
Avant de plonger dans le codage du jeu, parlons un peu des jeux basés sur les tiles. Après tout, pourquoi voudrions nous utiliser des tiles ? Est-ce que les jeux à base de tiles sont plus facile à faire ou peut-être qu’ils sont plus complexes que les autres jeux ? Est-ce que Flash est bon pour les jeux utilisant un système de tiles ?
Les tiles sont déjà utilisées depuis un long moment pour faire des jeux, ils datent d'une époque où l'on ne mesurait pas la vitesse des ordinateurs en GHz et la mémoire en centaines de Mo. La lenteur et la quantité limitée de mémoire signifiaient que les créateurs de jeux devaient utiliser leur cerveau et trouver des méthodes intelligentes pour améliorer les graphismes des jeux et augmenter leur vitesse.
Si vous voulez mettre un joli fond dans votre jeu mais que l’image est trop large et rend le jeu très lent, que faire ? Découper l’image en tiles !

Dans cette image, vous pouvez voir que certaines parties sont exactement identiques. 1 est identique à 2, 3 est identique à 4 et les parties 5, 6 et 7 sont également identiques entre elles. Si vous découpez l’image et que vous réutilisez les mêmes parties à des endroits différents, vous venez de créer des tiles… L’image au complet est beaucoup plus lourde que les tiles.
Les autres points intéressants des tiles est, si vous aviez à remplacer des parties de l’arrière plan, que vous n’avez pas à redessiner tout : vous pouvez remplacer uniquement une tile. Vous pouvez également utiliser une tile avec une autre. Par exemple, vous pourriez utiliser une tile avec de l’herbe et une autre, sur l’herbe, avec des fleurs. Vous pouvez donc prendre la même herbe de fond et dessiner seulement les fleurs.
Flash et les tiles
Comme nous le savons tous, Flash est vectoriel, donc les fichiers Flash sont légers et nous pouvons les redimensionner. Alors pourquoi donc utiliser des tiles pour créer un jeu? Et bien vous pouvez facilement créer des jeux Flash qui ne soient pas basés sur les tiles, mais quand votre zone de jeu devient trop grande et que vous voulez plus de détails, vous pourriez rencontrer des ennuis. Certaines choses sont beaucoup plus faciles à faire dans les jeux à base de tiles (vue isométrique, trouver des trajets et gestion de la profondeur moins gourmande en ressources). N’oubliez pas, les jeux basés sur les tiles ont été les plus répandus pendant longtemps et beaucoup de la théorie est également utilisable avec Flash.
Le coté triste de ces jeux en Flash est que nous ne pouvons pas bénéficier beaucoup des dessins ou des parties chronologiques, notre jeu est fait en actionscript et nous avons juste un groupe de code pour créer, déplacer et modifier les images dans le niveau.
C’est aussi une bonne idée d’utiliser des images bitmap en tant que tiles graphiques. Nous pourrions tout dessiner dans Flash et avoir des graphismes vectoriels, mais quand le jeu tourne, le player flash doit calculer les vecteurs à l’écran et nous ne voulons pas quelque que quelque chose ralentisse notre jeu. Les bitmaps ont un meilleur rendu et sont généralement plus jolis. Si vous voulez importer des tiles en bitmap dans Flash, il est préférable d’enregistrer les images en fichiers GIF avec un fond transparent (pour les objets).
Assez de bla-bla ennuyeux, faisons quelque chose...
Tout d’abord, nous allons voir comment stocker nos cartes de tiles.
________________________________________________________________
Format de la carte
Nous allons conserver nos cartes dans un joli format que Flash fournit : les tableaux. Si vous ne savez pas ce qu’est un tableau, ouvrez l’aide Flash et lisez-y ce que c'est avant de commencer.
Tableau à deux dimensions
Nous avons besoin d’un tableau bidimensionnel pour notre carte. Non, ce n’est pas quelque chose qui vient d’une autre dimension : c’est seulement un tableau qui contient un tableau pour chaque élément. Confus ? Voyez ce qui suit.
Prenons le tableau simple et normal suivant:
Code :
myArray=["a", "b", "c", "d"]
Vous pouvez obtenir la valeur du premier élément avec myArray[0], qui vaut "a", du second avec myArray[1] , qui vaut "b", et ainsi de suite.
Maintenant la partie subtile ! Qu’est ce qu’il en est si nous ne voulons pas mettre "a", "b" et "c" dans un tableau mais que nous voulons mettre d’autres tableaux ? Oui, nous pouvons le faire, par exemple comme ceci :
Code :
a=["a1", "a2", "a3"] b=["b1", "b2", "b3"] c=["c1", "c2", "c3"] myArray=[a, b, c]
Cette fois nous avons déclaré un tableau myArray et chaque élément qu’il contient est aussi un tableau. Donc, la valeur du premier élément myArray[a] est a et a est un tableau ["a1", "a2", "a3"], le second élément a comme valeur ["b1", "b2", "b3"]. Si vous écrivez :
Code :
myVar=myArrayΐ]
alors myVar a comme valeur ["c1", "c2", "c3"].
D’accord, vous pourriez vous dire : et alors ? Nous ne devons pas nous arrêter là. Si vous écrivez myVar=myArray[2][0]; vous obtiendrez le premier élément du troisième élément dans myArray "c1".
Exerçons nous plus. myVar=myArray[0][1] prend le premier élément de myArray (a) et le second élément de celui-ci ("a2").
myVar=myArray[1][0] renvoit la valeur "b1".
Vous comprenez le principe ?
Créer la carte
Nous devons d’abord écrire le tableau de la carte qui va contenir les informations de chaque tile :
Code :
myMap = [ Ώ, 1, 1, 1, 1, 1, 1, 1], Ώ, 0, 0, 0, 0, 0, 0, 1], Ώ, 0, 1, 0, 0, 0, 0, 1], Ώ, 0, 0, 0, 0, 1, 0, 1], Ώ, 0, 0, 0, 0, 0, 0, 1], Ώ, 1, 1, 1, 1, 1, 1, 1] ]
Comme vous pouvez voir, notre carte a 6 lignes et 8 colonnes. Si notre héros démarrait depuis le coin supérieur gauche, il pourrait se déplacer de 8 cases à droite et de 6 vers le bas avant de sortir de la carte et de pénétrer dans un endroit inconnu.
Mais quelques personnes se seront déjà posées la question suivante : "Qu’est ce que signifient ces nombres dans le tableau de notre carte ?". Et bien nous utiliserons un peu de POO (ce sont des objets, mais ne vous enfuiez pas, ils ne sont pas aussi effrayants qu’ils le paraissent) pour créer les tiles et les gérer dans notre jeu. Nous déclarons d’abord plusieurs tiles, ils sont comme des modèles pour les autres tiles que nous avons réellement mis dans notre jeu. Après, nous allons faire une boucle pour parcourir le tableau de la carte et récupérer les nombres à chaque position.
Si par exemple nous obtenons le nombre 1, nous créons ensuite un nouveau tile depuis le modèle Tile1. Après, dans le jeu, nous allons contrôler les propriétés de cet objet tile. Il peut avoir plusieurs propriétés, la plupart des tiles basiques n'ayant que 2 propriétés : la collision et l’affichage.
La collision est une propriété qui nous montre si un personnage peut marcher sur ce tile (alors nous paramétrons walkable=true –walkable est l’équivalent pour collision en anglais et true signifie vrai en anglais - ) ou non (false – faux - ). Nous n’utilisons pas hitTest car hitTest est lent et ce n’est pas propre de l’utiliser avec un jeu en tiles.
L’ affichage est une propriété qui nous dit quelle est l’image que nous devons afficher à cet endroit. Elle est utilisée pour placer les tiles à l’écran. Comme nous utilisons la même représentation à l’écran pour chaque tile qui sont qualifiés par le même nombre, tous les tiles 1 afficherons la même image par défaut. Nous y reviendrons plus en détail dans la section sur la création des tiles.
Si nous déclarons le tile suivant :
Code :
Tile1= function () {};
Tile1.prototype.walkable=false;
Tile1.prototype.frame=2; //frame représente l'imageAlors nous faisons un objet similaire à chaque fois qu’il y a 1 dans le tableau de la carte (Tile1), nous pouvons aussi dire que ce tile n’est pas accessible (walkable=false) et dans ce tile, l’image à afficher est la frame 2.
________________________________________________________________
Les cartes plus en détail
Il se peut que vous vous demandiez pourquoi exactement est-ce que nous avons choisi ce type de format de cartes. Je ne peux pas dire que c’est absolument la meilleure façon de voir les choses, je ne peux pas dire non plus que ce format est plus rapide ni qu’il crée des fichiers plus légers. Je peux seulement dire qu’après deux ans passés à utiliser ce système, j’ai trouvé que ce format répondait parfaitement à mes besoins. Jetons un coup d’oeil aux autres façons de procéder pour enregistrer les données de vos cartes.
La méthode de Jailbitch
Les tutoriaux originaux de OutsideOfSociety utilisent un format de carte très simple. Ils sauvegardent la même rangée dans un tableau bidimensionnel et chaque nombre nous donne le nombre de la case à afficher. Chaque fois que vous voulez vérifier si la tile suivante est accessible (ou un objet à ramasser, une porte ou tout autre chose), vous devez rechercher le nombre du tableau de la carte.
Quand vous cherchez les collisions, vous déterminez la section des cases qui correspondant aux murs (ou aux objets à ramasser, aux portes,…). Vous pouvez par exemple dire que tous les tiles de 0 à 100 sont des tiles parcourables, que ceux de 101 à 200 sont des murs et que les tiles plus supérieures à 200 sont des tiles spéciaux.
Quand vous avez peu de types de tiles différents et qu’ils ne changeront pas beaucoup, c’est une façon de voir les choses facile et bonne.
Un arbre dans le désert
Certaines cartes ont beaucoup de tiles différents et d’autres en ont moins. Imaginons le désert dans lequel il n’y a rien pendant des kilomètres et des kilomètres si ce n’est du sable, si vous êtes chanceux, vous pourriez voir quelques oasis. C’est pareil pour la mer, il y a de l’eau, de l’eau et encore de l’eau et finalement une petite île.
Si votre carte est composée en majorité d’une même sorte de tiles (sable) et que vous avez seulement quelques petits changements (arbres), alors utiliser un tableau bidimensionnel n’est pas un bon choix. Vous garderiez trop d’informations inutiles : des nombreuses rangées de zéros avant qu’une autre case apparaisse. Il serait mieux de déclarer dans cette case tous les objets qui ne sont pas du sable séparément et laisser tout ce qui reste comme du sable.
Supposons que vous avez une carte de 100x100 et que vous avez 3 arbres dedans, vous pourriez écrire :
Code :
trees = [⎣,6], ⎱,21], ⏃,345]]
Quand vous créez votre carte, vous consultez le tableau des arbres, vous placez les arbres et vous considérez que les autres tiles qui doivent être affiché sont du sable. C’est beaucoup plus simple que d’écrire le tableau bidimensionnel de 100x100.
Bien sur, cette méthode perd beaucoup de sa vitesse quand vous faites plus d’objets (arbres, buissons, herbe, pierres, eau) et il se peut qu’il devienne difficile de se rappeler quels tiles sont placés et où.
Petit, moyen, énorme
Si vous utilisez flash MX ou ultérieur, vous avez probablement entendu parlé des raccourcis XML magiques. C’est un format similaire au HTML qui permet de déclarer de nombreuses choses. Vous pouvez utiliser XML pour stocker les données de vos cartes. L’explication suivante sur la structure du format XML est basée sur le livre de Jobe Makar, "Macromedia Flash MX Game Design Demystified".
Regardons un exemple simple d’une carte en XML :
Code :
<map>
<row>
<cell type="1">
<cell type="1">
<cell type="1">
</row>
<row>
<cell type="1">
<cell type="4">
<cell type="1">
</row>
<row>
<cell type="1">
<cell type="1">
<cell type="1">
</row>
</map>Nous avons déclaré une carte de 3 sur 3. Il y a tout d’abord un en-tête "map", il y a ensuite 3 balises "row" et chacun d’eux a 3 balises "cell".
Pour charger les cartes depuis des fichiers externes, XML peut être une bonne solution car la plupart de l’analyse de fichiers XML peut être faite avec Flash MX qui possède des fonctions adéquates. Charger des tableaux à 2 dimensions depuis des fichiers textes n’est pas aussi facile car vous obtenez toujours des chaînes de caractères obtenues à partir des variables et vous devez convertir la chaîne en tableau, ce qui est très lent.
Vous pouvez aussi voir les désavantages du XML : il en résulte des fichiers beaucoup plus lourds et il nécessite Flash 6 Player pour fonctionner.
Tous les exemples qui suivent utilisent des tableaux bidimensionnels pour stocker les informations des cartes et utilisent des objets pour représenter les tiles à l’écran comme expliqué dans le chapitre "Format de la carte".
________________________________________________________________
Créer des tiles
Comme vous avez vu au chapitre "Format de la carte", notre carte sera conservée dans un tableau à 2 dimensions. Nous allons maintenant afficher les tiles à l’écran, les placer à la bonne place et afficher la bonne image.
Commençons pas déclarer quelques objets et variables :
Code :
myMap = [
Ώ, 1, 1, 1, 1, 1, 1, 1],
Ώ, 0, 0, 0, 0, 0, 0, 1],
Ώ, 0, 1, 0, 0, 0, 0, 1],
Ώ, 0, 0, 0, 0, 1, 0, 1],
Ώ, 0, 0, 0, 0, 0, 0, 1],
Ώ, 1, 1, 1, 1, 1, 1, 1]
]
game={tileW:30, tileH:30};
game.Tile0= function () {};
game.Tile0.prototype.walkable=true;
game.Tile0.prototype.frame=1;
game.Tile1= function () {};
game.Tile1.prototype.walkable=false;
game.Tile1.prototype.frame=2;Nous avons donc notre carte dans la variable myMap. La ligne qui suit la déclaration de la carte déclare un objet appelé "game". Nous utiliserons cette objet pour conserver tout ce qui est nécessaire. Nous pourrions le conserver dans le _root ou partout ailleurs mais c’est plus clair de mettre le contenu à un endroit pour toujours savoir où il est.
Remarquez aussi que nous donnons à cet objet game deux propriétés tileW=30 et tileH=30. Ils spécifient la largeur et la hauteur de tous nos tiles. Les tiles ne doivent pas obligatoirement être des carrés, vous pourriez aussi utiliser des rectangles. Si nous le voulons, nous pouvons connaître la largeur et la hauteur de n’importe quel tile en écrivant :
Code :
game.tileW; game.tileH;
Et quand nous voulons changer la taille des tiles, nous devons juste changer des nombres dans une ligne.
Après nous configurons les propriétés des tiles dans notre objet game.
Code :
game.Tile0= function () {};
game.Tile0.prototype.walkable=true;
game.Tile0.prototype.frame=1;La première ligne game.Tile0= function () {} déclare une nouvelle instance. Quand nous obtenons 0 depuis le tableau de la carte, nous utiliserons Tile0 comme modèle pour créer un nouvel objet tile à cet endroit.
Les deux lignes suivantes donnent à l’objet Tile0 et à chaque objet créé avec le modèle Tile0 des propriétés. Nous paramétrerons chaque objet comme ayant la propriété walkable=true (ce qui signifie qu’on peut marche dessus) et frame=1 (ça affichera l’image 1 depuis les tiles attachés au clip).
Afficher ma carte
Etes-vous prêt pour créer des tiles ? Nous allons faire la fonction buildMap qui gérer tout le placement des tiles. Si vous voulez créer plus de niveaux, vous pouvez utiliser la même fonction avec différents tableaux.
La fonction buildMap sera structurée comme ceci :
- attacher la container du MovieClip
- faire une boucle pour parcourir le tableau de la carte
- créer un nouvel objet pour chaque tile
- attacher tous les clips des tiles
- placer les tiles au bon endroit
- afficher la bonne image pour chaque tile
Voici le code équivalent :
Code :
function buildMap (map)
{
_root.attachMovie("empty", "tiles", ++d);
game.clip=_root.tiles;
var mapWidth = mapΎ].length;
var mapHeight = map.length;
for (var i = 0; i < mapHeight; ++i)
{
for (var j = 0; j < mapWidth; ++j)
{
var name = "t_"+i+"_"+j;
game[name]= new game["Tile"+map[i][j]]
game.clip.attachMovie("tile", name, i*100+j*2);
game.clip[name]._x = (j*game.tileW);
game.clip[name]._y = (i*game.tileH);
game.clip[name].gotoAndStop(game[name].frame);
}
}
}La première ligne déclare la fonction et nous paramétrons également l’argument de la fonction pour être la variable de la carte. Quand nous appelons la fonction, nous lui passerons le tableau de la carte. La variable de la carte sera donc un tableau bidimensionnel.
La ligne suivante attache le container du clip au niveau :
Code :
_root.attachMovie("empty", "tiles", ++d);Vous allez avoir besoin d’un clip vide (qui ne contient pas de graphiques) dans la librairie. Clic droit sur ce clip dans la bibliothèque, choisir "Liaison" puis "exporter ce symbole dans la première image" et écrire "empty" dans la boîte d’identification. Maintenant la commande attachMovie sera accessible depuis le clip avec un lien du nom "empty" dans la bibliothèque. Ca fera ensuite une nouvelle instance de ce clip dans le niveau et donnera le nom « tiles » au nouveau clip. Ce clip conservera tous les tiles que nous plaçons dans le niveau. Ce qui est bien quand on utilise un conteneur vidéo c’est que quand on veut enlever nos tiles (comme à la fin du jeu), nous devons juste enlever le MovieClip "tiles" et tous les tiles disparaîtrons. Si vous attachez tous les tiles directement dans le niveau _root et que vous allez à l’image suivante (comme l’écran de fin du jeu) alors les tiles ne disparaîtrons pas et vous devez tous les effacer en actionscript.
Une fois que nous avons un MovieClip pour tous les tiles, nous faisons aussi un lien de celui vers notre objet game.clip = _root.tiles. Maintenant quand nous avons besoin d’accéder au tiles du clip, nous pouvons utiliser game.clip. Cela permet, si nous avions jamais besoin de placer des tiles quelque part d’autre de simple renommer cette ligne et de ne pas devoir plonger dans le code.
Après nous faisons deux nouvelles variable mapWidth et mapHaight. C’est celles que nous allons utiliser dans la boucle pour parcourir le tableau de la carte. mapWidth a la valeur de la longueur du premier élément dans le tableau map[0].length. Allez revoir le chapitre "Format de la carte" si vous avez oublié à quoi ressemble le tableau de la carte. Le premier élément du tableau est un autre tableau [1, 1, 1, 1, 1, 1, 1, 1] et mapWidth aura la valeur de sa longueur ou du nombre d’éléments. Nous savons maintenant quel sera la largeur de notre carte.
C’est le même procédé pour mapHeight : elle aura la valeur de map.length, le nombre de lignes dans le tableau. Ce qui correspond au nombre de ligne que nous devons créer.
Notre parcourons le tableau grâce à ces lignes :
Code :
for (var i = 0; i < mapHeight; ++i)
{
for (var j = 0; j < mapWidth; ++j)
{Nous initialisons la variable i à 0 et nous l’incrémentons de 1 à chaque tour tant que i vaut moins que la hauteur de la carte. La variable j boucle de 0 jusqu’à la largeur de notre carte.
La variable "name" de la ligne var name = "t_"+i+"_"+j nous donne le nom du nouvel objet tile. Si i=0 et j=1 alors name = "t_0_1" et si i=34 et j=78 alors name aura "t_34_78" comme valeur.
Maintenant nous créons l’objet tile :
Code :
game[name] = new game["Tile"+map[i ][j]]
Du coté gauche, game[name] indiquera que le nouvel objet tile est placé dans l’objet game comme tous. La valeur de map[i ][j] nous donne le nombre du tableau de la carte qui dépend des valeurs de i et j ? Nous utilisons ensuite le mot clé "new" pour créer un nouvel objet tile depuis le modèle que nous avons déclaré plus tôt. Nous avons désormais un nouvel objet dans l’objet game qui représente le tile courant.
Dans les lignes qui suivent, nous attachons un nouveau MovieClip au niveau et nous utilisons game.clip[name] pour y accéder. Le clip sera placé à la bonne position x/y en utilisant les variables j et i multipliées par la largeur et par la hauteur de tiles. Comme notre nouvel objet tile hérite eds propiétés de "frame" depuis le modèle, nous l’utilisons pour allez à la bonne image avec la commande gotoAndStop.
Quand nous voulons créer des tiles la carte, nous pouvons appeler la fonction buildMap comme ceci :
Code :
buildMap(myMap);
Vous pouvez télécharger la source .fla avec tout le code et la configuration de la vidéo ici .
________________________________________________________________
Plus sur les tiles
Depuis que nous avons paramétré nos tiles en tant qu’objets, nous pouvons aussi utiliser quelques avantages fournit par les objets. Ce qui est bien avec les objets (a part qu’il sont mignons, doux et aimés par tout le monde) est la façon avec laquelle ils héritent des propriétés de chacun d’entre eux. Avec un peu de chance vous venez de lire le chapitre précédent et vous avez remarqué comment nous écrivions les propriétés des tiles :
Code :
game.Tile0= function () {};
game.Tile0.prototype.walkable=true;
game.Tile0.prototype.frame=1;Cela nous permet d’écrire les propriétés de chaque type de tile seulement une fois et pas à chaque fois qu’un nous tile est créé. De la même façon, nous pouvons faire évoluer la logique et nous préserver de devoir écrire tous les différents types de tile.
Déclarons la classe générale Tile :
Code :
game.TileClass = function () {};
game.TileClass.prototype.walkable=false;
game.TileClass.prototype.frame=20;Nous supposons ici que tous les tiles du jeu ne sont pas parcourables (walkable=false) par défaut et qu’ils affichent l’image 20. Bien sur de nombreux tiles sont en fait parcourable ou peuvent être contournés et ils peuvent aussi afficher d’autres images (ce n’est pas parce que l’image 20 à un problème avec cela, c’est une belle image en pleine forme). Ces problèmes peuvent paraître accablant mais ne vous faite pas de soucis, soyez heureux : nous pouvons faire en sorte que ce système fonctionne mieux.
Créons quelques types de tile :
Code :
game.Tile0 = function () {};
game.Tile0.prototype.__proto__ = game.TileClass.prototype;
game.Tile0.prototype.walkable=true;
game.Tile0.prototype.frame=1;
game.Tile1 = function () {};
game.Tile1.prototype.__proto__ = game.TileClass.prototype;
game.Tile1.prototype.frame=2;
game.Tile2 = function () {};
game.Tile2.prototype.__proto__ = game.TileClass.prototype;En utilisant cette ingénieuse petite chose appellée "__proto__", nous n’avons pas à écrire toutes les mêmes propriétés encore et encore, nos tiles récupérerons toutes les choses importantes depuis la classe TileClass. Donc quand nous devons créer un nouveau tile :
Code :
game.Tile2 = function () {};
game.Tile2.prototype.__proto__ = game.TileClass.prototype;Tous les tiles créés par après depuis le modèle Tile2 héritent des propriétés walkable=false et frame=20 de TileClass. C’est fort gentil de leur part, n’est-ce pas ? Mais l’amusement n’est pas encore là, nous pouvons aussi changer les propriétés des tiles obtenues depuis TileClass. Vous ne me croyez pas ? C’est vrai ! Regardez :
Code :
game.Tile0 = function () {};
game.Tile0.prototype.__proto__ = game.TileClass.prototype;
game.Tile0.prototype.walkable=true;
game.Tile0.prototype.frame=1;Tile0 a walkable=false depuis TileClass mais nous avons depuis déclaré un nouveau prototype walkable=true pour celui-ci. L’ancienne propriété est remplacée et tous les tiles faits avec Tile0 sont désormais parcourables.
Nous avons aussi déclaré une nouvelle image pour Tile0, il n’affichera pas une fois de plus la 20 mais à la place l’image 1.
Tous ceci est peut être un peu beaucoup à l’heure actuelle car nous avons seulement quelques tiles et peu de propriétés mais si vous voulez faire un jeu avec de nombreux types de tiles, possédant chacun beaucoup de propriétés, et que vous deviez tout taper, ça deviendrait vite lassant.
________________________________________________________________
Le héros
Aucun jeu ne peut exister sans le héros. Le héros va sauver le monde et la princesse et va chasser les méchants. Nous allons donc ajouter le héros. Il ne va pas encore sauver le monde, il ne fera rien d’utile mais le voici :
Le héros est un carré rouge . Quoi ? Il ne paraît pas puissant ? Vous pouvez dessiner votre propre héros. Son MovieClip est dans la bibliothèque nommée "char" et il a aussi été exporter en tant que "char". Vous ne pouvez pas créer le MovieClip du héros plus large que les tiles.
Remarquer aussi que son MovieClip (carré rouge) est enregistré via son point central et que les clips vidéos des tiles sont enregistrés via le point supérieur gauche.

Vous voulez du code ? Ajoutez cette ligne après la définition des tiles :
Code :
char={xtile:2, ytile:1};Ce code déclare un nouvel objet "char". Il va contenir toutes les informations sur notre personnage : comment il bouge, comment il se sent, ce qu’il mange.
Nous donnons à ce moment à seulement deux propriétés à l’objet : xtile et ytile. Ceux-ci nous donnent le tile sur lequel notre héros se trouve. Quand il se déplace, nous mettons à jour ces deux propriétés et nous sauvons toujours quel tile est en dessous du héros. Par exemple, quand xtile=2 et ytile=1, cela signifie que le héros se trouve sur le tile "t_1_2". Quand vous regardez la vidéo d’exemple, vous voyez que le héros se trouve sur le tile se situe à 3 cases à droite et 1 case en bas du coin supérieur gauche de notre jeu. Toutes les tiles commencent à être comptés à partir de 0.
Nous ajouterons plus de propriétés au héros plus tard.
Pour placer le clip du héros dans le niveau, ajoutez les lignes suivantes à la fonction buildMap après les boucles for.
Code :
game.clip.attachMovie("char", "char", 10000);
char.clip = game.clip.char;
char.x = (char.xtile * game.tileW)+game.tileW/2;
char.y = (char.ytile * game.tileH)+game.tileH/2;
char.width = char.clip._width/2;
char.height = char.clip._height/2;
char.clip._x = char.x;
char.clip._y = char.y;La première ligne attache un nouveau MovieClip de la bibliothèque dans game.clip (vous vous rappellez que nous sauvegardons le chemin pour _root.tiles comme game.clip dans le dernier chapitre) et donne le nom "char".
Après nous enregistrons le chemin du MovieClip char dans l’objet char. A chaque fois que nous voulons accéder au clip, nous pouvons simplement utiliser char.clip à la place de taper le nom complet du chemin du clip _root.tiles.char. Cela nous permet également de ne pas devoir parcourir tout le code pour modifier le nom si nous devons déplacer le clip vidé à un autre endroit.
Nous allons ensuite calculer deux propriétés dans l’objet char : x et y. Vous pouvez vous demander pourquoi est ce que nous avons besoin de plus de propriétés alors que nous avons déjà xtile et ytile. Rappelez-vous, les propriétés xtile et ytile compte le nombre de tiles et pas véritablement des pixels. Les propriétés x et y vont contenir les coordonnées des pixels du MovieClip du personnage. C‘est une bonne idée d’avoir les coordonnées dans des variables avant de placer le MovieClip, vous pourriez avoir besoin de changer de position parce que le héro a heurté le mur ou perdu l’équilibre et c’est plus facile de changer les variables que les propriétés _x/_y.
Nous allons calculer la position actuelle de notre héros en multipliant le nombre de la tile sur lequel il se trouve par la largeur des tiles et ajouter la moitié de la taille d’une tile pour placer le personnage au centre de la tile. Nous aurons donc char.xtile * game.tileW qui nous donnera le nombre de tiles à l’horizontal multiplié par la largeur de la tile venant de notre objet game.
Ensuite nous sauvegardons la moitié du la largeur et de la hauteur du MovieClip de notre héros dans l’objet char. Ils deviendront très utiles quand nous calculerons où sont les limites du héros. Notez que vous pouvez créer vos propres limites, vous n’êtes pas obligé d’utiliser la largeur et la hauteur du clip vidéo. Certains héros peuvent avoir une longue touffe de cheveux qui peuvent se heurter aux murs. Dans ce cas, déclarez vos propres variables pour la hauteur et la largeur.
Les deux dernières lignes placent le clip du personnage, char.clip, aux coordonnées que nous avons calculé plus tôt en tant que x et y.
Ecrit par Quintoff




