Programmes intégrés

pong
pong en réseau à deux
Tapez ceci à l'invite d'un ordinateur pour le copier sur le support :
> examples pong > edit pong
Le programme
-- PONG à deux joueurs sur deux ordinateurs reliés par câble, radio ou
-- Wi-Fi. Premier ordinateur : pong host Second : pong join
-- Flèches haut/bas (ou Z/S) pour la raquette. Le premier à 5 gagne.
-- Ctrl+T quitte. L'hôte déplace la balle et envoie tout l'état 10 fois
-- par seconde ; l'autre ordinateur n'envoie que sa raquette.
local mode = arg[1]
if mode ~= "host" and mode ~= "join" then
print("Usage : pong host ou pong join")
return
end
local W, H, PAD, WIN = 40, 15, 4, 5 -- terrain, hauteur des raquettes, score gagnant
local me = {y = 6}
local other = {y = 6}
local left, right = me, other -- l'hôte joue à gauche
if mode == "join" then left, right = other, me end
local ball = {x = 20, y = 8, dx = 1, dy = 1, wait = 10}
local score = {left = 0, right = 0}
local peer = nil
local running = true
-- 1. Trouver l'autre joueur
if mode == "host" then
print("J'attends un joueur (pong join)...")
while peer == nil do
local m = net.receive()
if m.channel == "pong" and m.data == "join" then
peer = m.sender
net.send(peer, "hello", "pong")
end
end
else
print("Je cherche une partie (pong host)...")
while peer == nil do
net.broadcast("join", "pong")
local m = net.receive(1) -- nil après 1 seconde sans message
if m and m.channel == "pong" and m.data == "hello" then peer = m.sender end
end
end
-- 2. La balle : seul l'hôte la déplace
function serve(dir)
ball.x = W // 2
ball.y = H // 2
ball.dx = dir
if math.random(2) == 1 then ball.dy = 1 else ball.dy = -1 end
ball.wait = 10 -- une seconde avant le service
end
function hit(paddle, y)
return y >= paddle.y and y < paddle.y + PAD
end
function step()
if ball.wait > 0 then
ball.wait = ball.wait - 1
return
end
local nx = ball.x + ball.dx
local ny = ball.y + ball.dy
if ny < 1 or ny > H then -- rebond sur les murs
ball.dy = -ball.dy
ny = ball.y + ball.dy
end
if nx == 1 and hit(left, ny) then
ball.dx = 1
nx = ball.x + 1
elseif nx == W and hit(right, ny) then
ball.dx = -1
nx = ball.x - 1
elseif nx < 1 then
score.right = score.right + 1
serve(1)
return
elseif nx > W then
score.left = score.left + 1
serve(-1)
return
end
ball.x = nx
ball.y = ny
end
-- 3. L'affichage, sur les deux ordinateurs
function draw()
term.clear()
term.set_fg(term.colors.yellow)
term.set_cursor(W // 2 - 2, 1)
term.write(score.left .. " - " .. score.right)
term.set_fg(term.colors.white)
term.set_cursor(1, 2)
term.write(string.rep("=", W + 2))
term.set_cursor(1, H + 3)
term.write(string.rep("=", W + 2))
for i = 0, PAD - 1 do
term.set_cursor(2, left.y + 2 + i)
term.write("#")
term.set_cursor(W + 1, right.y + 2 + i)
term.write("#")
end
term.set_fg(term.colors.orange)
term.set_cursor(ball.x + 1, ball.y + 2)
term.write("O")
term.set_fg(term.colors.white)
end
-- 4. La boucle de jeu : touches, messages, et un minuteur toutes les 0,1 s
local timer = os.start_timer(0.1)
while running do
local e = os.pull_event() -- n'importe quel évènement
if e.name == "key" or e.name == "char" then
local k = e.key or e.char
if (k == "up" or k == "w" or k == "z") and me.y > 1 then me.y = me.y - 1 end
if (k == "down" or k == "s") and me.y < H - PAD + 1 then me.y = me.y + 1 end
if mode == "join" then net.send(peer, {y = me.y}, "pong") end
elseif e.name == "message" and e.sender == peer and type(e.data) == "table" then
local d = e.data
other.y = d.y
if mode == "join" then -- l'hôte envoie tout l'état
ball.x = d.bx
ball.y = d.by
score.left = d.sl
score.right = d.sr
end
elseif e.name == "timer" and e.id == timer then
timer = os.start_timer(0.1)
if mode == "host" then
step()
net.send(peer, {y = me.y, bx = ball.x, by = ball.y, sl = score.left, sr = score.right}, "pong")
end
draw()
if score.left >= WIN or score.right >= WIN then running = false end
end
end
term.set_cursor(1, H + 4)
local mine = score.left
if mode == "join" then mine = score.right end
if mine >= WIN then
print("Gagné !")
else
print("Perdu !")
end