Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local w, h = term.getSize()
- local boardWidth, boardHeight = 10, 20
- local offsetX, offsetY = math.floor((w - boardWidth) / 2), math.floor((h - boardHeight) / 2)
- local settings = {
- plasmaEnabled = true,
- difficulty = 2
- }
- local pieces = {
- {{{0,0},{1,0},{0,1},{1,1}}},
- {{{0,0},{1,0},{2,0},{3,0}}, {{0,0},{0,1},{0,2},{0,3}}},
- {{{0,0},{1,0},{2,0},{2,1}}, {{1,0},{1,1},{1,2},{0,2}}, {{0,0},{0,1},{1,1},{2,1}}, {{0,0},{1,0},{0,1},{0,2}}},
- {{{0,0},{1,0},{2,0},{0,1}}, {{0,0},{1,0},{1,1},{1,2}}, {{2,0},{0,1},{1,1},{2,1}}, {{0,0},{0,1},{0,2},{1,2}}},
- {{{1,0},{2,0},{0,1},{1,1}}, {{0,0},{0,1},{1,1},{1,2}}},
- {{{0,0},{1,0},{1,1},{2,1}}, {{1,0},{0,1},{1,1},{0,2}}},
- {{{1,0},{0,1},{1,1},{2,1}}, {{0,0},{0,1},{1,1},{0,2}}, {{0,0},{1,0},{2,0},{1,1}}, {{1,0},{0,1},{1,1},{1,2}}}
- }
- local pieceColors = {
- colors.red,
- colors.blue,
- colors.green,
- colors.yellow,
- colors.magenta,
- colors.cyan,
- colors.white
- }
- local plasmaColors = {
- colors.red,
- colors.orange,
- colors.yellow,
- colors.lime,
- colors.green,
- colors.cyan,
- colors.lightBlue,
- colors.blue,
- colors.purple,
- colors.magenta,
- colors.pink,
- colors.brown,
- colors.white,
- colors.lightGray,
- colors.gray,
- colors.black
- }
- local board = {}
- local currentPiece = nil
- local currentPieceColor = 1
- local currentRotation = 1
- local currentX, currentY = 0, 0
- local score = 0
- local gameOver = false
- local plasmaBuffer = {}
- for y = 1, boardHeight do
- board[y] = {}
- for x = 1, boardWidth do
- board[y][x] = 0
- end
- end
- for y = 1, h do
- plasmaBuffer[y] = {}
- for x = 1, w do
- plasmaBuffer[y][x] = colors.black
- end
- end
- local function calculatePlasma(t)
- for y = 1, h do
- for x = 1, w do
- local v = math.sin(x/4) + math.sin(y/8) + math.sin((x+y+t)/16)
- local colorIndex = math.floor((v + 3) * 8) % 16 + 1
- plasmaBuffer[y][x] = plasmaColors[colorIndex]
- end
- end
- end
- local function drawPiece()
- if not currentPiece then return end
- for _, block in ipairs(pieces[currentPiece][currentRotation]) do
- local x, y = currentX + block[1], currentY + block[2]
- if x > 0 and x <= boardWidth and y > 0 and y <= boardHeight then
- term.setCursorPos(x + offsetX, y + offsetY)
- term.setBackgroundColor(pieceColors[currentPieceColor])
- term.write(" ")
- end
- end
- end
- local function checkCollision(pieceType, rotation, testX, testY)
- if not pieceType or not rotation then return true end
- for _, block in ipairs(pieces[pieceType][rotation]) do
- local x, y = (testX or 0) + block[1], (testY or 0) + block[2]
- if x < 1 or x > boardWidth or y > boardHeight then
- return true
- end
- if y > 0 and board[y] and board[y][x] and board[y][x] ~= 0 then
- return true
- end
- end
- return false
- end
- local function lockPiece()
- if not currentPiece then return end
- for _, block in ipairs(pieces[currentPiece][currentRotation]) do
- local x, y = currentX + block[1], currentY + block[2]
- if y > 0 and y <= boardHeight and x > 0 and x <= boardWidth then
- board[y][x] = currentPieceColor
- end
- end
- end
- local function clearLines()
- local linesCleared = 0
- for y = boardHeight, 1, -1 do
- local full = true
- for x = 1, boardWidth do
- if board[y][x] == 0 then
- full = false
- break
- end
- end
- if full then
- linesCleared = linesCleared + 1
- table.remove(board, y)
- table.insert(board, 1, {})
- for x = 1, boardWidth do
- board[1][x] = 0
- end
- end
- end
- score = score + linesCleared * 100
- end
- local function drawGame()
- if settings.plasmaEnabled then
- for y = 1, h do
- for x = 1, w do
- term.setCursorPos(x, y)
- term.setBackgroundColor(plasmaBuffer[y][x])
- term.write(" ")
- end
- end
- else
- term.setBackgroundColor(colors.black)
- term.clear()
- end
- for y = offsetY - 1, offsetY + boardHeight do
- term.setCursorPos(offsetX - 1, y)
- term.setBackgroundColor(colors.lightGray)
- term.write("█")
- term.setCursorPos(offsetX + boardWidth, y)
- term.write("█")
- end
- for x = offsetX - 1, offsetX + boardWidth do
- term.setCursorPos(x, offsetY - 1)
- term.setBackgroundColor(colors.lightGray)
- term.write("█")
- term.setCursorPos(x, offsetY + boardHeight)
- term.write("█")
- end
- for y = 1, boardHeight do
- for x = 1, boardWidth do
- term.setCursorPos(x + offsetX, y + offsetY)
- if board[y][x] ~= 0 then
- term.setBackgroundColor(pieceColors[board[y][x]])
- else
- term.setBackgroundColor(colors.black)
- end
- term.write(" ")
- end
- end
- drawPiece()
- term.setCursorPos(1, 1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.write("Score: " .. score)
- end
- local function plasmaProcess()
- local t = 0
- while not gameOver do
- calculatePlasma(t)
- t = t + 0.1
- sleep(0.05)
- end
- end
- local function gameProcess()
- local difficultySpeed = {0.8, 0.5, 0.3}
- while not gameOver do
- if currentPiece and not checkCollision(currentPiece, currentRotation, currentX, (currentY or 0) + 1) then
- currentY = (currentY or 0) + 1
- else
- if currentPiece then
- lockPiece()
- clearLines()
- end
- currentPiece = math.random(1, #pieces)
- currentPieceColor = math.random(1, #pieceColors)
- currentRotation = 1
- currentX = math.floor(boardWidth / 2) - 1
- currentY = 0
- if checkCollision(currentPiece, currentRotation, currentX, currentY) then
- gameOver = true
- end
- end
- drawGame()
- sleep(difficultySpeed[settings.difficulty])
- end
- end
- local function inputProcess()
- while not gameOver do
- local event, key = os.pullEvent("key")
- if currentPiece then
- if key == keys.left and not checkCollision(currentPiece, currentRotation, (currentX or 0) - 1, currentY) then
- currentX = (currentX or 0) - 1
- elseif key == keys.right and not checkCollision(currentPiece, currentRotation, (currentX or 0) + 1, currentY) then
- currentX = (currentX or 0) + 1
- elseif key == keys.up then
- local newRotation = currentRotation % #pieces[currentPiece] + 1
- if not checkCollision(currentPiece, newRotation, currentX, currentY) then
- currentRotation = newRotation
- end
- elseif key == keys.down then
- while not checkCollision(currentPiece, currentRotation, currentX, (currentY or 0) + 1) do
- currentY = (currentY or 0) + 1
- end
- end
- drawGame()
- end
- end
- end
- local function drawTitleScreen()
- term.clear()
- term.setCursorPos(1, 1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- local title = {
- " _____ _____ ___________ _____ _____ ",
- "|_ _| ___|_ _| ___ \\_ _/ ___|",
- " | | | |__ | | | |_/ / | | \\ `--. ",
- " | | | __| | | | / | | `--. \\",
- " | | | |___ | | | |\\ \\ _| |_/\\__/ /",
- " \\_/ \\____/ \\_/ \\_| \\_\\___/\\____/ "
- }
- local startY = math.floor((h - #title) / 2) - 5
- for i, line in ipairs(title) do
- term.setCursorPos(math.floor((w - #line) / 2), startY + i)
- term.write(line)
- end
- term.setCursorPos(math.floor(w/2) - 6, startY + #title + 3)
- term.write("[ Press ENTER to Start ]")
- term.setCursorPos(math.floor(w/2) - 8, startY + #title + 5)
- term.write("[ Press L for Leaderboard ]")
- term.setCursorPos(math.floor(w/2) - 7, startY + #title + 7)
- term.write("[ Press S for Settings ]")
- term.setCursorPos(math.floor(w/2) - 6, startY + #title + 9)
- term.write("[ Press C for Credits ]")
- term.setCursorPos(math.floor(w/2) - 5, startY + #title + 11)
- term.write("[ Press Q to Quit ]")
- end
- local leaderboard = {}
- local function saveScore(name, score)
- table.insert(leaderboard, {name = name or "Unknown", score = score or 0})
- table.sort(leaderboard, function(a, b)
- return (a.score or 0) > (b.score or 0)
- end)
- if #leaderboard > 10 then
- table.remove(leaderboard, 11)
- end
- local file = fs.open("tetris_leaderboard", "w")
- if file then
- for _, entry in ipairs(leaderboard) do
- local entryName = entry.name or "Unknown"
- local entryScore = entry.score or 0
- file.writeLine(entryName .. "," .. tostring(entryScore))
- end
- file.close()
- else
- print("Error: Unable to open file for writing")
- end
- end
- local function loadLeaderboard()
- if fs.exists("tetris_leaderboard") then
- local file = fs.open("tetris_leaderboard", "r")
- if file then
- while true do
- local line = file.readLine()
- if not line then break end
- local name, score = line:match("([^,]+),(%d+)")
- table.insert(leaderboard, {name = name, score = tonumber(score)})
- end
- file.close()
- else
- print("Error: Unable to open leaderboard file for reading")
- end
- end
- end
- local function drawLeaderboard()
- term.clear()
- term.setCursorPos(1, 1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.setCursorPos(math.floor(w/2) - 5, 2)
- term.write("LEADERBOARD")
- for i, entry in ipairs(leaderboard) do
- term.setCursorPos(math.floor(w/2) - 10, i + 4)
- local name = entry.name or "Unknown"
- local score = entry.score or 0
- term.write(string.format("%2d. %-10s %5d", i, name, score))
- end
- term.setCursorPos(math.floor(w/2) - 11, h - 2)
- term.write("[ Press any key to return ]")
- os.pullEvent("key")
- end
- local function drawSettingsMenu()
- local function toggleSetting(setting)
- settings[setting] = not settings[setting]
- end
- local function changeDifficulty()
- settings.difficulty = (settings.difficulty % 3) + 1
- end
- while true do
- term.clear()
- term.setCursorPos(1, 1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.setCursorPos(math.floor(w/2) - 4, 2)
- term.write("SETTINGS")
- term.setCursorPos(2, 5)
- term.write("1. Plasma Effect: " .. (settings.plasmaEnabled and "ON" or "OFF"))
- term.setCursorPos(2, 7)
- local difficultyText = {"Easy", "Normal", "Hard"}
- term.write("2. Difficulty: " .. difficultyText[settings.difficulty])
- term.setCursorPos(2, 9)
- term.write("3. Back to Main Menu")
- term.setCursorPos(2, h-1)
- term.write("Enter your choice (1-3): ")
- local _, key = os.pullEvent("key")
- if key == keys.one then
- toggleSetting("plasmaEnabled")
- elseif key == keys.two then
- changeDifficulty()
- elseif key == keys.three then
- break
- end
- end
- end
- local function drawCredits()
- term.clear()
- term.setCursorPos(1, 1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.setCursorPos(math.floor(w/2) - 3, 2)
- term.write("CREDITS")
- local credits = {
- "Inspired from XIXIT (effects)",
- "Based on the classic Tetris game",
- "For ComputerCraft",
- "Special Thanks For the ComputerCraft Community",
- "© 2024 nonogamer9"
- }
- local startY = math.floor((h - #credits) / 2)
- for i, line in ipairs(credits) do
- term.setCursorPos(math.floor((w - #line) / 2), startY + i)
- term.write(line)
- end
- term.setCursorPos(math.floor(w/2) - 11, h - 2)
- term.write("[ Press any key to return ]")
- os.pullEvent("key")
- end
- loadLeaderboard()
- local running = true
- while running do
- drawTitleScreen()
- local event, key = os.pullEvent("key")
- if key == keys.enter then
- currentPiece = math.random(1, #pieces)
- currentPieceColor = math.random(1, #pieceColors)
- currentRotation = 1
- currentX = math.floor(boardWidth / 2) - 1
- currentY = 0
- score = 0
- gameOver = false
- for y = 1, boardHeight do
- for x = 1, boardWidth do
- board[y][x] = 0
- end
- end
- parallel.waitForAll(plasmaProcess, gameProcess, inputProcess)
- term.clear()
- term.setCursorPos(1, h/2 - 1)
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.black)
- term.write("Game Over! Final Score: " .. score)
- term.setCursorPos(1, h/2 + 1)
- term.write("Enter your name: ")
- local name = read()
- saveScore(name, score)
- elseif key == keys.l then
- drawLeaderboard()
- elseif key == keys.s then
- drawSettingsMenu()
- elseif key == keys.c then
- drawCredits()
- elseif key == keys.q then
- term.clear()
- term.setCursorPos(1, h/2)
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.black)
- term.write("Thanks for playing Tetris! Goodbye!")
- sleep(2)
- running = false
- end
- end
- term.clear()
- term.setCursorPos(1, 1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement