Suis les étapes, pas à pas pour apprendre à créer tes propres jeux vidéos
Tout d’abord au début des premiers chapitres nous avons vu les Variables Simples.
Petit rappel des différents types de ces variables :
age = 10 -- number
name = "robert" -- string
enVie = true -- boolean
inventaire = nil -- nil (void / vide)
Ensuite nous avons abordé le nommage de ces variables :
heroVie = 100
heroName = "Arthur"
ennemiVie = 60
ennemiName = "Bidule"
Nous avons aussi vu qu’une variable pouvait être aussi une fonction :
maFonction = function()
-- corps de la fonction
end
-- strictement égale à :
function maFonction()
-- corps de la fonction
end
Les variables simples (vu) :
number – vu
string – vu
boolean – vu
nil – vu
variables complexes :
function – vu
table – On en est là !
celles que nous n’aborderons pas dans les chapitres “ Les bases Lua” (niveau plus avancé) :
userdata
thread
Maintenant il nous reste donc à aborder les variables de type(table) !
C’est un plateau généralement en bois auquel on rajoute des pieds pour le supporter. Ce qui nous forme alors une table… Non je déconne =)
Une table, c’est une espace de stockage où l’on va mettre un ensemble de variables qui la compose. Je vous l’accorde ça fait un peu définition de dictionnaire dit comme ça…
Prenons l’exemple dans un jeu vidéo, le héros par exemple doit être une table !
Car dans la table héro on voudra retrouver une variable vie, une variable nom, une variable force, une variable endurance, etc.
La table Héros serait donc composée de différents types de variables… :

On peut aussi visualiser la table HERO comme une grande armoire…
- La table Héro est une armoire.
- Chaque tiroir qui la compose sont ses composants.
- Dans chaque tiroir se trouve sa valeur.

Pseudo-code :
Hero est une Table
Hero est composé d'un composant vie qui vaut cette valeur
Hero est composé d'un composant force qui vaut cette valeur
Hero est composé d'un composant endurance qui vaut cette valeur
Hero est composé d'un composant nom qui vaut cette valeur
Syntaxe d’une table :
maTable = {} -- creation d'une table qui se nomme maTable
maTable.composant = "valeur"
Les constructeurs {} nous indiquent qu’il s’agit d’une table vide !
L’utilisation d’un point apres maTable indique que l’on veut accèder/créer à un des composants de la table.
Donc pour notre héros :
Hero = {} -- on créer la table Hero
Hero.vie = 100 -- on créer un composant "vie" avec sa valeur 100
Hero.force = 10 -- on créer un composant "force" avec sa valeur 10
Hero.endurance = 3 -- on créer un composant "endurance" avec sa valeur 3
Hero.nom = "Arthur" -- on créer un composant "nom" avec sa valeur "Arthur"
Plutôt pratique non ? =)
Les tables permettent de ranger (structurer) son code plus facilement !
Vous ne trouvez pas que tout de suite c’est plus clair et lisible ?!
Hero = {}
Hero.vie = 100
print(Hero.vie)
sortie console :
100
Tout simplement =)
Hero.vie = 100
Hero est une table
vie est un index alphanumérique de la table Hero
100 est la valeur de l’index vie de la table Hero soit Hero.vie
Vous avez vu c’est nouveau ça : index et alphanumériques !
Ça tombe bien, car dans l’étape suivante aborde les différents types d’index dans une table…
ils existent 2 types ! alphanumériques et numériques !
Un index alphanumériques représente un index d’une table, il est de type string.
Comme un string peut contenir des lettres et des chiffres c’est pourquoi on utilise le terme alphanumérique.
Voyons les différentes écritures pour créer/accéder à un index alphanumérique :
Hero = {}
Hero.vie = 100
print(Hero.vie)
sortie console :
100
Les crochets [] nous permettent aussi d’accéder à l’index d’une table !
Hero = {}
Hero["vie"] = 100
print(Hero["vie"])
sortie console :
100
On peut créer des index numériques dans une table.
Pour cela, nous devons utiliser les crochets [].
En Lua les index numérique commencent à 1 !
Exemple :
Inventaire = {}
Inventaire[1] = 150
Inventaire[2] = "épée"
Inventaire[3] = "bouclier"
print(Inventaire[1])
print(Inventaire[2])
print(Inventaire[3])
sortie console :
150
épée
bouclier
Notre table inventaire contient 3 index numériques !
l’index [1] de la table Inventaire contient la valeur 150
l’index [2] de la table Inventaire contient la valeur “épée”
l’index [3] de la table Inventaire contient la valeur “bouclier”
On utilise le terme de tableaux pour l’utilisation des index numériques du fait de leur écriture similaire à d’autres langages avec l’utilisation des [] pour les créer…
Attention à ne pas mélanger les index numériques et alphanumériques !
Inventaire = {}
Inventaire[1] = "epée"
print(Inventaire[1])
print(Inventaire["1"])
sortie console :
epée
nil
Inventaire.1 n’existe pas car “1” est un string !
Cependant, Inventaire[1] existe bien et c’est un index numérique !
De plus, on ne peut pas créer de variable en commençant par un nombre !
Pour voir le contenu d’une table il existe des boucles spécialement conçues pour les tables !
La boucle pairs, qui parcourt tous les types d’index, alphanumériques et numériques !
La boucle ipairs, qui parcourt uniquement les index numériques !
Nous utiliserons donc les boucles pairs pour explorer tout le contenu d’une table alphanumérique et les boucles ipairs pour explorer les contenus d’index numériques.
Voyons leurs syntaxes et des exemples =)
Pseudo-code boucle pairs:
POUR chaque index, et sa valeur contenu dans ( la table ) FAIT
ceci
FIN
Syntaxe d’une boucle pairs :
for k, v in pairs(table) do
-- corps de la fonction
end
k = index alphanumériques et/ou numériques (on utilise K pour key en anglais)
v = valeur (on utilise V pour value en anglais)
Voyons un exemple de la boucle pairs avec une table Hero…
Boucle pairs, elle parcourt tous les index qu’ils soient alphanumériques ou numériques :
Hero = {}
Hero.vie = 100
Hero.force = 10
Hero.endurance = 3
Hero.nom = "Arthur"
Hero[1] = 1
Hero[2] = 2
Hero[3] = 3
for k, v in pairs(Hero) do
print(tostring(k).." : "..tostring(v))
end
sortie console :
1 : 1
2 : 2
3 : 3
vie : 100
nom : Arthur
endurance : 3
force : 10
Tous nos index ont été identifiés et print()
Pseudo-code boucle ipairs:
POUR chaque index NUMÉRIQUES, et sa valeur contenu dans ( table ) FAIT
ceci
FIN
Syntaxe d’une boucle ipairs :
for k, v in ipairs(table) do
-- corps de la fonction
end
k = index numérique uniquement
v = valeur
Boucle ipairs : seulement numériques !
Hero = {}
Hero.vie = 100
Hero.force = 10
Hero.endurance = 3
Hero.nom = "Arthur"
Hero[1] = 1
Hero[2] = 2
Hero[3] = 3
for k, v in ipairs(Hero) do
print(tostring(k).." : "..tostring(v))
end
sortie console :
1 : 1
2 : 2
3 : 3
Seuls les index numériques ont été identifiés et print ! Parfait !
Les tables bénéficient des imbrications tout comme les boucles, les test de conditions et les fonctions.
imaginons que nous voulions créer une table Hero, qui contiendrait des variables simples et une autre table dans cette même table pour gérer son inventaire ?!
C’est tout à fait réalisable car une table est une variables complexes qui peut donc contenir des variables, d’index alphanumériques ou numériques, des fonctions, d’autres tables qui contiennent elles-mêmes aussi d’autres variables, fonctions, tables, etc.
Les possibilités sont quasiment infinies !
Créons, par exemple, notre table Hero avec des variables tels que vie, force, endurance et nom. Nous ajouterons une table inventaire dans la table Hero !
Exemple :
Hero = {}
Hero.vie = 100
Hero.force = 10
Hero.endurance = 3
Hero.nom = "Arthur"
Hero.inventaire = {}
Hero.inventaire[1] = 1
Hero.inventaire[2] = 2
Hero.inventaire[3] = 3
print("adresse de la table Hero : "..Hero)
print("Contenu de la table Hero : ")
for k, v in pairs(Hero) do
print("Hero."..tostring(k) .. " : " .. tostring(v))
end
print("\n" .. "Contenu de la table Hero.inventaire : ")
for k, v in ipairs(Hero.inventaire) do
print( "Hero.inventaire["..tostring(k).."] : " .. tostring(v) )
end
sortie console :
adresse de la table Hero : table: 0x10a22541 Contenu de la table Hero :
Hero.vie : 100
Hero.force : 10
Hero.inventaire : table: 0x10a27410
Hero.nom : Arthur
Hero.endurance : 3 Contenu de la table Hero.inventaire :
Hero.inventaire[1] : 1
Hero.inventaire[2] : 2
Hero.inventaire[3] : 3
Hero.inventaire est bien une sous-table de la table Hero =)
Car 0x10a27410 est l’adresse mémoire de l’emplacement de la table inventaire et elle est différente de celle de Hero !
Cela peut nous permettre de les identifier, pour comparer des données, et donc savoir s’il s’agit d’une même adresse de table ;)
Une table afin de bien saisir le concept, car c’est important ! C’est une grande boîte qui contient d’autres boîtes de toutes tailles et ceux jusqu’à l’infini !
_enfin presque à l’infini, mais avant d’atteindre le maximum, faut vraiment y aller fort !
_
Chaque boite peut donc contenir des allumettes, ou un briquet voire d’autres boîtes, etc.
Schéma pour résumé :

La flèche orange indique une variable de variables.
La flèche rouge indique une boucle infini de créations !
Reprenons cela sous une autre forme… :
Si on veut créer une table on utilise le constructeur {}
par défaut elle ne comporte pas de composants.
maTable = {}
-Une table peut contenir des index alphanumérique :
maTable["maVar"] = valeur
maTable.monAutreVar = valeur
-Une table peut contenir des index numériques :
maTable[number] = valeur
-Une table peut contenir des fonctions :
function maTable.maFonction()
-- bloc
end
-Une table peut contenir d’autres tables
maTable.maSousTable = {}
On dit alors que maTable.maSousTable est au 2ᵉ niveau de la table maTable.
maTable.maSousTable.monAutreTable = {} serait donc au 3ᵉ niveau…
Si vous n’avez pas bien saisi, il n’y a rien de mieux que d’expérimenter…
Relisez calmement. Puis essayez de créer d’autres tables, de les print(), pour bien comprendre le fonctionnement de celles-cis.
C’est dans ces tables que nous travaillerons le plus, il est primordial de bien saisir au moins comment on y accède et comment créer des index et/ou des variables. Voir d’autres tables dans des tables…
Même si ça reste assez flou (abstrait) si vous savez au moins comment les creer et y acceder c’est l’essentiel pour l’instant =)
Si vous pensez avoir compris cela, on va approfondir légèrement plus les tables !
On va reproduire l’exemple ci-dessous avec une boucle :
inventaire = {}
inventaire[1] = 1
inventaire[2] = 2
inventaire[3] = 3
exemple :
inventaire = {}
for i = 1, 3 do
inventaire[i] = i
end
for k, v in ipairs(inventaire) do
print("inventaire["..k.."] : "..v)
end
sortie console :
inventaire[1] : 1
inventaire[2] : 2
inventaire[3] : 3
Parfait !
Syntaxe :
maTable = {}
maTable[1] = 1
maTable[2] = 5
maTable[3] = 8
print(#maTable)
sortie console :
3
Exemple pour parcourir une table numérique en utilisant # (lenght) :
inventaire = {}
for i = 1, 3 do
inventaire[i] = i
end
print("total d'index de la table inventaire : "..#inventaire.."n")
for i = 1, #inventaire do
print("inventaire["..i.."] : "..inventaire[i])
end
sortie console :
total d'index de la table inventaire : 3 inventaire[1] : 1 inventaire[2] : 2 inventaire[3] : 3
ça fonctionne très bien, et personnellement je préfère cette méthode car on est sûr qu’elle sera parcourue dans l’ordre souhaité soit dans l’ordre d’incrémentation ou l’ordre de décrémentation.
Un autre exemple d’utilisation de # avec une variable string.
# permet aussi de donner le total de char d’une variable string.
exemple :
inventaire = "mon inventaire"
print(#inventaire)
sortie console :
14
14 étant le nombre de char (caractères) contenu dans la variable string espace inclus.
Oui l’espace est un caractère, certes vide, mais c’est un caractère quand même.
il existe une fonction dans lua qui sert à manipuler les index de table numérique… table.insert() et table.remove() :
table.insert(table, valeur) -- Permet d'ajouter un index à la fin
table.insert(table, index, valeur) -- Permet d'ajouter un index à l'emplacement souhaité
table.remove(table, index) -- Permet de supprimer un index
table.remove(table) -- Permet de supprimer le dernier index
###
Comment ajouter des index :
inventaire = {}
-- #inventaire = 0 : total d'index = 0
-- si on fait un table.insert(inventaire, valeur) alors : #inventaire vaut +1 (ajout d un index)
table.insert(inventaire, 1) -- equivaut a inventaire[1] = 1 :: #inventaire vaut desormais 1 (ajout d un index)
table.insert(inventaire, 2) -- equivaut a inventaire[2] = 2
table.insert(inventaire, 3) -- equivaut a inventaire[3] = 3
print("nombre d'index de la table inventaire : "..#inventaire.."n")
for i = 1, #inventaire do
print("inventaire["..i.."] : "..inventaire[i])
end
sortie console :
nombre d'index de la table inventaire : 3
inventaire[1] : 1
inventaire[2] : 2
inventaire[3] : 3
inventaire = {}
for i = 1, 3 do
inventaire[i] = i
end
print("total d'index de la table inventaire avant suppression : "..#inventaire.."n")
table.remove(inventaire, 3) -- on supprime l'index n°3 !
print("total d'index de la table inventaire apres suppression : "..#inventaire.."n")
for i = 1, #inventaire do
print("inventaire["..i.."] : "..inventaire[i])
end
sortie console :
total d'index de la table inventaire avant suppression : 3
total d'index de la table inventaire apres suppression : 2
inventaire[1] : 1
inventaire[2] : 2
l’index 3 à bien été supprimé !
Que se passe-t-il si l’on supprime un index au milieu ?
inventaire = {}
for i = 1, 3 do
inventaire[i] = i
end
print("#inventaire avant supression : "..#inventaire.."n")
table.remove(inventaire, 2) -- on supprime l'index 3 !
print("#inventaire apres supression : "..#inventaire.."n")
for i = 1, #inventaire do
print("inventaire["..i.."] : "..inventaire[i])
end
sortie console :
#inventaire avant supression : 3
#inventaire avant supression : 2
inventaire[1] : 1
inventaire[2] : 3
Quand l’index 2 a été supprimé tous les index suivant change de numéro d’index, dans notre cas l’index n°3 est devenu l’index n°2…
Voyons l’explication précédentes avec des schémas :
Que se passe-t-il réellement lors de l’utilisation de table.remove(inventaire, 2) ?

inventaire = {}
inventaire[1] = 1
inventaire[2] = 2
inventaire[3] = 3
avant : il y a 3 index a la table inventaire :
inventaire[1] = 1
inventaire[2] = 2
inventaire[3] = 3
pendant : table.remove(inventaire, 2)
l’index n°2 va être supprimé…
l’index n°3 devient l’index n°2…
ps : si l’index n°4 existe il devient l’index n°3, et cela jusqu’au dernier index...
et enfin le dernier index est supprimé !
après table.remove :
il ne reste plus que 2 index :
inventaire[1] = 1
inventaire[2] = 3
inventaire[3] = index supprimé...
Si vous ne comprenez pas tout, relisez au moins une fois ou deux, mais ne vous inquiétez si vous ne comprenez pas tout !
Parce que nous évoquerons de nouveau ces concepts lors d’exercices concrets avec des éléments attachés à ces index, comme des ennemis ou d’autres éléments qui se trouve dans un jeu vidéo et cela vous semblera beaucoup plus parlant qu’un simple schéma comme celui-ci.
Ce qu’il faut mémoriser c’est que le nombre total d’index d’une table change à l’ajout et/ou à la suppression de ses index !
Comme nous venons de le voir, les index se décalent a leur suppression.
c’est aussi le cas lorsque nous inseront un nouvel index a un emplacement deja existant ;)
compteur = {}
-- #compteur vaut 0 : soit un total d'index de 0
table.insert(compteur, 1) -- compteur[1] = 1 :: #inventaire vaut desormais 1 (ajout d un index)
table.insert(compteur, 3) -- equivaut a compteur[2] = 3
table.insert(compteur, 2, 2) -- equivaut a compteur[2] = 2, et deplacement de l'ancien index 2 en position 3.
--[[
le fait d'inserer un nouvel index a un index existant, deplace les index existant a l'index superieur.
Dans notre cas voici, ce qu'il se passe lors de l'tilisation de table.insert(compteur, 2, 3) :
- compteur[2] est déplacé a l'index 3 soit : compteur[3] = 2
PUIS
- l'index 2 est recrer avec sa nouvelle valeur soit : compteur[2] = 2
]]--
print("nombre d'index de la table compteur : "..#compteur.."n")
for i = 1, #compteur do
print("compteur["..i.."] : "..compteur[i])
end
sortie console :
nombre d'index de la table compteur : 3
compteur[1] : 1
compteur[2] : 2
compteur[3] : 3
Cela démontre bien que le déplacement des index, peut être effectuer avec table.insert() et table.remove()
Fin de ce chapitre sur les tables et tableaux !