
term
L'écran texte : curseur, couleurs, effacement et défilement.
La bibliothèque term pilote l'écran texte de l'ordinateur. L'écran est une grille de caractères, et chaque case a sa propre couleur de texte et sa propre couleur de fond. print et write ajoutent du texte là où se trouve le curseur et passent à la ligne d'eux-mêmes, comme une machine à écrire ; term vous laisse placer le curseur n'importe où, choisir les couleurs, effacer et faire défiler. C'est l'outil des écrans d'état, des tableaux de bord, des menus et des boutons.
Les coordonnées comptent à partir de 1 : (1, 1) est le coin en haut à gauche, x est la colonne (vers la droite), y est la ligne (vers le bas).
term.clear()
term.set_cursor(1, 1)
print("Coffre de fer")
term.set_cursor(20, 1)
term.write("1234 lingots")Coffre de fer 1234 lingots
La taille de l'écran dépend de l'ordinateur :
| ordinateur | colonnes × lignes | couleurs |
|---|---|---|
| Calculateur à tubes | 40 × 14 | aucune : un téléscripteur qui imprime sur papier |
| Ordinateur à transistors | 51 × 19 | aucune : phosphore vert |
| Mini-ordinateur | 51 × 19 | aucune : phosphore ambre |
| Micro-ordinateur | 51 × 19 | 16 couleurs |
| Microcontrôleur | 40 × 12 | 16 couleurs |
| Ordinateur moderne | 64 × 24 | 16 couleurs |
Tous les ordinateurs ont la bibliothèque term. Sur les plus anciens, les couleurs sont acceptées mais pas affichées (voir plus bas). Pour dessiner en pixels sous le texte, voyez gfx ; le guide Écrans et moniteurs montre comment les deux s'assemblent.
term.get_size() | La taille de l'écran en caractères : {w = 51, h = 19} sur un Micro-ordinateur. |
term.set_cursor(x, y) | Place le curseur à la colonne x, ligne y. |
term.get_cursor() | Où se trouve le curseur : {x = ..., y = ...}, compté à partir de 1. |
term.write(text) | Écrit du texte au curseur, sur une seule ligne, sans passer à la ligne. |
term.clear() | Efface tout l'écran avec la couleur de fond du moment. |
term.clear_line() | Efface la ligne du curseur avec la couleur de fond du moment. |
term.scroll(n) | Fait monter tout le texte de l'écran de n lignes. |
term.set_fg(color) | Choisit la couleur du texte écrit à partir de maintenant. |
term.set_bg(color) | Choisit la couleur de fond des cases écrites à partir de maintenant, et de celles effacées par term.clear, term.clear_line et term.scroll. |
term.colors | La table des 16 couleurs : white (blanc) vaut 0, black (noir) vaut 15. |
Curseur et taille
Le curseur est l'endroit où va le prochain caractère. print, write et term.write partent tous de là et le déplacent.
La taille de l'écran en caractères : {w = 51, h = 19} sur un Micro-ordinateur.
- table
w, le nombre de colonnes, eth, le nombre de lignes
Calculez les positions à partir d'elle plutôt que d'écrire des nombres à la main, et le même programme s'affiche bien sur tous les ordinateurs : un Microcontrôleur (40 colonnes), un Micro-ordinateur (51) ou un Ordinateur moderne (64).
local taille = term.get_size()
term.set_bg(term.colors.black)
term.clear()
local coins = {{1, 1}, {taille.w, 1}, {1, taille.h}, {taille.w, taille.h}}
term.set_fg(term.colors.yellow)
for _, c in ipairs(coins) do
term.set_cursor(c[1], c[2])
term.write("+")
end
local texte = taille.w .. " x " .. taille.h
term.set_fg(term.colors.white)
term.set_cursor(math.floor((taille.w - #texte) / 2) + 1, math.floor(taille.h / 2))
term.write(texte)
Exactement le même programme sur un Microcontrôleur, dont l'écran est plus petit :
local taille = term.get_size()
term.set_bg(term.colors.black)
term.clear()
local coins = {{1, 1}, {taille.w, 1}, {1, taille.h}, {taille.w, taille.h}}
term.set_fg(term.colors.yellow)
for _, c in ipairs(coins) do
term.set_cursor(c[1], c[2])
term.write("+")
end
local texte = taille.w .. " x " .. taille.h
term.set_fg(term.colors.white)
term.set_cursor(math.floor((taille.w - #texte) / 2) + 1, math.floor(taille.h / 2))
term.write(texte)
Un moniteur ne change pas cette taille : un mur de moniteurs montre la même grille, en plus grand.
Voir aussi term.set_cursor()
term.set_cursor(x, y)
Place le curseur à la colonne x, ligne y.
xnumber- la colonne, 1 à gauche
ynumber- la ligne, 1 en haut
term.clear()
term.set_cursor(5, 2)
term.write("Four 1 : allumé")
term.set_cursor(5, 3)
term.write("Four 2 : plus de charbon") Four 1 : allumé
Four 2 : plus de charbonLa position doit être en nombres entiers : term.set_cursor(10.5, 1) arrête le programme avec bad argument #1 to 'set_cursor' (number has no integer representation). Quand vous calculez une position (pour centrer un texte, par exemple), arrondissez-la avec math.floor.
Une position hors de l'écran est permise, sans erreur, mais ce que vous y écrivez est perdu : les caractères qui tombent hors de l'écran ne sont tout simplement pas dessinés. Un texte qui commence près du bord droit est coupé :
term.clear()
term.set_cursor(48, 1)
term.write("Pression")
term.set_cursor(1, 2)
term.write("seul Pres est visible")Pres seul Pres est visible
Voir aussi term.get_cursor() term.write()
Où se trouve le curseur : {x = ..., y = ...}, compté à partir de 1.
- table
xety, la position du curseur
Pratique pour retenir un endroit et y revenir plus tard, pour mettre à jour une valeur sans redessiner le reste :
term.clear()
term.set_cursor(1, 1)
write("Fer dans le coffre : ")
local place = term.get_cursor()
print("...")
-- plus tard, quand le compte est connu :
term.set_cursor(place.x, place.y)
term.write("1234 ")Fer dans le coffre : 1234
Après term.write, le curseur se trouve juste après le dernier caractère, même au-delà du bord droit : écrire jusqu'à la dernière colonne d'un écran de 51 colonnes laisse x à 52.
Voir aussi term.set_cursor()
Écrire
term.write(text)
Écrit du texte au curseur, sur une seule ligne, sans passer à la ligne.
textany- le texte à écrire (un nombre ou toute autre valeur est converti, comme avec
tostring)
term.write est l'outil de précision de l'écran : il écrit exactement là où se trouve le curseur et ne touche à rien d'autre. Il diffère des fonctions globales write et print sur quatre points :
term.write | write et print | |
|---|---|---|
| au bord droit | la suite du texte est coupée | le texte continue sur la ligne suivante |
\n | affiché comme une espace | passe à la ligne |
une tabulation \t | affichée comme ? | des espaces jusqu'au multiple de 4 colonnes suivant |
| en bas de l'écran | ne fait jamais défiler | fait défiler l'écran vers le haut |
term.clear()
term.set_cursor(1, 1)
term.write("Charbon :\t12\nFer :\t40")
term.set_cursor(1, 2)
write("Charbon :\t12\nFer :\t40")Charbon :?12 Fer :?40 Charbon : 12 Fer : 40
Utilisez donc term.write pour tout ce qui est placé sur une grille (une valeur dans un cadre, un bouton, une barre d'état), et print pour un texte qui s'écoule, comme un journal. Les autres caractères de contrôle s'affichent ? avec les deux.
Le texte prend les couleurs du moment (term.set_fg, term.set_bg). Écrire coûte une instruction de plus par tranche de 16 caractères.
Voir aussi write() print() term.set_cursor()
Effacer et faire défiler
Ces trois fonctions remplissent des cases d'espaces dans la couleur de fond du moment, et aucune ne déplace le curseur.
term.clear()
Efface tout l'écran avec la couleur de fond du moment.
Le curseur reste où il était : un effacement est donc presque toujours suivi de term.set_cursor(1, 1).
print("ancienne ligne 1")
print("ancienne ligne 2")
term.clear()
print("après l'effacement")
local c = term.get_cursor()
print("curseur sur la ligne " .. c.y)après l'effacement curseur sur la ligne 4
(Le nouveau texte commence à la ligne 3, sous l'emplacement des anciennes lignes.)
Pour peindre tout l'écran, choisissez d'abord le fond :
term.set_bg(term.colors.blue)
term.clear()
term.set_cursor(3, 2)
term.set_fg(term.colors.yellow)
term.write("TOUT EN BLEU")
term.clear n'efface pas ce que gfx a dessiné : appelez gfx.clear() pour les dessins.
Voir aussi term.clear_line() gfx.clear()
term.clear_line()
Efface la ligne du curseur avec la couleur de fond du moment.
Deux usages courants : effacer une ligne avant d'y écrire un texte plus court, et peindre une barre de couleur en travers de l'écran.
term.set_bg(term.colors.black)
term.clear()
term.set_cursor(1, 1)
term.set_bg(term.colors.green)
term.clear_line()
term.set_fg(term.colors.black)
term.write(" Stockage OK")
term.set_cursor(1, 3)
term.set_bg(term.colors.red)
term.clear_line()
term.set_fg(term.colors.white)
term.write(" Chaudière en surchauffe")
term.set_bg(term.colors.black)
Voir aussi term.clear() term.set_cursor()
term.scroll(n)
Fait monter tout le texte de l'écran de n lignes.
nnumber- de combien de lignes monter le texte ; un nombre négatif le fait descendre
Les lignes du haut disparaissent, et de nouvelles lignes vides (dans la couleur de fond du moment) apparaissent en bas. Avec un n négatif, le texte descend et les lignes vides apparaissent en haut. Défiler de la hauteur de l'écran ou plus l'efface. n doit être un nombre entier.
term.clear()
term.set_cursor(1, 1)
print("ligne 1")
print("ligne 2")
print("ligne 3")
term.scroll(1)ligne 2 ligne 3
Le curseur ne bouge pas avec le texte, et les dessins de gfx restent où ils sont (gfx.scroll les déplace). print fait défiler tout seul quand il atteint le bas ; term.scroll sert à un programme qui place lui-même ses lignes, comme un journal sous un titre fixe (voir les motifs plus bas).
Voir aussi term.clear()
Couleurs
Il y a 16 couleurs, numérotées de 0 à 15 dans l'ordre des teintures de Minecraft. Utilisez leurs noms par term.colors : term.colors.red vaut 14. La page Couleurs les montre toutes.
term.set_fg(color)
Choisit la couleur du texte écrit à partir de maintenant.
colornumber- une couleur de 0 à 15, comme
term.colors.red
Ce qui est déjà à l'écran garde ses couleurs : seuls les caractères suivants changent.
term.set_bg(term.colors.black)
term.clear()
term.set_cursor(1, 1)
term.set_fg(term.colors.lime)
print("Réservoir d'eau : 92 %")
term.set_fg(term.colors.yellow)
print("Réservoir de lave : 35 %")
term.set_fg(term.colors.red)
print("Réservoir de carburant : 4 %, à remplir !")
term.set_fg(term.colors.white)
La couleur doit être un nombre de 0 à 15. Un nom de couleur entre guillemets est une erreur ici (contrairement à gfx, qui accepte "red") : term.set_fg("red") s'arrête avec bad argument #1 to 'set_fg' (number expected, got string), et term.set_fg(16) avec bad argument #1 to 'set_fg' (color must be 0..15). Avec un nom rangé dans une variable, écrivez term.colors[nom].
Les couleurs restent après la fin du programme : l'invite du shell serait rouge elle aussi. Terminez vos programmes par term.set_fg(term.colors.white) et term.set_bg(term.colors.black). Le bouton Stopper (Ctrl+T) les remet à zéro, et efface l'écran.
Voir aussi term.set_bg() term.colors
term.set_bg(color)
Choisit la couleur de fond des cases écrites à partir de maintenant, et de celles effacées par term.clear, term.clear_line et term.scroll.
colornumber- une couleur de 0 à 15, comme
term.colors.blue
Un fond coloré transforme un texte en étiquette ou en bouton. Pensez à revenir au noir ensuite :
term.set_bg(term.colors.black)
term.clear()
term.set_cursor(2, 2)
term.set_bg(term.colors.green)
term.set_fg(term.colors.white)
term.write(" OUVRIR ")
term.set_bg(term.colors.black)
term.write(" ")
term.set_bg(term.colors.red)
term.write(" FERMER ")
term.set_bg(term.colors.black)
term.set_cursor(2, 4)
term.set_fg(term.colors.light_gray)
term.write("Cliquez sur un bouton pour bouger le portail.")
Le programme buttons fait de tels boutons un panneau cliquable avec os.pull_event("click").
Voir aussi term.set_fg() term.colors
La table des 16 couleurs : white (blanc) vaut 0, black (noir) vaut 15.
- table
- les 16 noms de couleurs, chacun donnant son numéro
| numéro | nom | numéro | nom |
|---|---|---|---|
| 0 | white (blanc) | 8 | light_gray (gris clair) |
| 1 | orange | 9 | cyan |
| 2 | magenta | 10 | purple (violet) |
| 3 | light_blue (bleu clair) | 11 | blue (bleu) |
| 4 | yellow (jaune) | 12 | brown (marron) |
| 5 | lime (vert clair) | 13 | green (vert) |
| 6 | pink (rose) | 14 | red (rouge) |
| 7 | gray (gris) | 15 | black (noir) |
Les mêmes noms et numéros servent dans gfx. Les voici sur un Micro-ordinateur :
term.set_bg(term.colors.black)
term.clear()
local noms = {"white", "orange", "magenta", "light_blue", "yellow", "lime", "pink", "gray",
"light_gray", "cyan", "purple", "blue", "brown", "green", "red", "black"}
for i, nom in ipairs(noms) do
local colonne = 2 + math.floor((i - 1) / 8) * 25
local ligne = 2 + (i - 1) % 8 * 2
term.set_cursor(colonne, ligne)
term.set_fg(term.colors.gray)
term.write("[")
term.set_bg(term.colors[nom])
term.write(" ")
term.set_bg(term.colors.black)
term.write("]")
term.set_fg(term.colors.white)
term.write(" " .. term.colors[nom] .. " " .. nom)
end
Voir aussi term.set_fg() term.set_bg() Couleurs
Moniteurs et écrans anciens
Les moniteurs. Un Moniteur cathodique ou un Moniteur LCD qui touche l'ordinateur affiche son écran : la même grille, les mêmes caractères et couleurs, agrandis pour remplir le moniteur (plusieurs moniteurs côte à côte forment un seul grand écran, jusqu'à 8 × 6 blocs). Le programme ne voit aucune différence : term.get_size donne la taille de l'écran propre de l'ordinateur. Le Moniteur cathodique garde l'aspect de l'ordinateur (vert ou ambre sur les anciens, phosphore vert pour le papier du Calculateur à tubes), le Moniteur LCD affiche toujours les couleurs. Voyez Moniteurs.
Les écrans à phosphore. L'Ordinateur à transistors (vert) et le Mini-ordinateur (ambre) ont des écrans monochromes : chaque caractère s'allume dans la couleur du phosphore, et les couleurs de fond ne s'affichent pas. term.set_fg et term.set_bg marchent quand même (sans erreur) : un programme écrit pour un écran couleur tourne sans changement, mais ses couleurs disparaissent. Voici l'exemple « OUVRIR / FERMER » ci-dessus sur un Ordinateur à transistors :
term.set_bg(term.colors.black)
term.clear()
term.set_cursor(2, 2)
term.set_bg(term.colors.green)
term.set_fg(term.colors.white)
term.write(" OUVRIR ")
term.set_bg(term.colors.black)
term.write(" ")
term.set_bg(term.colors.red)
term.write(" FERMER ")
term.set_bg(term.colors.black)
term.set_cursor(2, 4)
term.set_fg(term.colors.light_gray)
term.write("Cliquez sur un bouton pour bouger le portail.")
On ne distingue plus les boutons du texte. Sur ces écrans, montrez les choses avec des caractères : des crochets autour des boutons, > pour un choix, une barre de # pour un niveau.
term.clear()
term.set_cursor(2, 2)
term.write("[ OUVRIR ] [ FERMER ]")
term.set_cursor(2, 4)
term.write("Eau [##########----------] 50 %")
term.set_cursor(2, 5)
term.write("Lave [###-----------------] 15 %")
term.set_cursor(2, 7)
term.write("> Démarrer les pompes")
term.set_cursor(2, 8)
term.write(" Arrêter les pompes")
Le téléscripteur. Le Calculateur à tubes imprime sur une feuille de papier, 40 caractères sur 14 lignes, à l'encre sombre. C'est toujours le même genre d'écran : print fait monter le papier, term.set_cursor, term.clear et term.scroll marchent comme sur les autres. Seules les couleurs ne sont pas imprimées, et le papier ne se clique pas : un clic dans la fenêtre du terminal n'envoie aucun évènement click (un moniteur relié à un Calculateur à tubes peut quand même être pressé). Il n'y a pas de gfx sur le Calculateur à tubes.
print("== RAPPORT SILICIUM ==")
print("boules tirées : 12")
print("plaquettes coupées : 72")
print("rebuts : 3")== RAPPORT SILICIUM == boules tirées : 12 plaquettes coupées : 72 rebuts : 3
Motifs courants
Un titre centré. Retirez la longueur du texte de la largeur, coupez en deux, et arrondissez vers le bas :
local function centrer(y, texte)
local taille = term.get_size()
term.set_cursor(math.floor((taille.w - #texte) / 2) + 1, y)
term.write(texte)
end
term.clear()
centrer(1, "CHAUFFERIE")Une barre d'état en bas. Peignez la dernière ligne, écrivez dessus, puis remettez le curseur où il était, pour ne pas déranger les print du reste du programme :
local function etat(texte)
local taille = term.get_size()
local retour = term.get_cursor()
term.set_cursor(1, taille.h)
term.set_bg(term.colors.gray)
term.set_fg(term.colors.white)
term.clear_line()
term.write(" " .. texte)
term.set_bg(term.colors.black)
term.set_cursor(retour.x, retour.y)
end
etat("Ligne de presses : en marche, 37 objets/min")Redessiner une ligne sans clignotement. Un programme qui efface tout l'écran et redessine tout chaque seconde fait clignoter l'écran : sur un ordinateur lent, le dessin prend plusieurs ticks, et les joueurs le voient à moitié fait. Dessinez les parties fixes une fois, puis réécrivez seulement les valeurs qui changent. Complétez le nouveau texte avec des espaces, pour qu'une valeur plus courte efface la fin de la plus longue :
term.clear()
term.set_cursor(1, 1)
term.write("Lingots de fer :")
term.set_cursor(1, 2)
term.write("Lingots d'or :")
local function montrer(ligne, valeur)
term.set_cursor(18, ligne)
term.write(string.format("%-8d", valeur)) -- 8 colonnes, complétées d'espaces
end
montrer(1, 1234)
montrer(2, 56)
montrer(1, 99) -- "1234" devient "99", pas "9934"
term.set_cursor(1, 4) -- laissez le curseur sous l'écran dessinéLingots de fer : 99 Lingots d'or : 56
Un écran avec une barre de titre. Tout ensemble : une barre colorée avec un titre centré, des valeurs en deux couleurs, et une barre d'état :
local taille = term.get_size()
term.set_bg(term.colors.black)
term.clear()
local function barre(y, couleur, texte)
term.set_cursor(1, y)
term.set_bg(couleur)
term.set_fg(term.colors.white)
term.clear_line()
term.set_cursor(math.floor((taille.w - #texte) / 2) + 1, y)
term.write(texte)
term.set_bg(term.colors.black)
end
local function valeur(y, libelle, quantite, unite, ok)
term.set_cursor(3, y)
term.set_fg(term.colors.light_gray)
term.write(libelle)
term.set_cursor(24, y)
if ok then term.set_fg(term.colors.lime) else term.set_fg(term.colors.red) end
term.write(quantite .. " " .. unite)
end
barre(1, term.colors.blue, "MOTEUR À VAPEUR - CHAUFFERIE")
valeur(3, "Chaleur chaudière", 18, "/ 18", true)
valeur(4, "Entrée d'eau", 1620, "mB/t", true)
valeur(5, "Moteurs en marche", 6, "sur 8", false)
valeur(6, "Capacité de stress", 98304, "su", true)
barre(taille.h, term.colors.gray, "mis à jour chaque seconde")
Un tableau de bord sur deux colonnes. Deux panneaux côte à côte, chacun avec son titre, pour deux parties d'une usine :
local taille = term.get_size()
local moitie = math.floor(taille.w / 2)
term.set_bg(term.colors.black)
term.clear()
local function panneau(x, titre, couleur, lignes)
term.set_cursor(x, 1)
term.set_bg(couleur)
term.set_fg(term.colors.black)
term.write(string.format(" %-" .. (moitie - 2) .. "s", titre))
term.set_bg(term.colors.black)
for i, ligne in ipairs(lignes) do
term.set_cursor(x + 1, i + 2)
term.set_fg(term.colors.white)
term.write(ligne[1])
term.set_cursor(x + moitie - 8, i + 2)
term.set_fg(ligne[3])
term.write(string.format("%6d", ligne[2]))
end
end
panneau(1, "FONDERIE : LINGOTS", term.colors.orange, {
{"Fer", 1234, term.colors.lime},
{"Or", 312, term.colors.lime},
{"Cuivre", 18, term.colors.red},
})
panneau(moitie + 1, "PRESSES : PLAQUES", term.colors.light_blue, {
{"Fer", 640, term.colors.lime},
{"Laiton", 96, term.colors.yellow},
{"Or", 0, term.colors.red},
})
Un journal en couleurs sous un titre fixe. Chaque ligne porte une étiquette colorée. Quand l'écran est plein, term.scroll fait monter les lignes et le titre est redessiné en haut :
local taille = term.get_size()
local ligne = 2
local function titre()
term.set_cursor(1, 1)
term.set_bg(term.colors.gray)
term.set_fg(term.colors.white)
term.clear_line()
term.write(" Journal du trieur")
term.set_bg(term.colors.black)
end
local function journal(couleur, etiquette, texte)
if ligne > taille.h then
term.scroll(1)
titre()
ligne = taille.h
end
term.set_cursor(1, ligne)
term.set_fg(couleur)
term.write(etiquette)
term.set_fg(term.colors.white)
term.write(" " .. texte)
ligne = ligne + 1
end
term.set_bg(term.colors.black)
term.clear()
titre()
local cargaison = {"lingots de fer", "lingots de cuivre", "pépites d'or", "andésite", "plaques de laiton"}
for i = 1, 20 do
local objet = cargaison[(i - 1) % #cargaison + 1]
journal(term.colors.lime, "[ OK ]", "tri : " .. (i * 7 % 50 + 14) .. " " .. objet)
if i == 9 then
journal(term.colors.yellow, "[WARN]", "coffre renforcé B plein à 90 %")
end
end
journal(term.colors.red, "[FAIL]", "coffre renforcé B plein, tapis arrêté")