Les objets avec LÖVE2D

Dans le chapitre précédent, nous avons utilisé les tables comme des listes numérotées, mais nous pouvons stocker des valeurs d’une manière différente, à savoir avec des chaînes de caractères comme indices :

1
2
3
4
5
function love.load()
  -- rect est l'abréviation de rectangle
  rect = {}
  rect["width"] = 100
end

“width” est appelé une clé ou une propriété. La table rect a maintenant une propriété “width” avec une valeur de 100. Nous n’avons pas besoin d’utiliser les crochets et les guillemets chaque fois que nous voulons créer une propriété. Un point (.) est un raccourci pour table_name[“propriété”]. Ajoutons quelques propriétés :

1
2
3
4
5
6
7
function love.load()
  rect = {}
  rect.x = 100
  rect.y = 100
  rect.width = 70
  rect.height = 90
end

Maintenant que nous avons nos propriétés, nous pouvons commencer à dessiner le rectangle :

1
2
3
function love.draw()
  love.graphics.rectangle("line", rect.x, rect.y, rect.width, rect.height)
end

Faisons-le bouger !

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function love.load()
  rect = {}
  rect.x = 100
  rect.y = 100
  rect.width = 70
  rect.height = 90

  -- Ajout de la vitesse comme propriété
  rect.speed = 100
end

function love.update(dt)
  rect.x = rect.x + rect.speed * dt
end

Maintenant, nous avons un rectangle qui se déplace, mais pour montrer la puissance des tables, je vais créer plusieurs rectangles qui se déplacent.
Pour ce faire, nous allons utiliser une table comme liste et nous aurons une liste de rectangles. Déplaçons le code de love.load dans une nouvelle fonction et créons une nouvelle table dans love.load :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
function love.load()
  -- Rappel: utilisation du camelCase!
  listOfRectangles = {}
end

function createRect()
  rect = {}
  rect.x = 100
  rect.y = 100
  rect.width = 70
  rect.height = 90
  rect.speed = 100

  -- Mettre le nouveau rectangle dans la liste
  table.insert(listOfRectangles, rect)
end

Maintenant, à chaque fois que nous appelons createRect, un nouvel objet rectangle sera ajouté à notre liste. C’est bien une table contenant d’autres tables.
Faisons en sorte qu’à chaque appui sur la touche espace, nous appelions createRect. Nous pouvons faire cela avec la fonction de rappel love.keypressed :

1
2
3
4
5
6
function love.keypressed(key)
  -- Rappel: deux signes égal (==) pour comparer!
  if key == "space" then
    createRect()
  end
end

Dès que nous appuyons sur une touche, LÖVE appellera love.keypressed et passera la touche pressée en argument. Si la touche est “space” (espace), cela appellera createRect.

La dernière chose à faire est de modifier nos fonctions update et draw. Nous devons parcourir la liste des rectangles pour les mettre à jour et les afficher :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function love.update(dt)
  for i, v in ipairs(listOfRectangles) do
    v.x = v.x + v.speed * dt
  end
end

function love.draw()
  for i, v in ipairs(listOfRectangles) do
    love.graphics.rectangle("line", v.x, v.y, v.width, v.height)
  end
end

Et maintenant, si nous exécutons le jeu, un nouveau rectangle qui se déplace apparaît à chaque fois que la touche espace est pressée.

Résultat quand on appuie sur la barre d’espace
Résultat quand on appuie sur la barre d’espace

Récapitulons

Il y avait beaucoup de code dans ce petit chapitre. Je peux imaginer que vous soyez un peu dérouté, alors passons en revue le code une fois de plus :

  1. Dans la fonction love.load, nous créons une table appelée listOfRectangles.
  2. Quand nous pressons la touche “space” (espace), LÖVE appelle love.keypressed et dans cette fonction, nous vérifions si la touche est “space”. Si c’est le cas, nous appelons la fonction createRect.
  3. Dans createRect, nous créons une nouvelle table. Nous lui donnons des propriétés comme x et y, puis nous la stockons dans la liste listOfRectangles.
  4. Dans love.update et love.draw, nous parcourons cette liste de rectangles pour mettre à jour et dessiner chaque rectangle.

Les méthodes

Un objet peut aussi avoir des fonctions, que l’on appelle alors des méthodes. Vous créez une méthode pour un objet comme ceci :

1
2
3
function tableName.functionName()
  -- Code de la fonction
end

Ou avec la syntaxe alternative qui utilise deux points :

1
2
3
4
function tableName:functionName()
  -- Le ":" crée automatiquement une variable "self" qui référence la table
  -- Exemple: self.x accéderait à tableName.x
end

Résumé

Nous pouvons stocker des valeurs dans une table avec des indices numériques, mais aussi avec des chaînes de caractères comme indices. Nous appelons ces types de tables des objets.
Utiliser des objets nous permet d’organiser notre code de manière logique, d’économiser de nombreuses variables en regroupant les données connexes, et de rendre notre code plus facile à lire et à maintenir.