La map des positions
Une case = une adresse, un nom dessus : ton monde tient dans un Hash — et un mur, c'est une case déjà prise.
42 secondes · sous-titres Français inclus · 8.8 Mo
Les 7 trucs que tu vas savoir faire
Leçon 8 : La map des positions
Regarde la leçon (42 s) : ton monde n'a pas de décor, il a une table. Qui est où — et qui ne peut pas passer.
Une case = une adresse
Écris `case_de(x, y)` : la clé de la map pour la case (3, 4) est `"3,4"` — x, une virgule, y. Toute la case tient dans une chaîne.
Loger un sprite
Écris `pose(carte, x, y, nom)` qui renvoie une NOUVELLE map avec le sprite posé sur la case — l'original ne bouge jamais. Tu ranges, tu ne détruits.
La case est-elle prise ?
Écris `occupe?(carte, x, y)` : true si un sprite est sur cette case. On interroge l'ADRESSE — `key?` — pas la valeur : le vide n'a pas de nom.
Qui rencontre qui ?
Écris `rencontre(carte, x, y)` : le nom du sprite sur la case — ou `nil` si elle est vide. Dans un vrai jeu, c'est ce retour qui déclenche tout : dégât, pièce, dialogue.
60 mises à jour par seconde
Écris `tic(secondes)` : le nombre de fois où la map est relue et recalculée — 60 fois par seconde, pas une de plus. Une seconde de jeu, soixante calculs.
Leçon 8 : OK
Sans aide : `avance(carte, x, y, dx, dy)` — un pas vers `[x + dx, y + dy]`. Si cette case est déjà occupée (un mur, un autre sprite), le pas est IMPOSSIBLE : tu restes à `[x, y]`.
📄 La feuille de chute
imprime-la, colle-la à ton écran, fais semblant que c'est ton idée📄 Cheat sheet — La map des positions (le monde est un Hash)
Ton monde n'a pas de décor : il a une table. Une case = une adresse, une adresse = un sprite — et un mur, c'est une case déjà prise.
La map en 4 mots
| Mot | Ce que c'est | Exemple |
|---|---|---|
| case | une adresse x,y |
"3,4" |
| map | toutes les cases, un Hash | carte = {} |
| tic | une mise à jour | 60 par seconde |
| mur | une case occupée | carte["5,5"] = "mur" |
Une case = une adresse
def case_de(x, y)
"#{x},#{y}" # x d'abord, la virgule, y ensuite
end
case_de(3, 4) # => "3,4"
Toute la case tient dans une chaîne : c'est la clé de ton Hash. 4,3 est une autre case.
Loger un sprite : on copie, on ne détruit pas
def pose(carte, x, y, nom)
carte.merge("#{x},#{y}" => nom) # nouveau Hash, original intact
end
pose({}, 1, 2, "joueur") # => { "1,2" => "joueur" }
merge copie, = détruit. Depuis la leçon 6, la règle n'a pas bougé — appliquée au monde entier.
Occupée ou vide : key? vs valeur
carte = { "3,4" => "joueur" }
carte.key?("3,4") # => true l'ADRESSE existe
carte.key?("0,0") # => false personne n'y loge
carte["0,0"] # => nil le vide n'a pas de nom
key? te dit si la case est prise quelle que soit la valeur. C'est la question que le jeu pose
soixante fois par seconde.
Qui rencontre qui
def rencontre(carte, x, y)
carte["#{x},#{y}"] # le nom… ou nil
end
rencontre(carte, 3, 4) # => "joueur"
rencontre(carte, 0, 0) # => nil
Un nil qui revient : rien sur la route. Un nom qui revient : dégât, pièce, dialogue — tout le
gameplay part de ce retour.
60 mises à jour par seconde
def tic(secondes)
secondes * 60 # une seconde de jeu = soixante relectures de la table
end
tic(1) # => 60
À chaque tic : on relit la map, on déplace, on recompare. Le jeu ne bouge pas : il recalcule.
Face à un mur, l'avancée est impossible
def avance(carte, x, y, dx, dy)
cible = "#{x + dx},#{y + dy}"
carte.key?(cible) ? [x, y] : [x + dx, y + dy]
end
avance({}, 2, 2, 1, 0) # => [3, 2] case libre : j'avance
avance({ "3,2" => "mur" }, 2, 2, 1, 0) # => [2, 2] case prise : je reste
Pas de physique, pas de collision "du moteur" : une adresse déjà prise, un key?, un choix.
À ne plus jamais dire
"le sprite heurte un mur"→ la case d'arrivée est déjà dans la map — et tu renvoies l'ancienne position"il me faut un moteur de collision"→ ton Hash fait ce travail depuis la leçon 3.
SlopCourse — du slop au code propre.