Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local gridSize = 4
- local function getOSVersion()
- local v = os.version()
- if v:find("1%.7") then return "1.7.10"
- elseif v:find("1%.8") then return "1.8"
- elseif v:find("1%.9") then return "1.9"
- else return "tweaked" end
- end
- local OS_VER = getOSVersion()
- local isCC_Tweaked = (OS_VER == "tweaked" or OS_VER == "1.9")
- local isVanilla = (OS_VER == "1.8")
- local isLegacy = (OS_VER == "1.7.10")
- local hasWget = http and http.checkURL and shell and shell.run
- local function wget(url, filename)
- if not hasWget then return false end
- if fs.exists(filename) then return true end
- local ok, err = pcall(function()
- shell.run("wget", url, filename)
- end)
- return fs.exists(filename)
- end
- local function isMosaicCapable()
- local v = os.version()
- local major = tonumber(v:match("(%d+)%.%d+"))
- return major and major >= 2 or v:find("1%.8") or v:find("1%.9")
- end
- local mosaicCapable = isMosaicCapable()
- local isColor = term.isColor()
- local w, h = term.getSize()
- local tileColors, plasmaColors, mode7Colors
- if isColor then
- tileColors = {
- [0] = colors.gray,
- [2] = colors.white,
- [4] = colors.lightGray,
- [8] = colors.yellow,
- [16] = colors.orange,
- [32] = colors.red,
- [64] = colors.magenta,
- [128] = colors.purple,
- [256] = colors.blue,
- [512] = colors.cyan,
- [1024] = colors.green,
- [2048] = colors.lime,
- [4096] = colors.brown,
- [8192] = colors.pink,
- }
- plasmaColors = {
- colors.black, colors.blue, colors.green, colors.cyan,
- colors.red, colors.purple, colors.brown, colors.lightGray,
- colors.gray, colors.lightBlue, colors.lime, colors.yellow,
- colors.pink, colors.magenta, colors.orange, colors.white
- }
- mode7Colors = {colors.lightGray, colors.gray}
- else
- tileColors = {
- [0] = colors.gray,
- [2] = colors.white,
- [4] = colors.gray,
- [8] = colors.white,
- [16] = colors.gray,
- [32] = colors.white,
- [64] = colors.gray,
- [128] = colors.white,
- [256] = colors.gray,
- [512] = colors.white,
- [1024] = colors.gray,
- [2048] = colors.white,
- [4096] = colors.gray,
- [8192] = colors.white,
- }
- plasmaColors = {colors.black, colors.gray, colors.white}
- mode7Colors = {colors.white, colors.gray}
- end
- -- Shadow color mapping for pretty shadows
- local tileShadowColors = {
- [colors.white] = colors.lightGray,
- [colors.lightGray] = colors.gray,
- [colors.yellow] = colors.orange,
- [colors.orange] = colors.red,
- [colors.red] = colors.brown,
- [colors.magenta] = colors.purple,
- [colors.purple] = colors.blue,
- [colors.blue] = colors.cyan,
- [colors.cyan] = colors.gray,
- [colors.green] = colors.lime,
- [colors.lime] = colors.green,
- [colors.brown] = colors.gray,
- [colors.pink] = colors.magenta,
- [colors.gray] = colors.black,
- [colors.black] = colors.black,
- [colors.lightBlue] = colors.blue,
- }
- local UPPER = "\143"
- local LOWER = "\131"
- local FULL = "\132"
- local SPACE = " "
- local function mosaicPixelColor(val)
- if isColor then
- return plasmaColors[math.floor(val * (#plasmaColors-1)) + 1]
- else
- if val < 0.33 then return colors.black
- elseif val < 0.66 then return colors.gray
- else return colors.white end
- end
- end
- local function newBuffer()
- local buf = {}
- for y=1,h do
- buf[y] = {}
- for x=1,w do
- buf[y][x] = {bg=colors.black, fg=colors.white, ch=" "}
- end
- end
- return buf
- end
- local function blitToTerm(buf)
- for y=1,h do
- local bgLine, fgLine, chLine = "", "", ""
- for x=1,w do
- local cell = buf[y][x]
- bgLine = bgLine .. string.format("%x", math.log(cell.bg)/math.log(2))
- fgLine = fgLine .. string.format("%x", math.log(cell.fg)/math.log(2))
- chLine = chLine .. cell.ch
- end
- term.setCursorPos(1, y)
- term.blit(chLine, fgLine, bgLine)
- end
- end
- local speaker = peripheral.find("speaker")
- local canPlayMusic = false
- local canPlaySound = false
- if isCC_Tweaked or isVanilla or isLegacy then
- if speaker then
- canPlaySound = true
- if isCC_Tweaked then
- canPlayMusic = true
- end
- end
- end
- local TITLE_URL = "https://files.catbox.moe/ji6xje.raw"
- local GAME_URL = "https://files.catbox.moe/y2w7rv.raw"
- local TITLE_FILE = "nono2048_title.raw"
- local GAME_FILE = "nono2048_game.raw"
- local function playPCM(filename, inputSampleRate, stopFlag)
- if not canPlayMusic then return end
- while not stopFlag[1] do
- local file = fs.open(filename, "rb")
- if not file then break end
- local chunkSize = 8192
- local outputSampleRate = 48000
- local ratio = inputSampleRate / outputSampleRate
- local samplesPerChunk = math.floor(chunkSize / ratio)
- local filePos = 0
- local totalBytes = fs.getSize(filename)
- local playedBytes = 0
- while not stopFlag[1] and playedBytes < totalBytes do
- file.seek("set", filePos)
- local rawChunk = {}
- for i = 1, chunkSize do
- local byte = file.read()
- if not byte then break end
- table.insert(rawChunk, byte - 128)
- filePos = filePos + 1
- playedBytes = playedBytes + 1
- end
- if #rawChunk == 0 then break end
- local chunk = {}
- if inputSampleRate ~= outputSampleRate then
- for i = 1, math.floor(#rawChunk / ratio) do
- local src = (i - 1) * ratio + 1
- local idx = math.floor(src)
- local frac = src - idx
- local s1 = rawChunk[idx] or 0
- local s2 = rawChunk[idx + 1] or s1
- table.insert(chunk, math.floor(s1 + (s2 - s1) * frac + 0.5))
- end
- else
- chunk = rawChunk
- end
- while not speaker.playAudio(chunk) do
- os.pullEvent("speaker_audio_empty")
- end
- os.sleep(0)
- end
- file.close()
- end
- end
- -- Only use 1.12.2 noteblock sounds for CraftOS 1.8
- local vanillaInstruments = {"harp", "bass", "snare", "hat", "basedrum", "guitar", "flute", "bell", "chime", "xylophone"}
- local tweakedInstruments = {"harp", "bass", "bell", "chime", "flute", "guitar", "xylophone", "bit"}
- local function playMergeSound(val)
- if not canPlaySound then return end
- local instruments = isVanilla and vanillaInstruments or tweakedInstruments
- local idx = 1
- if val then
- idx = (math.log(val or 2)/math.log(2)) % #instruments + 1
- end
- local instrument = instruments[math.floor(idx)]
- local logVal = val and math.log(val)/math.log(2) or 1
- local pitch = 0.5 + math.min(2, logVal) / 8
- if speaker.playNote then
- speaker.playNote(instrument, 3, pitch)
- elseif speaker.playSound then
- speaker.playSound("block.note_block."..instrument, 3, 1)
- end
- end
- local musicStopFlag = {false}
- local function startMusic(filename, inputSampleRate)
- musicStopFlag[1] = false
- parallel.waitForAny(
- function() playPCM(filename, inputSampleRate, musicStopFlag) end
- )
- end
- local function stopMusic()
- musicStopFlag[1] = true
- os.queueEvent("music_stop")
- end
- if isCC_Tweaked and canPlayMusic then
- if hasWget then
- wget(TITLE_URL, TITLE_FILE)
- wget(GAME_URL, GAME_FILE)
- else
- if not fs.exists(TITLE_FILE) or not fs.exists(GAME_FILE) then
- end
- end
- end
- local function drawMosaicBackground(buf, t, mode, isMode7)
- for y=1,h do
- for x=1,w do
- local top, bottom
- if isMode7 then
- local function mode7Pixel(px, py)
- local mosaicH = h*2
- local cx, cy = w/2, mosaicH/2
- local camHeight, horizon, scale = 8, mosaicH/2*0.6, 0.7
- local dx, dy = (px - cx), (py - cy)
- local perspective = camHeight / (dy + horizon)
- local wx = dx * perspective * scale
- local wy = perspective * scale
- local angle = t
- local cosA, sinA = math.cos(angle), math.sin(angle)
- local u = 16 + wx * cosA - wy * sinA
- local v = 16 + wx * sinA + wy * cosA
- local tx = math.floor(u) % 32
- local ty = math.floor(v) % 32
- return ((math.floor(tx/4) + math.floor(ty/4)) % 2 == 0) and mode7Colors[1] or mode7Colors[2]
- end
- top = mode7Pixel(x, (y-1)*2+1)
- bottom = mode7Pixel(x, (y-1)*2+2)
- else
- local function plasmaPixel(px, py)
- if mode == 1 then
- local v = math.sin(px/2 + t) + math.sin(py/1.5 + t/2) + math.sin((px+py)/2 + t/3)
- v = (v + 3) / 6
- return mosaicPixelColor(v)
- elseif mode == 2 then
- local v = math.sin(math.sqrt((px-13)^2 + (py-7)^2)/2 + t)
- v = (v + 1) / 2
- return mosaicPixelColor(v)
- elseif mode == 3 then
- local v = math.sin(px/2 + t) * math.cos(py/2 + t)
- v = (v + 1) / 2
- return mosaicPixelColor(v)
- else
- local v = math.sin((px + py)/2 + t) + math.cos((px - py)/2 - t)
- v = (v + 2) / 4
- return mosaicPixelColor(v)
- end
- end
- top = plasmaPixel(x, (y-1)*2+1)
- bottom = plasmaPixel(x, (y-1)*2+2)
- end
- if top == bottom then
- buf[y][x] = {bg=top, fg=top, ch=FULL}
- elseif top == colors.black and bottom == colors.black then
- buf[y][x] = {bg=colors.black, fg=colors.black, ch=SPACE}
- elseif top == colors.black then
- buf[y][x] = {bg=bottom, fg=top, ch=LOWER}
- elseif bottom == colors.black then
- buf[y][x] = {bg=top, fg=bottom, ch=UPPER}
- else
- buf[y][x] = {bg=bottom, fg=top, ch=LOWER}
- end
- end
- end
- end
- local mode7_bg = {}
- for y=0,31 do
- mode7_bg[y] = {}
- for x=0,31 do
- if ((math.floor(x/4) + math.floor(y/4)) % 2 == 0) then
- mode7_bg[y][x] = mode7Colors[1]
- else
- mode7_bg[y][x] = mode7Colors[2]
- end
- end
- end
- local function mode7Floor(x, y, angle)
- local cx, cy = w/2, h/2
- local camHeight = 8
- local horizon = cy * 0.6
- local scale = 0.7
- local dx = (x - cx)
- local dy = (y - cy)
- local perspective = camHeight / (dy + horizon)
- local wx = dx * perspective * scale
- local wy = perspective * scale
- local cosA, sinA = math.cos(angle), math.sin(angle)
- local u = 16 + wx * cosA - wy * sinA
- local v = 16 + wx * sinA + wy * cosA
- local tx = math.floor(u) % 32
- local ty = math.floor(v) % 32
- return mode7_bg[ty][tx]
- end
- local function drawTitleScreen(t)
- local buf = newBuffer()
- if mosaicCapable then
- drawMosaicBackground(buf, t, 1, true)
- else
- for y=1,h do
- for x=1,w do
- buf[y][x].bg = mode7Floor(x, y, t)
- buf[y][x].fg = colors.white
- buf[y][x].ch = " "
- end
- end
- end
- local title = mosaicCapable and "nono2048 3! by nonogamer9! [ENHANCED MODE!]" or "nono2048 3! by nonogamer9!"
- local subtitle = "Press any key to start"
- local tx = math.floor((w - #title) / 2) + 1
- local ty = math.floor(h / 2)
- for i=1,#title do
- buf[ty][tx+i-1].ch = title:sub(i,i)
- buf[ty][tx+i-1].fg = isColor and colors.yellow or colors.white
- buf[ty][tx+i-1].bg = colors.black
- end
- tx = math.floor((w - #subtitle) / 2) + 1
- ty = ty + 2
- for i=1,#subtitle do
- buf[ty][tx+i-1].ch = subtitle:sub(i,i)
- buf[ty][tx+i-1].fg = colors.white
- buf[ty][tx+i-1].bg = colors.black
- end
- blitToTerm(buf)
- end
- local function titleScreen()
- local t = 0
- local keyPressed = false
- local function animate()
- while not keyPressed do
- drawTitleScreen(t)
- t = t + 0.07
- os.sleep(0.04)
- end
- end
- local function input()
- os.pullEvent("key")
- keyPressed = true
- end
- if isCC_Tweaked and canPlayMusic and fs.exists(TITLE_FILE) then
- parallel.waitForAny(
- function() startMusic(TITLE_FILE, 32000) end,
- animate,
- input
- )
- stopMusic()
- else
- parallel.waitForAny(animate, input)
- end
- end
- local particles = {}
- local function spawnParticles(x, y, count)
- for i = 1, count do
- local angle = math.random() * math.pi * 2
- local speed = 0.2 + math.random() * 0.8
- table.insert(particles, {
- x = x + 0.5,
- y = y + 0.5,
- vx = math.cos(angle) * speed,
- vy = math.sin(angle) * speed,
- life = 10 + math.random(10),
- ch = "*",
- fg = colors.white,
- })
- end
- end
- local function updateParticles()
- local i = 1
- while i <= #particles do
- local p = particles[i]
- p.x = p.x + p.vx
- p.y = p.y + p.vy
- p.life = p.life - 1
- if p.life <= 0 then
- table.remove(particles, i)
- else
- i = i + 1
- end
- end
- end
- local function drawParticles(buf)
- for _, p in ipairs(particles) do
- local x, y = math.floor(p.x), math.floor(p.y)
- if x >= 1 and x <= w and y >= 1 and y <= h then
- buf[y][x].ch = p.ch
- buf[y][x].fg = p.fg
- buf[y][x].bg = colors.black
- end
- end
- end
- local function drawLogo(buf, t)
- local logo = "nono2048 3!"
- local rainbow = {
- colors.red, colors.orange, colors.yellow, colors.green,
- colors.cyan, colors.blue, colors.purple, colors.pink
- }
- -- Calculate board height and position
- local tileW, tileH = 4, 2
- local gap = 1
- local gridPixelH = gridSize * tileH + (gridSize-1)*gap
- local startY_board = math.max(1, math.floor((h - gridPixelH)/2) - 4)
- local boardBottom = startY_board + gridPixelH - 1
- -- Place logo 6 rows below the board, but not off the screen
- local startY = math.min(h, boardBottom + 6)
- local startX = math.floor((w - #logo) / 2) + 1
- for i = 1, #logo do
- local ch = logo:sub(i, i)
- local x = startX + i - 1
- local y = startY + math.floor(math.sin(t * 2 + i * 0.5) * 1.5)
- if y >= 1 and y <= h and x >= 1 and x <= w then
- if isColor then
- buf[y][x].ch = ch
- buf[y][x].fg = rainbow[(i-1) % #rainbow + 1]
- buf[y][x].bg = colors.black
- else
- buf[y][x].ch = ch
- buf[y][x].fg = (i%2==0) and colors.gray or colors.white
- buf[y][x].bg = colors.black
- end
- end
- end
- end
- local grid = {}
- local score = 0
- local currentPlasma = 1
- local seenDoubles = {}
- local mergedTi, mergedTj
- local function getTileColor(val)
- return tileColors[val] or (isColor and colors.white or colors.white)
- end
- local function initGrid()
- grid = {}
- for i=1,gridSize do
- grid[i] = {}
- for j=1,gridSize do
- grid[i][j] = 0
- end
- end
- end
- local function spawnTile()
- local empty = {}
- for i=1,gridSize do
- for j=1,gridSize do
- if grid[i][j] == 0 then table.insert(empty, {i, j}) end
- end
- end
- if #empty > 0 then
- local pos = empty[math.random(#empty)]
- grid[pos[1]][pos[2]] = (math.random() < 0.9) and 2 or 4
- end
- end
- local function canMove()
- for i=1,gridSize do
- for j=1,gridSize do
- if grid[i][j] == 0 then return true end
- if i < gridSize and grid[i][j] == grid[i+1][j] then return true end
- if j < gridSize and grid[i][j] == grid[i][j+1] then return true end
- end
- end
- return false
- end
- local function move(dir)
- local moved = false
- local merged = false
- local mergedValues = {}
- local mergedGrid = {}
- for i=1,gridSize do mergedGrid[i] = {}; for j=1,gridSize do mergedGrid[i][j] = false end end
- local function traverse(start, finish, step)
- local t = {}
- for i=start,finish,step do table.insert(t, i) end
- return t
- end
- local rows, cols
- if dir == "up" then
- rows, cols = traverse(1, gridSize, 1), traverse(1, gridSize, 1)
- elseif dir == "down" then
- rows, cols = traverse(gridSize, 1, -1), traverse(1, gridSize, 1)
- elseif dir == "left" then
- rows, cols = traverse(1, gridSize, 1), traverse(1, gridSize, 1)
- elseif dir == "right" then
- rows, cols = traverse(1, gridSize, 1), traverse(gridSize, 1, -1)
- end
- for _,i in ipairs(rows) do
- for _,j in ipairs(cols) do
- if grid[i][j] ~= 0 then
- local ni, nj = i, j
- while true do
- local ti, tj = ni, nj
- if dir == "up" then ti = ni - 1 end
- if dir == "down" then ti = ni + 1 end
- if dir == "left" then tj = nj - 1 end
- if dir == "right" then tj = nj + 1 end
- if ti < 1 or ti > gridSize or tj < 1 or tj > gridSize then break end
- if grid[ti][tj] == 0 then
- grid[ti][tj] = grid[ni][nj]
- grid[ni][nj] = 0
- ni, nj = ti, tj
- moved = true
- elseif grid[ti][tj] == grid[ni][nj] and not mergedGrid[ti][tj] then
- grid[ti][tj] = grid[ti][tj] * 2
- score = score + grid[ti][tj]
- grid[ni][nj] = 0
- mergedGrid[ti][tj] = true
- moved = true
- merged = true
- table.insert(mergedValues, grid[ti][tj])
- mergedTi, mergedTj = ti, tj
- break
- else
- break
- end
- end
- end
- end
- end
- return moved, merged, mergedValues
- end
- local function drawPlasmaToBuffer(buf, t)
- if mosaicCapable then
- drawMosaicBackground(buf, t, currentPlasma, false)
- return
- end
- local plasma
- if isColor then
- plasma = {
- function(x, y, t)
- local v = math.sin(x/2 + t) + math.sin(y/1.5 + t/2) + math.sin((x+y)/2 + t/3)
- v = (v + 3) / 6
- return plasmaColors[math.floor(v * (#plasmaColors-1)) + 1]
- end,
- function(x, y, t)
- local cx, cy = 13, 7
- local v = math.sin(math.sqrt((x-cx)^2 + (y-cy)^2)/2 + t)
- v = (v + 1) / 2
- return plasmaColors[math.floor(v * (#plasmaColors-1)) + 1]
- end,
- function(x, y, t)
- local v = math.sin(x/2 + t) * math.cos(y/2 + t)
- v = (v + 1) / 2
- return plasmaColors[math.floor(v * (#plasmaColors-1)) + 1]
- end,
- function(x, y, t)
- local v = math.sin((x + y)/2 + t) + math.cos((x - y)/2 - t)
- v = (v + 2) / 4
- return plasmaColors[math.floor(v * (#plasmaColors-1)) + 1]
- end,
- }
- else
- plasma = {
- function(x, y, t)
- local v = math.sin(x/2 + t) + math.sin(y/1.5 + t/2)
- v = (v + 2) / 4
- if v < 0.33 then return colors.black
- elseif v < 0.66 then return colors.gray
- else return colors.white end
- end,
- function(x, y, t)
- local v = math.sin((x+y)/3 + t)
- v = (v + 1) / 2
- if v < 0.33 then return colors.black
- elseif v < 0.66 then return colors.gray
- else return colors.white end
- end,
- function(x, y, t)
- local v = math.cos(x/3 + y/3 + t)
- v = (v + 1) / 2
- if v < 0.33 then return colors.black
- elseif v < 0.66 then return colors.gray
- else return colors.white end
- end,
- }
- end
- local func = plasma[currentPlasma]
- for y=1,h do
- for x=1,w do
- buf[y][x].bg = func(x, y, t)
- buf[y][x].ch = " "
- buf[y][x].fg = colors.white
- end
- end
- end
- local function drawGridToBuffer(buf)
- local tileW, tileH = 4, 2 -- width, height of each tile
- local gap = 1 -- gap between tiles
- local gridPixelW = gridSize * tileW + (gridSize-1)*gap
- local gridPixelH = gridSize * tileH + (gridSize-1)*gap
- local startX = math.floor((w - gridPixelW)/2) + 1
- local startY = math.max(1, math.floor((h - gridPixelH)/2) - 2)
- for i=1,gridSize do
- for j=1,gridSize do
- local val = grid[i][j]
- local bg = getTileColor(val)
- local fg = colors.black
- local s = val == 0 and "" or tostring(val)
- local pad = math.floor((tileW - #s)/2)
- local x = startX + (j-1)*(tileW+gap)
- local y = startY + (i-1)*(tileH+gap)
- -- Draw shadow (only for CraftOS 1.8+)
- if isVanilla or isCC_Tweaked then
- local shadowColor = tileShadowColors[bg] or colors.gray
- for dy=0,tileH-1 do
- for dx=0,tileW-1 do
- local sx, sy = x+dx+1, y+dy+1
- if sx>=1 and sx<=w and sy>=1 and sy<=h then
- buf[sy][sx].bg = shadowColor
- buf[sy][sx].fg = shadowColor
- buf[sy][sx].ch = " "
- end
- end
- end
- end
- -- Draw tile
- for dy=0,tileH-1 do
- for dx=0,tileW-1 do
- local tx, ty = x+dx, y+dy
- if tx>=1 and tx<=w and ty>=1 and ty<=h then
- buf[ty][tx].bg = bg
- buf[ty][tx].fg = fg
- buf[ty][tx].ch = " "
- end
- end
- end
- -- Draw value centered on tile
- if val ~= 0 then
- local tx = x + pad
- local ty = y + math.floor(tileH/2)
- for k=1,#s do
- if tx+k-1>=1 and tx+k-1<=w and ty>=1 and ty<=h then
- buf[ty][tx+k-1].ch = s:sub(k,k)
- buf[ty][tx+k-1].fg = fg
- buf[ty][tx+k-1].bg = bg
- end
- end
- end
- end
- end
- end
- local function drawUIToBuffer(buf, fps)
- local scoreStr = ("Score: %d"):format(score)
- for i=1,#scoreStr do
- buf[2][i+1].bg = colors.black
- buf[2][i+1].fg = isColor and colors.yellow or colors.white
- buf[2][i+1].ch = scoreStr:sub(i,i)
- end
- local fpsStr = ("FPS: %d"):format(fps)
- for i=1,#fpsStr do
- buf[3][i+1].bg = colors.black
- buf[3][i+1].fg = isColor and colors.lime or colors.white
- buf[3][i+1].ch = fpsStr:sub(i,i)
- end
- end
- local function drawGameOverToBuffer(buf)
- local msg = "Game Over! R to restart, Q to quit."
- for i=1,#msg do
- buf[5][i+1].bg = colors.black
- buf[5][i+1].fg = isColor and colors.red or colors.white
- buf[5][i+1].ch = msg:sub(i,i)
- end
- end
- local function pollInput(timeout)
- local timer = os.startTimer(timeout)
- while true do
- local e, p = os.pullEvent()
- if e == "key" then
- if p == keys.up then return "up"
- elseif p == keys.down then return "down"
- elseif p == keys.left then return "left"
- elseif p == keys.right then return "right"
- elseif p == keys.r then return "restart"
- elseif p == keys.q then return "quit"
- end
- elseif e == "timer" and p == timer then
- return nil
- end
- end
- end
- local function mainGameLoop()
- local t = 0
- local frames = 0
- local fps = 0
- local lastFpsTime = os.clock()
- local gameOver = false
- local startY = math.floor((h - gridSize*2) / 2)
- initGrid()
- spawnTile()
- spawnTile()
- while true do
- local frameStart = os.clock()
- local buf = newBuffer()
- drawPlasmaToBuffer(buf, t)
- drawGridToBuffer(buf)
- updateParticles()
- drawParticles(buf)
- drawLogo(buf, t)
- drawUIToBuffer(buf, fps)
- if gameOver then drawGameOverToBuffer(buf) end
- blitToTerm(buf)
- t = t + 0.15
- if gameOver then
- local action = pollInput(0.1)
- if action == "restart" then
- initGrid()
- score = 0
- spawnTile()
- spawnTile()
- t = 0
- gameOver = false
- seenDoubles = {}
- particles = {}
- elseif action == "quit" then
- stopMusic()
- term.setCursorPos(1, 1)
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1, 1)
- return
- end
- else
- local action = pollInput(0.1)
- local moved, merged, mergedValues = false, false, nil
- if action == "up" or action == "down" or action == "left" or action == "right" then
- moved, merged, mergedValues = move(action)
- if moved then
- spawnTile()
- if merged and mergedValues then
- for _, v in ipairs(mergedValues) do
- if not seenDoubles[v] then
- seenDoubles[v] = true
- currentPlasma = currentPlasma % (isColor and 4 or 3) + 1
- break
- end
- end
- local x = (mergedTj-1)*4 + math.floor((w - gridSize*4 - (gridSize-1)*1)/2) + 3
- local y = (mergedTi-1)*2 + math.max(1, math.floor((h - gridSize*2 - (gridSize-1)*1)/2) - 2) + 1
- spawnParticles(x, y, 10)
- if canPlaySound then playMergeSound(mergedValues[1]) end
- end
- if not canMove() then
- gameOver = true
- end
- end
- elseif action == "restart" then
- initGrid()
- score = 0
- spawnTile()
- spawnTile()
- t = 0
- gameOver = false
- seenDoubles = {}
- particles = {}
- elseif action == "quit" then
- stopMusic()
- term.setCursorPos(1, 1)
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1, 1)
- return
- end
- end
- frames = frames + 1
- local now = os.clock()
- if now - lastFpsTime >= 1 then
- fps = frames
- frames = 0
- lastFpsTime = now
- end
- local frameTime = os.clock() - frameStart
- if frameTime < 0.05 then
- os.sleep(0.05 - frameTime)
- end
- end
- end
- math.randomseed(os.time())
- titleScreen()
- if isCC_Tweaked and canPlayMusic and fs.exists(GAME_FILE) then
- parallel.waitForAll(
- function() startMusic(GAME_FILE, 32000) end,
- mainGameLoop
- )
- stopMusic()
- else
- mainGameLoop()
- end
Add Comment
Please, Sign In to add comment