Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- 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()
Advertisement