LevelManager - Utilisation de base - Partie 03

< < LevelManager - Utilisation de base - Partie 02

Tutoriels

LevelManager - Utilisation de base - Partie 04 > >


Dans ce tutoriel, vous serez initiés à la gestion des objets.

 

Tout d'abord, il faut savoir que notre carte contient 9 objets répartis dans 2 groupes :

Le dernier objet, "Ellipse", étant une forme, il n'a aucun affichage à l'écran. J'ai pour habitude de m'en servir comme déclencheur.
C'est ce que j'ai fait dans mon jeu Floor is Lava où, en entrant en collision avec un objet de type forme, un chronomètre se déclenche.

 

Affichage de la carte

On va repartir à partir d'un affichage de la carte centrée.

 

-- The lines below is used for debugging.
if arg[#arg] == "-debug" then require("mobdebug").start() end
io.stdout:setvbuf('no')
love.graphics.setDefaultFilter("nearest")

-- Chargement du LevelManager
local LevelManager = require("LevelManager")

-- Dimensions de l'écran
local screenWidth = love.graphics.getWidth()
local screenHeight = love.graphics.getHeight()

function love.load()
  -- Chargement de la carte
  LevelManager:load("datas/map01")
  
  -- Application du décalage sur la carte
  LevelManager:centerMap(screenWidth / 2, screenHeight / 2)
end
--

function love.update(dt)
end
--

function love.draw()
  LevelManager:draw()
end
--

-- Cette fonction n'est pas obligatoire
function love.keypressed(key)
  -- Quitter le jeu
  if key == "escape" then
    love.event.quit(0)
  end
end
--

 

Lorsque l'on affiche la carte, nous avons 2 personnages : un en haut à gauche face à nous et un en bas à droite et de dos.
Celui en haut et à gauche est Player1 et l'autre, Player 2.

 

Vous devriez obtenir ceci (sans les textes hein 😉) :

 

Récupération des objets

Il existe plusieurs façons pour récupérer un objet dans la carte :

  1. par son nom avec la fonction getObjectByName
  2. par sa position dans la grille avec la fonction getObjectsOnGrid
  3. par ses coordonnées avec la fonction getObjectsAtCoord
  4. par son appartenance à un groupe avec la fonction getObjectsInGroup
  5. par sa classe avec la fonction getAllObjectsByClass
  6. par un de ses propriétés avec la fonction getAllObjectsByProperty
  7. par sa forme avec la fonction getAllObjectsByShape

 

Récupérer un objet par son nom

C'est la façon que je vous conseille de toujours utiliser.
Premièrement, parce que c'est la façon la plus facile de le faire et deuxièmement, parce que vous n'avez pas à parcourir une liste d'objet pour récupérer celui qui vous intéresse.

Voici comment le faire :

Player1 = LevelManager:getObjectByName("Player1")

 

Récupérer des objets à partir d'une position dans la grille

La fonction getObjectsOnGrid recherche tous les objets qui sont positionnés à la ligne Row et la colonne Col.

Cette fonction retourne toujours une liste d'objets. C'est ensuite à vous de parcourir cette liste pour trouver le ou les objets qui vous intéressent vraiment.

Voici comment l'utiliser :

listObjects = LevelManager:getObjectsOnGrid(7, 9)

 

Dans notre carte, listObject va contenir 2 objets : l'objet Panel et l'objet Flower.

 

 

Récupérer des objets à partir d'une coordonnée

La fonction getObjectsAtCoord recherche tous les objets qui sont à la coordonnée X et  Y.

Cette fonction retourne toujours une liste d'objets. C'est ensuite à vous de parcourir cette liste pour trouver le ou les objets qui vous intéressent vraiment.

Voici comment l'utiliser :

listObjects = LevelManager:getObjectsAtCoord(520, 450)

 

Dans notre carte, listObject va contenir 2 objets : l'objet Panel et l'objet Flower.

 

 

Récupérer des objets d'un groupe donné

La fonction getObjectsInGroup recherche tous les objets qui appartiennent au groupe passé en paramètre.
Cette information est calculée lors du chargement de la carte.

Cette fonction retourne toujours une liste d'objets. C'est ensuite à vous de parcourir cette liste pour trouver le ou les objets qui vous intéressent vraiment.

Voici comment l'utiliser :

listObjects = LevelManager:getObjectsInGroup("Objects")

 

Dans notre carte, listObject va contenir 5 objets : l'objet Player1, l'objet Player2, l'objet Panel, l'objet Flower et l'objet Ellipse.

 

 

Récupérer des objets d'une classe donnée

La fonction getAllObjectsByClass recherche tous les objets qui appartiennent à la classe passée en paramètre.

Cette fonction retourne toujours une liste d'objets. C'est ensuite à vous de parcourir cette liste pour trouver le ou les objets qui vous intéressent vraiment.

Voici comment l'utiliser :

listObjects = LevelManager:getAllObjectsByClass("Panel")

 

Dans notre carte, listObject va contenir 2 objets : l'objet Panel et l'objet Flower.

 

 

Récupérer des objets avec une propriété donnée

La fonction getAllObjectsByProperty recherche tous les objets qui possède la propriété passée en paramètre (avec sa valeur).

Cette fonction retourne toujours une liste d'objets. C'est ensuite à vous de parcourir cette liste pour trouver le ou les objets qui vous intéressent vraiment.

Voici comment l'utiliser :

listObjects = LevelManager:getAllObjectsByProperty("Teleport", "6")

 

Dans notre carte, listObject va contenir un unique objet : l'objet Warp4-1.

 

Cette fonction a une particularité : si on ne renseigne pas le paramètre Value (valeur nil), on recherche tous les objets ayant la propriété donnée.

listObjects = LevelManager:getAllObjectsByProperty("Teleport")

 

Dans notre carte, listObject va contenir 4 objets : l'objet Warp1-2, l'objet Warp2-3, l'objet Warp3-4 et l'objet Warp4-1

 

 

Récupérer des objets d'une forme (shape) donnée

La fonction getAllObjectsByShape recherche tous les objets qui appartiennent à la forme (shape) passée en paramètre.

Cette fonction retourne toujours une liste d'objets.

Voici comment l'utiliser :

listObjects = LevelManager:getAllObjectsByShape("ellipse")

 

Dans notre carte, listObject va contenir 1 seul objet : l'objet Ellipse.

C'est ensuite à vous de parcourir cette liste pour trouver le ou les objets qui vous intéressent vraiment.

Attention ! Tous les objets ont comme forme par défaut la valeur rectangle.

Donc si vous recherchez tous les objets dont la forme est rectangle, vous pourriez vous retrouver avec tous les objets de votre carte.

 

 

Récupération et déplacement des joueurs

La récupération des joueurs étant tellement simple, on va en profiter pour les faire bouger.

 

En premier lieu, nous allons créer 2 variables pour contenir les objets :

-- Variables
local Player1 = {}
local Player2 = {}

 

Ensuite, dans la fonction love.load, après la fonction LevelManager:centerMap, nous allons récupérer les deux joueurs :

-- Récupération des Players
Player1 = LevelManager:getObjectByName("Player1")
Player2 = LevelManager:getObjectByName("Player2")

 

Voilà, nous avons récupéré nos joueurs. Tellement simple non ? 😁

Bon, maintenant, nous allons faire qu'on puisse les déplacer au clavier.

 

On va créer une nouvelle fonction que l'on va nommer MovePlayer.
Cette fonction prendra en paramètre le joueur et les noms des touches de directions.

Ensuite, on va vérifier si la touche utilisée pour aller vers le haut est appuyée. Puis, on va déplacer notre joueur en changeant sa coordonnée en Y.

On va faire pareil pour le touche utilisée pour aller vers le bas.

Pour la gauche et le droite, c'est pareil mais en changeant la coordonnée du joueur en X.

local function MovePlayer(player, up, down, left, right)
  if love.keyboard.isDown(up) then
    player.y = player.y - 1
  elseif love.keyboard.isDown(down) then
    player.y = player.y + 1
  end
  if love.keyboard.isDown(left) then
    player.x = player.x - 1
  elseif love.keyboard.isDown(right) then
    player.x = player.x + 1
  end
end

 

Enfin, on va appeler cette fonction dans love.update pour chacun des joueurs :

-- Déplacement des joueurs
MovePlayer(Player1, "w", "s", "a", "d") -- ATTENTION ! Ici, j'utilise un clavier qwerty
MovePlayer(Player2, "up", "down", "left", "right")

 

Maintenant, vous pouvez déplacer vos joueurs sans souci.

 

Changer l'image d'un objet

Dans le jeu de tuiles Character, il y a plusieurs représentation de notre joueur.

On va juste faire en sorte que notre joueur soit orienté vers la direction où on se déplace.

 

Pour changer l'image d'un objet, il nous faut l'id de l'image dans le jeu de tuile.

Pour connaître l'id de l'image, il n'y a pas d'autre choix que d'ouvrir le fichier lua de la carte.

Dans notre cas, pour l'objet Player1, son id est 199 (image de gauche). Et pour l'objet Player2, son id est 208 (image de droite).

 

Ne cherchez pas dans Tiled, vous n'obtiendrez que l'id de l'image dans le jeu de tuile, pas l'id dans la totalité des jeux de tuiles.

On aurait aussi pu utiliser la fonction getImageId qui retourne l'id de l'image de l'objet passé en paramètre.

 

On va modifier notre fonction MovePlayer pour lui rajouter 4 nouveaux paramètres : idup, iddown, idleft, idright.
Ces 4 paramètres vont contenir les ids des images.

 

 

Pour l'objet Player1, on va utiliser les 4 images de la même rangée. Idem pour le Player2.
Vous devriez avoir ceci :

local function MovePlayer(player, up, down, left, right, idup, iddown, idright, idleft)

 

Ensuite, il ne nous reste plus qu'à changer l'id de l'image de l'objet.

Après la mise à jour de la coordonnée Y lorsque la touche up est appuyée (love.keyboard.isDown), on change l'id comme suit :

LevelManager:setImageId(player, idup)

 

Il ne vous reste plus qu'à faire la même chose pour les 3 autres directions.

Enfin, on va modifier les appels de la fonction MovePlayer dans love.update :

-- Déplacement des joueurs
MovePlayer(Player1, "w", "s", "a", "d", 200, 199, 201, 202)
MovePlayer(Player2, "up", "down", "left", "right", 208, 207, 209, 210)

Faites attention à l'ordre des images !
Dans notre jeu de tuile, c'est l'image pour aller vers le bas qui est en premier, suivie par l'image pour aller vers le haut.

 

Voici le résultat attendu :

 

 

Restaurer les objets

Si on a besoin de restaurer les valeurs d'origine d'un objet, il suffit d'appeler la fonction LevelManager:restoreObject qui prend en paramètre l'objet concerné.

Cette fonction ne restaure que les données suivantes :

Toutes les autres informations ne sont pas restaurées.
Si vous faites des changements, c'est à vous de conserver les données pour les restaurer.

 

On va restaurer la position des joueurs si on appuye sur la touche 1 ou 2 correspondant au joueur.

Dans la fonction love.keypressed, on va rajouter les lignes suivantes :

-- Restauration de la position des joueurs
if key == "1" then
  LevelManager:restoreObject(Player1)
end
if key == "2" then
  LevelManager:restoreObject(Player2)
end

 

Maintenant, après avoir déplacé vos joueurs, si vous appuyez sur la touche 1 ou 2, le joueur se retrouvera à sa position de départ.

 

Il existe deux autres façons de restaurer les objets.
Cependant, elles ont un effet plus important que juste traiter un seul objet :

On pourrait utiliser la fonction restoreObjects pour un jeu de Sokoban pour rejouer un niveau par exemple.

 

Pour la fonction reload, cela peut être nécessaire si vous avez modifié certaines données dans de nombreux calques.
Mais elle a une conséquence qui est de forcer la création d'un nouveau canvas, ce qui peut prendre un certain temps selon la dimension de la carte.
On verra au prochain tutoriel que ce n'est pas la seule.

 

Pensez à toujours privilégier les fonctions ciblant un item (objet ou calque) plutôt que des fonctions générales !

 



< < LevelManager - Utilisation de base - Partie 02

Tutoriels

LevelManager - Utilisation de base - Partie 04 > >