Solarus Wiki

A wiki for the Solarus engine community

Outils pour utilisateurs

Outils du site


fr:tutorial:lost_woods

Chap. 12Chap. 14Sommaire

Chapitre 13 : Les Bois Perdus

Dans ce chapitre, nous allons apprendre à faire des Bois Perdus de façon très efficace grâce aux capteurs.

Ressources

De nouvelles ressources sont nécessaires pour ce chapitre : il s'agit de la map des Bois Perdus ainsi que la nouvelle transition sur la map B2 pour y accéder.

Comme d'habitude, vous pouvez aussi télécharger directement l'archive data ayant déjà reçu toutes ces modifications et qui contient aussi les résultats des précédents chapitre.

Comment créer une map

Voici à quoi ressemble la map fournie des Bois Perdus. Comme vous pouvez le constater, elle est relativement vide et assez répétitive, mais c'est clairement volontaire.

Il existe plusieurs types de Bois Perdus, il y a le plus simple qui consiste en une multitude de croisements et si le joueur prend le mauvais, il est ramené au début de la map. Plusieurs méthodes : soit vous lui indiquez explicitement qu'il s'est trompé par un message ou un son, soit vous le téléportez à un autre endroit qui le perd encore plus. Dangereux car certains joueurs n'aimeront pas trop ne pas savoir s'ils avancent ou s'ils reculent. Voici un exemple (il s'agit plus d'une esquisse que d'une véritable map : il manque les fleurs, les arbustes, etc…)

Mais les Bois concernés par ce chapitre ne sont pas de cet acabit. En effet, si vous êtes observateur, vous remarquerez que 3 zones se répètent à l'identique. L'idée va être de téléporter de façon totalement invisible le joueur d'une zone à l'autre lorsqu'il activera des capteurs. Cela donne une notion d'infinité à la map (ou en tout cas d'une grandeur exagérée comparé à la taille réelle de la map), et le joueur pourra désactiver ces capteurs soit après des passages clés du jeu (exemple : un donjon terminé), soit en finissant une quête (exemple : donner un objet à un personnage).

La façon de construire ce genre de Bois est assez prise de tête lorsqu'on ne maîtrise pas le mapping, aussi essayez-vous d'abord sur une map relativement petite. L'idée est de faire l'entrée de la map puis ensuite de faire la zone que vous voudrez répéter. N'oubliez pas que cette zone doit être plus grande que votre résolution max de votre quête ! Dans la map fournie par exemple, cela ne fonctionnera pas tout le temps sur une fenêtre de résolution 400*240 (format console portable). Le minimum est de 320*240, donc la zone que vous voudrez répéter devra toujours être au moins égale, idéalement supérieure à ces dimensions.

Une fois cette zone terminée, copiez-la ailleurs sur la map. Faites cela pour toutes les zones que vous voudrez répéter, en veillant à ce que les zones puisse se rejoindre (la grille vous permettra de bien positionner vos copies, n'oubliez pas que les tiles de talus font la taille d'un carré, donc 16*16 pixels… Si vous décalez la copie de 8 pixels vous êtes bon pour refaire la moitié de la map !). Lorsque vous aurez terminé, réalisez le reste de la map.

Conseils

  • Évitez de mettre le chemin de répétition de votre zone trop proche du bord de la map. La caméra se bloquant sur ces bords, lorsque le joueur sera téléporté le héros sera de nouveau centré et cela fera un effet bizarre.
  • Ne placez pas d'ennemis (pour le moment nous ne savons pas en faire, mais dans tous les cas ce n'est pas une bonne idée) : ceux-ci bougeant d'eux-mêmes, il faudrait que vous les synchronisiez tous pour qu'une transition invisible ne soit pas ratée par un ennemi qui pope d'un coup. Si vous voulez absolument mettre des ennemis, arrangez-vous pour aménager des “zones de combat” qui n'empiètent pas sur vos zones de téléportation grâce à des murs invisibles.
  • Dans un premier temps, ne mettez pas non plus de destructibles dans les zones de téléportation, contentez-vous de décors statiques : lorsque vous aurez un peu mieux assimilé les mécaniques des Bois Perdus, vous pourrez mettre des destructibles qui devront aussi être gérés par la programmation (en les détruisant à un endroit, il faut obligatoirement que son jumeau à l'autre endroit soit détruit aussi sinon nous aurons encore une fois droit à un élément qui pope et qui rate l'effet invisible)
  • Veillez à ce qu'il soit toujours possible de revenir au début : si vous avez deux passages pour retourner à l'entrée et que les deux sont bloqués par des téléportations, vous bloquerez le joueur.

Gérer les capteurs

Les Capteurs (en anglais Sensors) sont gérés par l'icône à côté de celle des murs invisibles : ils sont représentés par un “?”. Ils sont extensibles et extrêmement polyvalents. Ils vous permettent de faire ce que ferait un bouton en règle général mais en plus complexe. De plus, un capteur ne peut être esquivé, contrairement aux boutons qui peuvent être ignorés (grâce à la Plume ou un recul dû à un coup ennemi).

Dans notre cas, il n'aurait pas été possible non plus de réaliser l'énigme via un téléporteur car même si ces derniers permettent une transition immédiate et sont extensibles, ils ne peuvent aller que sur une destination qui elle-même fait une taille fixe de 16*16 (bord de la map mis à part).

Placez deux capteurs comme indiqué sur le screen suivant, et nommez celui de gauche hidden_sensor puis celui de droite de même (l'éditeur s'occupera de lui-même d'ajouter le suffixe _2 au nom).

Programmons-les maintenant. Ce que nous voulons, c'est que lorsque le héros atteint celui de gauche, il soit téléporté sur celui de droite de façon invisible. Pour cela, nous avons trois méthodes que nous allons utiliser : le on_activated du sensor, le get_position des entités de map, et le set_position des entités de la map (en l'occurrence, le héros).

Ouvrez le fichier de map et écrivez le code suivant.

local map = ...
 
function hidden_sensor:on_activated()
  local hero_x, hero_y = hero:get_position()
  local hidden_sensor_x, hidden_sensor_y = hidden_sensor:get_position()
  local hidden_sensor_2_x, hidden_sensor_2_y = hidden_sensor_2:get_position()
 
  hero:set_position(hero_x + hidden_sensor_2_x - hidden_sensor_x, hero_y + hidden_sensor_2_y - hidden_sensor_y)
end

Comme vous pouvez le constater, ce code est très simple sans être moins puissant pour autant. Lorsque le héros active le capteur, nous récupérons la position du héros, du capteur sur lequel il est (n'oubliez pas que le capteur a son point d'origine en 0*0 et qu'il est extensible, d'où la nécessité d'avoir sa position pour le calcul car le héros peut être n'importe où sur ce capteur), et la position du capteur sur lequel on veut le téléporter. Le reste est une simple petite opération mathématique : on veut que le héros se décale de la distance entre le hidden_sensor_2 et le hidden_sensor. L'opération dans l'autre sens vous aidera peut-être un peu plus : on veut que le héros soit téléporté au coin haut gauche de la map (d'où le retrait des coordonnées du hidden_sensor), puis on lui ajoute les coordonnées du hidden_sensor_2 pour le mettre dessus.

Désormais, vous pouvez ajouter de vous-même les divers capteurs qu'il manque et les coder. N'oubliez pas qu'ils doivent être à peu près au centre des zones.

Afin d'éviter la répétition de code (car c'est le Mal), nous allons réaliser une fonction qui prendra en paramètre le capteur à retirer des coordonnées et celui à rajouter, et nous l'appellerons simplement sur certains capteurs (pas tous pour la raison évoqué un peu plus haut : il faut une porte de sortie pour le joueur). Voici le contenu du fichier avec cette fonction et les trois nouvelles zones.

local map = ...
 
local function teleport_sensor(to_sensor, from_sensor)
  local hero_x, hero_y = hero:get_position()
  local to_sensor_x, to_sensor_y = to_sensor:get_position()
  local from_sensor_x, from_sensor_y = from_sensor:get_position()
 
  hero:set_position(hero_x - from_sensor_x + to_sensor_x, hero_y - from_sensor_y + to_sensor_y)
end
 
function hidden_sensor:on_activated()
  teleport_sensor(hidden_sensor_2, self)
end
 
function hidden_sensor_3:on_activated()
  teleport_sensor(hidden_sensor_4, self)
end
 
function hidden_sensor_5:on_activated()
  teleport_sensor(hidden_sensor_6, self)
end

Rappel : le mot-clé self est le premier paramètre (caché) sur les méthodes d'objet utilisant : et font référence à l'objet appelant.

Exercice

Maintenant que les téléportations sont devenues une formalité, essayons de corser un peu les Bois en tant que créateur de map et non en tant que joueur. Nous allons y placer des herbes que le joueur pourra détruire. Lorsque le joueur les détruira, leurs potentielles jumelles devront aussi être détruites. Mettez-en autant qu'il vous plaira mais veillez à ne pas être trop gourmand.

Correction

Et enfin voici une des solutions possibles. Nous avons fait un peu différemment cette fois-ci car nous avons utilisé une méthodologie assez répandue dans Zelda Mystery of Solarus DX : nous faisons une boucle for pour chaque groupe d'entités qui nous intéresse, et nous désactivons toutes les entités restantes du groupe. Cela permet de ne pas se soucier du nombre d'herbes à détruire. Vous remarquerez que ce sont des herbes et non pas des plantes que nous avons mis, mais même les plantes auraient pu convenir car en les soulevant, la méthode on_removed est tout de même appelée.

Version 1.1+

Attention : la méthodologie utilisée dans ce chapitre n'est valable que pour la version 1.0, en version 1.1 la façon de boucler sur les entités a été revu et il faut faire for entity in map:get_entities(“nom”) ! Adaptez le code si besoin est.

Chap. 12 : Bouton débloquant un coffreChap. 14 : Les RubisSommaire

fr/tutorial/lost_woods.txt · Dernière modification: 2018/12/22 14:14 (modification externe)