LevelManager - Utilisation de base - Partie 03
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 :
- Groupe "Warp_Objects"
- Warp1-2
- Warp2-3
- Warp3-4
- Warp4-1
- Groupe "Objects"
- Player1
- Player2
- Panel
- Flower
- Ellipse
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 :
- par son nom avec la fonction
getObjectByName - par sa position dans la grille avec la fonction
getObjectsOnGrid - par ses coordonnées avec la fonction
getObjectsAtCoord - par son appartenance à un groupe avec la fonction
getObjectsInGroup - par sa classe avec la fonction
getAllObjectsByClass - par un de ses propriétés avec la fonction
getAllObjectsByProperty - 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 :
- ses coordonnées X et Y
- sa position dans la grille (ligne et colonne)
- son image
- son opacité
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 :
- la fonction
restoreObjectsqui permet de restaurer tous les objets de la carte - la fonction
reloadqui recharge la carte au complet
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 !
Me contacter