cours n°8 · Découverte

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.

~11 min7 stations
▶ vidéo🧩 exercices📄 cheat sheet

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]`.

Partage la leçon

← tous les cours

📄 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 Microduck — du slop au code propre.