-- Pong Game for SimpleOS
-- CC: Tweaked compatible
local w, h = term.getSize()
h = h - 1 -- Leave room for score
-- Game state
local paddle1Y, paddle2Y = math.floor(h/2) - 1, math.floor(h/2) - 1
local paddleHeight = 4
local ballX, ballY = math.floor(w/2), math.floor(h/2)
local ballDX, ballDY = 1, 0
local score1, score2 = 0, 0
local gameOver = false
local speed = 0.08
local aiMode = true -- Single player by default
-- Reset ball
local function resetBall(direction)
ballX = math.floor(w/2)
ballY = math.floor(h/2)
ballDX = direction or (math.random(2) == 1 and 1 or -1)
ballDY = (math.random(3) - 2) * 0.5
end
-- Draw game
local function draw()
term.setBackgroundColor(colors.black)
term.clear()
-- Draw center line
term.setTextColor(colors.gray)
for y = 1, h do
if y % 2 == 0 then
term.setCursorPos(math.floor(w/2), y)
term.write("|")
end
end
-- Draw paddles
term.setBackgroundColor(colors.white)
for i = 0, paddleHeight - 1 do
term.setCursorPos(2, paddle1Y + i)
term.write(" ")
term.setCursorPos(w - 1, paddle2Y + i)
term.write(" ")
end
-- Draw ball
term.setBackgroundColor(colors.black)
term.setTextColor(colors.yellow)
term.setCursorPos(math.floor(ballX), math.floor(ballY))
term.write("O")
-- Draw score bar
term.setBackgroundColor(colors.gray)
for x = 1, w do
term.setCursorPos(x, h + 1)
term.write(" ")
end
term.setTextColor(colors.white)
term.setCursorPos(2, h + 1)
term.write("P1: " .. score1)
term.setCursorPos(w - 7, h + 1)
term.write("P2: " .. score2)
term.setCursorPos(math.floor(w/2) - 3, h + 1)
term.write("[Q]uit")
end
-- AI movement
local function moveAI()
local targetY = ballY - paddleHeight / 2
if paddle2Y < targetY - 1 then
paddle2Y = math.min(paddle2Y + 1, h - paddleHeight + 1)
elseif paddle2Y > targetY + 1 then
paddle2Y = math.max(paddle2Y - 1, 1)
end
end
-- Update ball
local function update()
ballX = ballX + ballDX
ballY = ballY + ballDY
-- Top/bottom bounce
if ballY <= 1 then
ballY = 1
ballDY = -ballDY
elseif ballY >= h then
ballY = h
ballDY = -ballDY
end
-- Paddle 1 collision
if ballX <= 3 and ballX >= 2 then
if ballY >= paddle1Y and ballY < paddle1Y + paddleHeight then
ballDX = math.abs(ballDX)
local hitPos = (ballY - paddle1Y) / paddleHeight
ballDY = (hitPos - 0.5) * 2
end
end
-- Paddle 2 collision
if ballX >= w - 2 and ballX <= w - 1 then
if ballY >= paddle2Y and ballY < paddle2Y + paddleHeight then
ballDX = -math.abs(ballDX)
local hitPos = (ballY - paddle2Y) / paddleHeight
ballDY = (hitPos - 0.5) * 2
end
end
-- Scoring
if ballX < 1 then
score2 = score2 + 1
resetBall(-1)
elseif ballX > w then
score1 = score1 + 1
resetBall(1)
end
-- Win condition
if score1 >= 10 or score2 >= 10 then
gameOver = true
end
end
-- Game over screen
local function showGameOver()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.yellow)
term.setCursorPos(math.floor(w/2) - 5, math.floor(h/2) - 1)
if score1 >= 10 then
term.write("PLAYER 1 WINS!")
else
term.write("PLAYER 2 WINS!")
end
term.setTextColor(colors.white)
term.setCursorPos(math.floor(w/2) - 10, math.floor(h/2) + 1)
term.write("Press ENTER to restart")
term.setCursorPos(math.floor(w/2) - 7, math.floor(h/2) + 2)
term.write("Press Q to quit")
end
-- Main game loop
local function run()
resetBall()
score1, score2 = 0, 0
gameOver = false
paddle1Y = math.floor(h/2) - paddleHeight/2
paddle2Y = math.floor(h/2) - paddleHeight/2
-- Mode selection
term.setBackgroundColor(colors.black)
term.clear()
term.setTextColor(colors.yellow)
term.setCursorPos(math.floor(w/2) - 3, math.floor(h/2) - 2)
term.write("PONG")
term.setTextColor(colors.white)
term.setCursorPos(math.floor(w/2) - 10, math.floor(h/2))
term.write("[1] Single Player (vs AI)")
term.setCursorPos(math.floor(w/2) - 8, math.floor(h/2) + 1)
term.write("[2] Two Players")
while true do
local event, key = os.pullEvent("key")
if key == keys.one then
aiMode = true
break
elseif key == keys.two then
aiMode = false
break
elseif key == keys.q then
return
end
end
while true do
draw()
if gameOver then
showGameOver()
while true do
local event, key = os.pullEvent("key")
if key == keys.enter then
resetBall()
score1, score2 = 0, 0
gameOver = false
paddle1Y = math.floor(h/2) - paddleHeight/2
paddle2Y = math.floor(h/2) - paddleHeight/2
break
elseif key == keys.q then
return
end
end
end
local timer = os.startTimer(speed)
while true do
local event, p1 = os.pullEvent()
if event == "key" then
-- Player 1 controls (W/S)
if p1 == keys.w then
paddle1Y = math.max(1, paddle1Y - 1)
elseif p1 == keys.s then
paddle1Y = math.min(h - paddleHeight + 1, paddle1Y + 1)
end
-- Player 2 controls (Up/Down) - only in 2P mode
if not aiMode then
if p1 == keys.up then
paddle2Y = math.max(1, paddle2Y - 1)
elseif p1 == keys.down then
paddle2Y = math.min(h - paddleHeight + 1, paddle2Y + 1)
end
end
if p1 == keys.q then
return
end
draw()
elseif event == "timer" and p1 == timer then
break
end
end
if aiMode then
moveAI()
end
update()
end
end
run()