Aujourd'hui, je vais vous apprendre comment je gère mes tilesets, du moins d'un point de vue ressources. Je pourrai vous expliquer ça d'un point de vue programmation dans un futur billet si ça vous intéresse.
Tout d'abord, une petite définition personnel : un tileset est un ensemble de tiles, qui se traduit par tuile en français. Holyspirit est composé de "tuiles",[...]
Aujourd'hui, je vais vous apprendre comment je gère mes tilesets, du moins d'un point de vue ressources. Je pourrai vous expliquer ça d'un point de vue programmation dans un futur billet si ça vous intéresse.
Tout d'abord, une petite définition personnel : un tileset est un ensemble de tiles, qui se traduit par tuile en français. Holyspirit est composé de "tuiles", correspondant en fait aux petites images qui composent la partie graphique du jeu.
Nous pouvons avoir toutes sortes de tiles : des tiles pour des décors (sols, murs, arbres, ...), pour des personnages, pour des effets de sorts (ou miracles dans Holyspirit), ...
Dans cet article, je vais principalement détailler le fonctionnement des tilesets de décors, puis je vous expliquerai rapidement comment ça marche pour les personnages et miracles.
Un tileset de décor est composé simplement d'un fichier *.ts.hs, ainsi que d'une ou plusieurs images de ce genre :
Exemple de fichier *.ts.hs, celui qui va avec l'image ci-dessus.
*Data/Landscapes/Misc/smallCart.png
$
$
*x0 y0 w192 h128 ex126 ey64 i0 c1 z1 vPetitChariotDetruit $
*x192 y0 w192 h128 ex126 ey64 i0 c1 z1 vPetitChariot $
$
Les plus malins d'entre vous l'auront tout de suite compris, le fichier est décomposé en 3 parties.
La première contenant la liste des chemins des images, la seconde, même si l'on ne le voit pas ici, la liste des chemins des sons et la dernière, la liste des tiles.
Je ne penses pas devoir donner des informations sur les deux premières parties, on a simplement "*Chemin". En programmation, je récupère le chemin et ajoute à mon objet tileset l'ID de l'image dans le moteur graphique, idem pour le son.
Pour la liste des tiles, vous pouvez retrouver le même genre de structure que dans les miracles, donc des blocs ouverts par '*' et fermés par '$', avec des lettres pour indiquer le type de l'information, chacun de ces blocs correspondant à un tile, à un décor.
'x' et 'y' pour la position en pixels dans l'image du tile et 'w' et 'h' pour la largeur et la hauteur du tile.
'ex' et 'ey' c'est la position du centre du tile. En gros, si le décor est placé à la position 32 en x et 48 en y, ce sera le pixel de l'image en 'ex' et 'ey' qui s'y trouvera. C'est donc l'origine du tile. C'est aussi utile pour placer le centre de rotation du tile, pour l'ombre.
'i' pour le numéro de l'image dans le tileset. Ici, nous avons qu'une seule image qui compose ce tileset, donc c'est l'image 0. (On commence à 0).
'c' pour dire qu'il y a collision sur l'élément. Le personnage ne peut donc pas le traverser. Pour ne pas mettre de collision, on aurait eut 'c0' ou rien du tout.
'z' ça n'a aucune utilité pour le jeu lui-même, mais c'est pour l'éditeur. Ça veut dire que si, dans l'éditeur, je sélectionne ce tile, il me le place en par défaut sur la couche n°1, donc celle à hauteur des personnages.
'v' n'a aussi aucune utilité pour le jeu, mais permet de mieux s'y retrouver dans l'éditeur. C'est le nom associé au tile.
C'est tout pour ce tileset-ci, mais il existe encore de nombreux autres types d'informations.
Passons à un autre exemple de tileset :
*Data/Landscapes/Misc/Lantern.png
$
$
*x0 y0 w192 h192 i0 o1 c1 z1 ex83 ey168 lr255 lv200 lb81 li128 $
$
Vous avez comme nouvel élément : lr255 lv200 lb81 li128
Ça, c'est simplement pour indiquer que le tile émet une lumière. Les composantes RGB sont données par lr, lv et lb, ainsi que l'intensité, qui définit le rayon de la lumière, par li.
Tile tiré d'un tileset d'arbres :
*Data/Landscapes/Trees/Trees.png
*Data/Menus/MinimapIcones.png
$
$
*x0 y0 w384 h384 i0 c1 o1 f1 ey342 z1 vBouleau m i1 x48 y32 w16 h16 $ $
$
Vous avez le 'f' qui signifie que le tile est réfléchi dans l'eau.
Le 'o' permet de dire que le tile possède une ombre.
Voyez le m i1 x48 y32 w16 h16 $, c'est pour dire que le tile possède aussi une image sur la minimap.
Niveau fonctionnement, c'est comme avoir un tile dans un tile, si ce n'est que le bloc est délimité par 'm' et '$'.
NB : Le 'i1', on est donc sur la seconde image du tileset, soit :
En jeu, nous obtenons ceci :
Maintenant, un tileset de feu de camp :
*Data/Landscapes/Campfire/Campfire.png
*Data/Landscapes/Fire/Campfire_distortion.png
$
* mData/Sounds/Feu.wav $
$
Feu de camp
*x0 y0 w128 h128 i0 c1 a1 s0 lr236 lv136 lb36 li255 lh0 j x0 y0 ey160 w128 h128 i1 $ $
*x128 y0 w128 h128 i0 c1 a2 s0 lr236 lv136 lb36 li245 lh0 j x128 y0 ey160 w128 h128 i1 $ $
*x256 y0 w128 h128 i0 c1 a3 s0 lr236 lv136 lb36 li235 lh0 j x256 y0 ey160 w128 h128 i1 $ $
*x384 y0 w128 h128 i0 c1 a4 s0 lr236 lv136 lb36 li245 lh0 j x384 y0 ey160 w128 h128 i1 $ $
*x512 y0 w128 h128 i0 c1 a5 s0 lr236 lv136 lb36 li255 lh0 j x512 y0 ey160 w128 h128 i1 $ $
*x640 y0 w128 h128 i0 c1 a6 s0 lr236 lv136 lb36 li245 lh0 j x640 y0 ey160 w128 h128 i1 $ $
*x768 y0 w128 h128 i0 c1 a7 s0 lr236 lv136 lb36 li255 lh0 j x768 y0 ey160 w128 h128 i1 $ $
*x896 y0 w128 h128 i0 c1 a0 s0 lr236 lv136 lb36 li255 lh0 j x896 y0 ey160 w128 h128 i1 $ $
$
Notez le 'a', c'est simplement le n° de la prochaine image dans l'animation du tile. Le tile devient donc un autre tile parmi la liste quand le temps est écoulé. Ce temps est par défaut de 0.075 secondes. Mais il peut être modifié par 'n'.
Vous pouvez aussi remarquer le 's' pour le n° du son joué.
Enfin, vous avez le j x768 y0 ey160 w128 h128 i1 $
En fait, c'est une image qui est utilisée pour donner un effet de distorsion sur l'écran via un shader, afin de donner une impression de chaleur. Je ne vais pas trop approfondir ce sujet, ce n'est pas le but de ce billet.
Il est définit de la même manière que pour la minimap, mais avec un 'j' au lieu d'un 'm'.
Je ne vais plus donner d'exemple, mais vous pouvez encore avoir :
't' : le tile devient transparent si le héros passe derrière, utile pour des tiles qui prennent beaucoup de place à l'écran ou des murs dans des donjons.
'p' : permet de modifier l'opacité du tile. Surtout utilisé pour des effets de miracles qui disparaissent petit à petit.
'd' : cette information n'est utilisée que dans les personnages. Elle peut valoir -1, 0, 1 ou 2. En gros, elle permet de définir à quel moment dans l'animation le personnage inflige des dégâts, quand il a fini de frapper, etc.
'g' : cette information n'est utilisée que pour le héros. Je ne vais rien expliquer ici car ça fera l'objet d'un prochain billet qui expliquera comment je fais pour que, suivant les objets que le héros porte, ses graphismes changent.
'r' : il peut valoir x, y, g, d, b, h, ... En gros, tout ce que vous avez besoin de savoir c'est que ça définit l'orientation des murs pour bloquer la lumière. Si je fais un billet sur mon moteur de lumières, je vous expliquerai tout ça plus en détails.
'k' : dans le même genre que 'm' pour la minimap et 'j' pour les distortions, 'k' est l'image de la shadowmap du tile. En gros, c'est utilisé pour assombrir des morceaux du tile suivant l'orientation du soleil.
Pour ça, j'utilise une autre information, 'b' qui est l'angle. Je compare cet angle avec l'angle du soleil et en fonction de ça, je modifie l'opacité de la shadowmap que j'applique sur le décor. Je peux avoir plusieurs shadowmap pour un même tile.
Exemple :
Enfin, si vous vous souvenez, dans le billet sur les miracles, nous avions des séquences. Vous pourrez remarquer que ces séquences ne sont autre que des tilesets, possédant exactement la même structure.
Pour les personnages, c'est un petit peu différent. En effet, vous avez juste un fichier .rs.hs qui contient le .ts.hs et les images. C'est donc une forme de fichier *.dat.
Par ailleurs, le .ts.hs est un petit peu différent.
Vous avez toujours la liste des images, liste des sons et puis des tiles, mais avec quelques nuances.
Tout d'abord, la liste des sons est maintenant comme ceci :
Liste des chemins de tous les sons
* mData/Sounds/9906__Snoman__grass3.wav $
* mData/Sounds/14609__man__swosh.wav $
* mData/Sounds/punch.wav n0 $
$
En effet, vous pouvez avoir une information 'n', à 0, cela signifie que le son est joué quand le personnage est touché par une attaque.
Quant aux tiles, ils vont par blocs de 8 blocs. En gros, ça veut dire que vous avez une liste de tile par direction, donc 8 listes. Et ces 8 listes sont elles même séparées en différents blocs qui représentent les états du personnage, donc à l'arrêt, qui marche, qui frappe, qui meurt, qui lance un miracle, ...
Le code permet de mettre autant d'états qu'on le souhaite, si on veut faire plusieurs animations différentes suivant les miracles lancés.
C'est tout pour aujourd'hui. Si vous avez des questions ou remarques, n'hésitez pas.
Tout d'abord, une petite définition personnel : un tileset est un ensemble de tiles, qui se traduit par tuile en français. Holyspirit est composé de "tuiles", correspondant en fait aux petites images qui composent la partie graphique du jeu.
Nous pouvons avoir toutes sortes de tiles : des tiles pour des décors (sols, murs, arbres, ...), pour des personnages, pour des effets de sorts (ou miracles dans Holyspirit), ...
Dans cet article, je vais principalement détailler le fonctionnement des tilesets de décors, puis je vous expliquerai rapidement comment ça marche pour les personnages et miracles.
Un tileset de décor est composé simplement d'un fichier *.ts.hs, ainsi que d'une ou plusieurs images de ce genre :
Exemple de fichier *.ts.hs, celui qui va avec l'image ci-dessus.
*Data/Landscapes/Misc/smallCart.png
$
$
*x0 y0 w192 h128 ex126 ey64 i0 c1 z1 vPetitChariotDetruit $
*x192 y0 w192 h128 ex126 ey64 i0 c1 z1 vPetitChariot $
$
Les plus malins d'entre vous l'auront tout de suite compris, le fichier est décomposé en 3 parties.
La première contenant la liste des chemins des images, la seconde, même si l'on ne le voit pas ici, la liste des chemins des sons et la dernière, la liste des tiles.
Je ne penses pas devoir donner des informations sur les deux premières parties, on a simplement "*Chemin". En programmation, je récupère le chemin et ajoute à mon objet tileset l'ID de l'image dans le moteur graphique, idem pour le son.
Pour la liste des tiles, vous pouvez retrouver le même genre de structure que dans les miracles, donc des blocs ouverts par '*' et fermés par '$', avec des lettres pour indiquer le type de l'information, chacun de ces blocs correspondant à un tile, à un décor.
'x' et 'y' pour la position en pixels dans l'image du tile et 'w' et 'h' pour la largeur et la hauteur du tile.
'ex' et 'ey' c'est la position du centre du tile. En gros, si le décor est placé à la position 32 en x et 48 en y, ce sera le pixel de l'image en 'ex' et 'ey' qui s'y trouvera. C'est donc l'origine du tile. C'est aussi utile pour placer le centre de rotation du tile, pour l'ombre.
'i' pour le numéro de l'image dans le tileset. Ici, nous avons qu'une seule image qui compose ce tileset, donc c'est l'image 0. (On commence à 0).
'c' pour dire qu'il y a collision sur l'élément. Le personnage ne peut donc pas le traverser. Pour ne pas mettre de collision, on aurait eut 'c0' ou rien du tout.
'z' ça n'a aucune utilité pour le jeu lui-même, mais c'est pour l'éditeur. Ça veut dire que si, dans l'éditeur, je sélectionne ce tile, il me le place en par défaut sur la couche n°1, donc celle à hauteur des personnages.
'v' n'a aussi aucune utilité pour le jeu, mais permet de mieux s'y retrouver dans l'éditeur. C'est le nom associé au tile.
C'est tout pour ce tileset-ci, mais il existe encore de nombreux autres types d'informations.
Passons à un autre exemple de tileset :
*Data/Landscapes/Misc/Lantern.png
$
$
*x0 y0 w192 h192 i0 o1 c1 z1 ex83 ey168 lr255 lv200 lb81 li128 $
$
Vous avez comme nouvel élément : lr255 lv200 lb81 li128
Ça, c'est simplement pour indiquer que le tile émet une lumière. Les composantes RGB sont données par lr, lv et lb, ainsi que l'intensité, qui définit le rayon de la lumière, par li.
Tile tiré d'un tileset d'arbres :
*Data/Landscapes/Trees/Trees.png
*Data/Menus/MinimapIcones.png
$
$
*x0 y0 w384 h384 i0 c1 o1 f1 ey342 z1 vBouleau m i1 x48 y32 w16 h16 $ $
$
Vous avez le 'f' qui signifie que le tile est réfléchi dans l'eau.
Le 'o' permet de dire que le tile possède une ombre.
Voyez le m i1 x48 y32 w16 h16 $, c'est pour dire que le tile possède aussi une image sur la minimap.
Niveau fonctionnement, c'est comme avoir un tile dans un tile, si ce n'est que le bloc est délimité par 'm' et '$'.
NB : Le 'i1', on est donc sur la seconde image du tileset, soit :
En jeu, nous obtenons ceci :
Maintenant, un tileset de feu de camp :
*Data/Landscapes/Campfire/Campfire.png
*Data/Landscapes/Fire/Campfire_distortion.png
$
* mData/Sounds/Feu.wav $
$
Feu de camp
*x0 y0 w128 h128 i0 c1 a1 s0 lr236 lv136 lb36 li255 lh0 j x0 y0 ey160 w128 h128 i1 $ $
*x128 y0 w128 h128 i0 c1 a2 s0 lr236 lv136 lb36 li245 lh0 j x128 y0 ey160 w128 h128 i1 $ $
*x256 y0 w128 h128 i0 c1 a3 s0 lr236 lv136 lb36 li235 lh0 j x256 y0 ey160 w128 h128 i1 $ $
*x384 y0 w128 h128 i0 c1 a4 s0 lr236 lv136 lb36 li245 lh0 j x384 y0 ey160 w128 h128 i1 $ $
*x512 y0 w128 h128 i0 c1 a5 s0 lr236 lv136 lb36 li255 lh0 j x512 y0 ey160 w128 h128 i1 $ $
*x640 y0 w128 h128 i0 c1 a6 s0 lr236 lv136 lb36 li245 lh0 j x640 y0 ey160 w128 h128 i1 $ $
*x768 y0 w128 h128 i0 c1 a7 s0 lr236 lv136 lb36 li255 lh0 j x768 y0 ey160 w128 h128 i1 $ $
*x896 y0 w128 h128 i0 c1 a0 s0 lr236 lv136 lb36 li255 lh0 j x896 y0 ey160 w128 h128 i1 $ $
$
Notez le 'a', c'est simplement le n° de la prochaine image dans l'animation du tile. Le tile devient donc un autre tile parmi la liste quand le temps est écoulé. Ce temps est par défaut de 0.075 secondes. Mais il peut être modifié par 'n'.
Vous pouvez aussi remarquer le 's' pour le n° du son joué.
Enfin, vous avez le j x768 y0 ey160 w128 h128 i1 $
En fait, c'est une image qui est utilisée pour donner un effet de distorsion sur l'écran via un shader, afin de donner une impression de chaleur. Je ne vais pas trop approfondir ce sujet, ce n'est pas le but de ce billet.
Il est définit de la même manière que pour la minimap, mais avec un 'j' au lieu d'un 'm'.
Je ne vais plus donner d'exemple, mais vous pouvez encore avoir :
't' : le tile devient transparent si le héros passe derrière, utile pour des tiles qui prennent beaucoup de place à l'écran ou des murs dans des donjons.
'p' : permet de modifier l'opacité du tile. Surtout utilisé pour des effets de miracles qui disparaissent petit à petit.
'd' : cette information n'est utilisée que dans les personnages. Elle peut valoir -1, 0, 1 ou 2. En gros, elle permet de définir à quel moment dans l'animation le personnage inflige des dégâts, quand il a fini de frapper, etc.
'g' : cette information n'est utilisée que pour le héros. Je ne vais rien expliquer ici car ça fera l'objet d'un prochain billet qui expliquera comment je fais pour que, suivant les objets que le héros porte, ses graphismes changent.
'r' : il peut valoir x, y, g, d, b, h, ... En gros, tout ce que vous avez besoin de savoir c'est que ça définit l'orientation des murs pour bloquer la lumière. Si je fais un billet sur mon moteur de lumières, je vous expliquerai tout ça plus en détails.
'k' : dans le même genre que 'm' pour la minimap et 'j' pour les distortions, 'k' est l'image de la shadowmap du tile. En gros, c'est utilisé pour assombrir des morceaux du tile suivant l'orientation du soleil.
Pour ça, j'utilise une autre information, 'b' qui est l'angle. Je compare cet angle avec l'angle du soleil et en fonction de ça, je modifie l'opacité de la shadowmap que j'applique sur le décor. Je peux avoir plusieurs shadowmap pour un même tile.
Exemple :
Enfin, si vous vous souvenez, dans le billet sur les miracles, nous avions des séquences. Vous pourrez remarquer que ces séquences ne sont autre que des tilesets, possédant exactement la même structure.
Pour les personnages, c'est un petit peu différent. En effet, vous avez juste un fichier .rs.hs qui contient le .ts.hs et les images. C'est donc une forme de fichier *.dat.
Par ailleurs, le .ts.hs est un petit peu différent.
Vous avez toujours la liste des images, liste des sons et puis des tiles, mais avec quelques nuances.
Tout d'abord, la liste des sons est maintenant comme ceci :
Liste des chemins de tous les sons
* mData/Sounds/9906__Snoman__grass3.wav $
* mData/Sounds/14609__man__swosh.wav $
* mData/Sounds/punch.wav n0 $
$
En effet, vous pouvez avoir une information 'n', à 0, cela signifie que le son est joué quand le personnage est touché par une attaque.
Quant aux tiles, ils vont par blocs de 8 blocs. En gros, ça veut dire que vous avez une liste de tile par direction, donc 8 listes. Et ces 8 listes sont elles même séparées en différents blocs qui représentent les états du personnage, donc à l'arrêt, qui marche, qui frappe, qui meurt, qui lance un miracle, ...
Le code permet de mettre autant d'états qu'on le souhaite, si on veut faire plusieurs animations différentes suivant les miracles lancés.
C'est tout pour aujourd'hui. Si vous avez des questions ou remarques, n'hésitez pas.
Par Gregouar - 06/06/2010

4