Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Declarations
- local updateLines
- local turnTransition
- local getSpritePixelData
- local constructSpriteColor
- local gameLoop
- local exited = false
- local replay = false
- local showControls
- local mainMenu
- local currentPiece
- local nextPiece
- local nextPieceSprite
- local currentSprite
- local downTimer
- local pieceActive
- local currentRotation
- local lines
- --local fallenPieces
- local fallenPieceSprite
- local timer
- local running
- local interval
- -- Initialization
- term.clear()
- term.setCursorPos(1,1)
- if not term.isColor() then
- print("This game requires and advanced computer to play")
- return
- end
- local function installAPI(name, code) -- Uses code from pastebin program
- if not fs.exists(name) then
- print(fs.getName(name).." API not found. Attempting to download...")
- local response = http.get(
- "http://pastebin.com/raw.php?i="..textutils.urlEncode( code )
- )
- if response then
- local sResponse = response.readAll()
- response.close()
- local file = fs.open( name, "w" )
- file.write( sResponse )
- file.close()
- print("Download successful")
- else
- print("Unable to connect to pastebin.com\nAPI download failed")
- return false
- end
- end
- getfenv(os.loadAPI).print = function() end
- local success = os.loadAPI(name)
- getfenv(os.loadAPI).print = print
- if not success then
- print(fs.getName(name).." API failed to load.")
- return false
- end
- return true
- end
- installAPI("CGE", "r2UReK1M")
- installAPI("menu", "UgMUtQGU")
- local width, height = term.getSize()
- local offset = math.floor((width-14)/2)
- local wall = {}
- for _=1,height do
- table.insert(wall, "||")
- end
- local wall1 = CGE.constructSprite(0, 0, wall, "wall1")
- local wall2 = CGE.constructSprite(12, 0, wall, "wall2")
- CGE.addSprites({wall1, wall2})
- local floor = CGE.constructSprite(1, height, {string.rep("-", 12)}, "floor")
- local ceiling = CGE.constructSprite(1, -1, {string.rep("-", 12)}, "ceiling")
- CGE.addSprite(floor)
- CGE.addSprite(ceiling)
- -- Sprites
- local sprites = {
- {{"&c&c&c&c"}, {"&c", "&c", "&c", "&c"}},
- {{"&e&e", "&e&e"}},
- {{"&1&1&1", " &1"}, {" &1", " &1", "&1&1"}, {"&1", "&1&1&1"}, {"&1&1", "&1", "&1"}},
- {{"&6&6&6", "&6"}, {"&6&6", " &6", " &6"}, {" &6", "&6&6&6"}, {"&6", "&6", "&6&6"}},
- {{" &5&5", "&5&5"}, {"&5", "&5&5", " &5"}},
- {{"&3&3&3", " &3"}, {" &3", "&3&3", " &3"}, {" &3", "&3&3&3"}, {"&3", "&3&3", "&3"}},
- {{"&a&a", " &a&a"}, {" &a", "&a&a", "&a"}}
- }
- local offsets = {
- {{1,-2},{-1,2}},
- {{0,0}},
- {{1,-1},{-1,0},{1,0},{-1,1}},
- {{1,-1},{-1,0},{1,0},{-1,1}},
- {{1,0},{-1,0}},
- {{1,-1},{-1,0},{1,0},{-1,1}},
- {{1,-1},{-1,1}}
- }
- -- Variable preparation
- local function resetVars()
- nextPiece = math.random(1, 7)
- nextPieceSprite = constructSpriteColor(18, 4, sprites[nextPiece][1], "nextPieceSprite")
- pieceActive = false
- currentRotation = 0
- lines = 0
- fallenPieces = {}
- running = true
- interval = 0.5
- for _=1,height do
- table.insert(fallenPieces, {})
- end
- do
- local preSprite = {}
- for _,line in ipairs(fallenPieces) do
- local stringLine = ""
- for i=1,10 do
- stringLine = stringLine .. (line[i] or " ")
- end
- table.insert(preSprite, stringLine)
- end
- fallenPieceSprite = constructSpriteColor(2, 0, preSprite, "fallenPieceSprite")
- CGE.addSprite(fallenPieceSprite)
- end
- for _=1,height do
- table.insert(fallenPieces, {})
- end
- do
- local preSprite = {}
- for _,line in ipairs(fallenPieces) do
- local stringLine = ""
- for i=1,10 do
- stringLine = stringLine .. (line[i] or " ")
- end
- table.insert(preSprite, stringLine)
- end
- fallenPieceSprite = constructSpriteColor(2, 0, preSprite, "fallenPieceSprite")
- CGE.addSprite(fallenPieceSprite)
- end
- end
- local controls = {
- [keys.down] = function()
- if not downTimer then
- local movedSprite = CGE.moveSprite(currentSprite, 0, 1)
- if CGE.checkCollision(movedSprite, {fallenPieceSprite, floor}) then
- turnTransition()
- else
- CGE.changeSprite(currentSprite, movedSprite)
- currentSprite = CGE.getSprite("currentSprite")
- downTimer = os.startTimer(0.1)
- end
- end
- end,
- [keys.up] = function()
- currentRotation = (currentRotation+1) % #sprites[currentPiece]
- local posX, posY = unpack(CGE.getSpriteBounds(currentSprite))
- offY, offX = unpack(offsets[currentPiece][currentRotation+1])
- local rotatedSprite = constructSpriteColor(posX + offX - 1, posY + offY - 1, sprites[currentPiece][currentRotation+1], "currentSprite")
- if not CGE.checkCollision(rotatedSprite, {wall1, wall2, fallenPieceSprite, floor}) then
- CGE.changeSprite(currentSprite, rotatedSprite)
- currentSprite = CGE.getSprite("currentSprite")
- end
- end,
- [keys.left] = function()
- if not pieceActive then return end
- local movedSprite = CGE.moveSprite(currentSprite, -1, 0)
- if not CGE.checkCollision(movedSprite, {wall1, wall2, fallenPieceSprite}) then CGE.changeSprite(currentSprite, movedSprite) end
- currentSprite = CGE.getSprite("currentSprite")
- end,
- [keys.right] = function()
- if not pieceActive then return end
- local movedSprite = CGE.moveSprite(currentSprite, 1, 0)
- if not CGE.checkCollision(movedSprite, {wall1, wall2, fallenPieceSprite}) then CGE.changeSprite(currentSprite, movedSprite) end
- currentSprite = CGE.getSprite("currentSprite")
- end,
- [keys.space] = function()
- local wOffset = math.floor((width-15)/2)
- local hOffset = math.floor((height-9)/2)
- local pauseText = {
- "===============",
- "| Game Paused |",
- "| ----------- |",
- "| Press SPACE |",
- "| To Continue |",
- "| ----------- |",
- "| Press CTRL |",
- "| To Quit |",
- "==============="
- }
- for line = 1, 9 do
- term.setCursorPos(wOffset+1, hOffset+line)
- term.write(pauseText[line])
- end
- while true do
- local e,p = os.pullEvent()
- if e == "key" then
- if p == keys.space then break
- elseif p == keys.leftCtrl or p == keys.rightCtrl then running = false break end
- elseif e == "timer" and p == timer then
- timer = os.startTimer(interval)
- end
- end
- end
- }
- -- Redraw
- local function redraw()
- term.clear()
- local nextOffset = offset + 16
- term.setCursorPos(nextOffset, 2)
- term.write("Next Piece:")
- CGE.deleteSprite(nextPieceSprite)
- nextPieceSprite = constructSpriteColor(18, 4, sprites[nextPiece][1], "nextPieceSprite")
- CGE.addSprite(nextPieceSprite)
- CGE.colorDraw(offset, 0)
- term.setCursorPos(2,2)
- term.write("Lines: "..lines)
- end
- -- Other Functions
- function updateLines()
- if CGE.checkCollision(currentSprite, {ceiling}) then running = false return end
- pixels = getSpritePixelData(currentSprite)
- for _,pixel in ipairs(pixels) do
- local x, y = tonumber(pixel[1])-2, tonumber(pixel[2])
- fallenPieces[y][x] = pixel[3]
- end
- local lineCount = #fallenPieces
- local insertCount = 0
- for line=lineCount,1,-1 do
- local lineFound = true
- local pieceLine = fallenPieces[line]
- local space = false
- for i=1,10 do
- if not pieceLine[i] then
- lineFound = false
- break
- end
- end
- if lineFound then
- local pieceLine = fallenPieces[line]
- table.remove(fallenPieces, line)
- lines = lines + 1
- insertCount = insertCount + 1
- end
- end
- for _=1,insertCount do
- table.insert(fallenPieces, 1, {})
- end
- end
- function turnTransition()
- pieceActive = false
- updateLines()
- CGE.deleteSprite(currentSprite)
- local preSprite = {}
- for _,line in ipairs(fallenPieces) do
- local stringLine = ""
- for i=1,10 do
- stringLine = stringLine .. (line[i] or " ")
- end
- table.insert(preSprite, stringLine)
- end
- CGE.deleteSprite(fallenPieceSprite)
- fallenPieceSprite = constructSpriteColor(2, 0, preSprite, "fallenPieceSprite")
- CGE.addSprite(fallenPieceSprite)
- end
- function constructSpriteColor(sx, sy, stable, name, maxani)
- if maxani == nil then maxani = 1 end
- local nsprite = {}
- local cur = 1
- for i,v in ipairs(stable) do
- local y = i
- local line = v
- local x = 1
- local offsetX = 1
- while x <= string.len(line) do
- local type = string.sub(line, x, x)
- if type ~= " " then
- if type == "&" then type = string.sub(line, x, x+1); x = x + 1 end
- nsprite[cur] = (sx+offsetX)..":"..(sy+y)..":"..type..":"..name..":"..maxani..":"..(1)..":".."0,0,0"
- cur = cur + 1
- end
- x = x + 1
- offsetX = offsetX + 1
- end
- end
- return nsprite
- end
- function getSpritePixelData(sprite)
- local ttable = {}
- for i,v in ipairs(sprite) do
- local splt = CGE.split(v, ":")
- ttable[#ttable + 1] = {splt[1], splt[2], splt[3]}
- end
- return ttable
- end
- local function main()
- while not exited do
- mainMenu:display(false, true)
- end
- end
- function showControls()
- term.clear()
- term.setCursorPos(1,1)
- print("Right/left - Move piece right/left")
- print("Up - Rotate piece")
- print("Space - Pause")
- print("Down - Move piece down")
- print("\nPress any key to return to menu")
- while true do
- local e,p = os.pullEvent("key")
- if p ~= 1 then break end
- end
- end
- -- Game Loop
- function gameLoop()
- resetVars()
- term.clear()
- timer = os.startTimer(interval)
- while running do
- local event,p1 = os.pullEvent()
- if event == "timer" and p1 == timer then
- if not pieceActive then
- currentPiece = nextPiece
- nextPiece = math.random(1, 7)
- currentRotation = 0
- currentSprite = constructSpriteColor(2, -1, sprites[currentPiece][currentRotation+1], "currentSprite")
- CGE.addSprite(currentSprite)
- pieceActive = true
- else
- local movedSprite = CGE.moveSprite(currentSprite, 0, 1)
- if CGE.checkCollision(movedSprite, {fallenPieceSprite, floor}) then
- turnTransition()
- else
- CGE.changeSprite(currentSprite, movedSprite)
- currentSprite = CGE.getSprite("currentSprite")
- end
- end
- redraw()
- timer = os.startTimer(interval)
- elseif event == "timer" and p1 == downTimer then
- downTimer = nil
- elseif event == "key" and controls[p1] then
- controls[p1]()
- redraw()
- end
- end
- CGE.deleteSprite(currentSprite)
- CGE.deleteSprite(fallenPieceSprite)
- CGE.deleteSprite(nextPieceSprite)
- local wOffset = math.floor((width-16)/2)
- local hOffset = math.floor((height-8)/2)
- local score = tostring(lines)
- local pauseText = {
- "================",
- "| Game Over! |",
- "| ------------ |",
- "| Lines: "..score..string.rep(" ", 5-score:len()).." |",
- "| ------------ |",
- "| Press Space |",
- "| To Continue |",
- "================"
- }
- for line = 1, 8 do
- term.setCursorPos(wOffset+1, hOffset+line)
- term.write(pauseText[line])
- end
- while true do
- local e,p = os.pullEvent("key")
- if e == "key" and p == keys.space then break end
- end
- replayMenu:display(false, true)
- if replay then
- resetVars()
- return gameLoop()
- end
- end
- -- Menus
- mainMenu = menu.create("Tetro")
- mainMenu:addOption("Play", gameLoop)
- mainMenu:addOption("Controls", showControls)
- mainMenu:addOption("Exit", function() exited = true end)
- replayMenu = menu.create("Play again?")
- replayMenu:addOption("Yes", function() replay = true end)
- replayMenu:addOption("Exit Tetro", function() replay = false; exited = true end)
- replayMenu:addOption("Back to Main Menu", function() replay = false; exited = false end)
- -- Other Stuff
- main()
- for _,sprite in pairs(CGE.getSprites()) do
- CGE.deleteSprite(sprite)
- end
- term.clear()
- term.setCursorPos(1,1)
- print("Thank you for playing Tetro")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement