-- Breakout Game for SimpleOS -- CC: Tweaked compatible local w, h = term.getSize() h = h - 1 -- Game state local paddleX = math.floor(w/2) - 3 local paddleWidth = 7 local ballX, ballY = math.floor(w/2), h - 3 local ballDX, ballDY = 1, -1 local bricks = {} local score = 0 local lives = 3 local gameOver = false local gameWon = false local speed = 0.05 local ballActive = false -- Brick settings local brickRows = 5 local brickCols = math.floor((w - 4) / 4) local brickWidth = 3 local brickStartY = 3 -- Brick colors local brickColors = { colors.red, colors.orange, colors.yellow, colors.green, colors.cyan } -- Initialize bricks local function initBricks() bricks = {} for row = 1, brickRows do bricks[row] = {} for col = 1, brickCols do bricks[row][col] = true end end end -- Count remaining bricks local function countBricks() local count = 0 for row = 1, brickRows do for col = 1, brickCols do if bricks[row][col] then count = count + 1 end end end return count end -- Reset ball local function resetBall() ballX = paddleX + paddleWidth / 2 ballY = h - 3 ballDX = (math.random(2) == 1) and 1 or -1 ballDY = -1 ballActive = false end -- Draw game local function draw() term.setBackgroundColor(colors.black) term.clear() -- Draw bricks for row = 1, brickRows do for col = 1, brickCols do if bricks[row][col] then local x = 2 + (col - 1) * (brickWidth + 1) local y = brickStartY + row - 1 term.setBackgroundColor(brickColors[row] or colors.white) term.setCursorPos(x, y) term.write(string.rep(" ", brickWidth)) end end end -- Draw paddle term.setBackgroundColor(colors.white) term.setCursorPos(paddleX, h - 1) term.write(string.rep(" ", paddleWidth)) -- Draw ball term.setBackgroundColor(colors.black) term.setTextColor(colors.yellow) term.setCursorPos(math.floor(ballX), math.floor(ballY)) term.write("O") -- Draw info 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("Score: " .. score .. " Lives: " .. lives) term.setCursorPos(w - 7, h + 1) term.write("[Q]uit") -- Instructions if not ballActive and not gameOver and not gameWon then term.setBackgroundColor(colors.black) term.setTextColor(colors.gray) term.setCursorPos(math.floor(w/2) - 8, math.floor(h/2)) term.write("Press SPACE to launch") end end -- Update ball local function update() if not ballActive then ballX = paddleX + paddleWidth / 2 return end ballX = ballX + ballDX ballY = ballY + ballDY -- Wall collisions if ballX <= 1 then ballX = 1 ballDX = math.abs(ballDX) elseif ballX >= w then ballX = w ballDX = -math.abs(ballDX) end if ballY <= 1 then ballY = 1 ballDY = math.abs(ballDY) end -- Paddle collision if ballY >= h - 2 and ballY <= h - 1 then if ballX >= paddleX and ballX <= paddleX + paddleWidth then ballDY = -math.abs(ballDY) -- Adjust angle based on hit position local hitPos = (ballX - paddleX) / paddleWidth ballDX = (hitPos - 0.5) * 3 if math.abs(ballDX) < 0.5 then ballDX = (ballDX >= 0) and 0.5 or -0.5 end end end -- Brick collisions for row = 1, brickRows do for col = 1, brickCols do if bricks[row][col] then local bx = 2 + (col - 1) * (brickWidth + 1) local by = brickStartY + row - 1 if ballX >= bx and ballX < bx + brickWidth and math.floor(ballY) == by then bricks[row][col] = false score = score + (brickRows - row + 1) * 10 ballDY = -ballDY if countBricks() == 0 then gameWon = true end end end end end -- Ball lost if ballY > h then lives = lives - 1 if lives <= 0 then gameOver = true else resetBall() end end end -- Game over screen local function showGameOver() term.setBackgroundColor(colors.black) term.setTextColor(colors.red) term.setCursorPos(math.floor(w/2) - 4, math.floor(h/2)) term.write("GAME OVER") term.setTextColor(colors.white) term.setCursorPos(math.floor(w/2) - 6, math.floor(h/2) + 1) term.write("Score: " .. score) term.setCursorPos(math.floor(w/2) - 8, math.floor(h/2) + 3) term.write("ENTER=Restart Q=Quit") end -- Win screen local function showWin() term.setBackgroundColor(colors.black) term.setTextColor(colors.lime) term.setCursorPos(math.floor(w/2) - 4, math.floor(h/2)) term.write("YOU WIN!") term.setTextColor(colors.white) term.setCursorPos(math.floor(w/2) - 6, math.floor(h/2) + 1) term.write("Score: " .. score) term.setCursorPos(math.floor(w/2) - 8, math.floor(h/2) + 3) term.write("ENTER=Restart Q=Quit") end -- Main game loop local function run() initBricks() resetBall() score = 0 lives = 3 gameOver = false gameWon = false paddleX = math.floor(w/2) - 3 while true do draw() if gameOver then showGameOver() elseif gameWon then showWin() end local timer = os.startTimer(speed) while true do local event, p1 = os.pullEvent() if event == "key" then if gameOver or gameWon then if p1 == keys.enter then initBricks() resetBall() score = 0 lives = 3 gameOver = false gameWon = false paddleX = math.floor(w/2) - 3 break elseif p1 == keys.q then return end else if p1 == keys.left then paddleX = math.max(1, paddleX - 2) elseif p1 == keys.right then paddleX = math.min(w - paddleWidth, paddleX + 2) elseif p1 == keys.space then ballActive = true elseif p1 == keys.q then return end end if not (gameOver or gameWon) then draw() end elseif event == "timer" and p1 == timer then break end end if not (gameOver or gameWon) then update() end end end run()