Solution : Le Pong
love.window.setTitle("Le Pong")
local raquettes = {}
local balle = {x=0, y=0, w=15, h=15, speed=250, speedDef=250, vx=0, vy=0, follow=true, joueur=1}
local joueur = {}
local filet = {x=400,y=0,w=1,h=600}
local gameUI = {}
local Game = {over=false, winner=1}
-- ###### Functions ######
function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
return x1 < x2+w2 and
x2 < x1+w1 and
y1 < y2+h2 and
y2 < y1+h1
end
--
function math.angle(x1,y1, x2,y2) return math.atan2(y2-y1, x2-x1) end
function raquettes.new(positionX)
local raquette = {x=positionX, y=225, yDef=225, w=20, h=150, speed=300}
function raquette.draw()
love.graphics.rectangle("fill", raquette.x, raquette.y, raquette.w, raquette.h)
end
return raquette
end
--
function joueur.load()
-- joueur 1
joueur[1] = {score=0}
joueur[1].raquette = raquettes.new(10) -- positionX
joueur[1].keys = {up="z", down="s", fire="space"}
-- joueur 2
joueur[2] = {score=0}
joueur[2].raquette = raquettes.new(770) -- positionX
joueur[2].keys = {up="up", down="down", fire="return"}
end
--
function joueur.update(dt)
for n=1, 2 do
local j = joueur[n]
local pad = joueur[n].raquette
if love.keyboard.isDown(j.keys.up) and love.keyboard.isDown(j.keys.down) then
-- nothing
elseif love.keyboard.isDown(j.keys.up) then
pad.y = pad.y - (pad.speed * dt)
elseif love.keyboard.isDown(j.keys.down) then
pad.y = pad.y + (pad.speed * dt)
end
-- limit to screen
if pad.y <= 0 then
pad.y = 0
elseif pad.y + pad.h >= 600 then
pad.y = 600 - pad.h
end
end
end
--
function joueur.draw()
for n=1, #joueur do
joueur[n].raquette.draw()
end
end
--
function balle.update(dt)
if balle.follow then
local x
local y
local raquette
if balle.joueur == 1 then
raquette = joueur[1].raquette
-- Position x a droite de la raquette
x = raquette.x + raquette.w + 1
elseif balle.joueur == 2 then
raquette = joueur[2].raquette
-- Position x a gauche de la raquette
x = raquette.x - balle.w - 1
end
-- Position Y au centre de la raquette
y = raquette.y + ( (raquette.h/2) - (balle.w/2) )
--
balle.x = x
balle.y = y
else -- elle est en cours de deplacement libre
balle.x = balle.x + (balle.vx * balle.speed * dt)
balle.y = balle.y + (balle.vy * balle.speed * dt)
-- rebonds murs, on accelere la vitesse de la balle a chaque rebonds
if balle.y <= 0 then
balle.y = 0
balle.vy = 0 - balle.vy
balle.speed = balle.speed + 20
elseif balle.y + balle.h >= 600 then
balle.y = 600 - balle.h
balle.vy = 0 - balle.vy
balle.speed = balle.speed + 20
end
-- rebonds raquettes
for n=1, 2 do
local pad = joueur[n].raquette
if CheckCollision(balle.x,balle.y,balle.w,balle.h, pad.x,pad.y,pad.w,pad.h) then
-- nouvel angle
local pointRepere
local decX = 20
if n == 1 then
pointRepere = {
x= pad.x - decX,
y=pad.y + (pad.h/2)
}
else
pointRepere = {
x= pad.x + pad.w + decX,
y=pad.y + (pad.h/2)
}
end
local angle = math.angle(pointRepere.x,pointRepere.y, balle.x+(balle.w/2),balle.y+(balle.h/2))
balle.vx = math.cos(angle)
balle.vy = math.sin(angle)
-- replace la balle
if n == 1 then
balle.x = pad.x + pad.w
else
balle.x = pad.x - balle.w
end
-- augmente la vitesse
balle.speed = balle.speed + 30
end
end
-- balle Out
if balle.x <= 0 then
balle.follow = true
balle.speed = balle.speedDef
joueur[2].score = joueur[2].score + 1
elseif balle.x + balle.w >= 800 then
balle.follow = true
balle.speed = balle.speedDef
joueur[1].score = joueur[1].score + 1
end
-- game win ?
for n=1, 2 do
if joueur[n].score >= 11 then
Game.over = true
Game.winner = n
end
end
end
end
--
function balle.draw()
love.graphics.rectangle("fill", balle.x, balle.y, balle.w, balle.h)
end
--
function filet.draw()
love.graphics.rectangle("fill", filet.x, filet.y, filet.w, filet.h)
end
--
function gameUI.draw()
love.graphics.print("J1 : "..joueur[1].score, 200, 10)
love.graphics.print("J2 : "..joueur[2].score, 600, 10)
end
--
--###### Love2D ######
function love.load()
love.graphics.setFont(love.graphics.newFont(22))
joueur.load()
end
--
function love.update(dt)
if Game.over then
-- nothing
else
balle.update(dt)
joueur.update(dt)
end
end
--
function love.draw()
if Game.over then
if Game.winner ==1 then
love.graphics.print("Player "..Game.winner.." Win !", 150, 100)
else
love.graphics.print("Player "..Game.winner.." Win !", 450, 100)
end
end
filet.draw()
joueur.draw()
balle.draw()
--
gameUI.draw()
end
--
function love.keypressed(k)
if balle.follow then
local j = joueur[balle.joueur] -- j1 ou j2 ?
if k == j.keys.fire then
if balle.joueur == 1 then
balle.vx = 1 -- la balle doit partir sur la droite
else
balle.vx = -1 -- la balle doit partir sur la gauche
end
-- direction de la balle au hasard (haut ou bas)
local vy = {-1, 1}
balle.vy = vy[love.math.random(#vy)]
--
balle.follow = false
-- prochain joueur a lancer la balle
if balle.joueur == 1 then
balle.joueur = 2
else
balle.joueur = 1
end
end
end
end
--C’est toujours améliorable, sons, musique, images etc…
Le jeu est simple car destiné en challenge pour les débutants.
J’ai volontairement mis en avant la logique du code pour les choses essentiels tels que le gameplay et une petite dynamique pour ne pas lasser les gens (même si ca reste un pong…).
Et les conditions de victoire pour jouer à 2 😉