local scr_x, scr_y = term.getSize() local modemID = 712 local gamename = "" waitingForGame = true local grid = { x1 = -80, y1 = -80, x2 = 80, y2 = 80, border = "#", voidcol = "f", forecol = "8", backcol = "7", edgecol = "0" } local scrollX = 0 local scrollY = 0 local scrollAdjX = 0 local scrollAdjY = 0 local lockInput = false local player local resetPlayers = function() player = { [1] = { x = -2, y = -5, direction = -1, char = "@", color = { colors.blue, colors.blue, colors.blue, colors.cyan, colors.cyan, colors.lightBlue, colors.lightBlue, colors.cyan, colors.cyan }, dead = false, putTrail = true }, [2] = { x = 2, y = -5, direction = -1, char = "@", color = { colors.red, colors.red, colors.red, colors.orange, colors.orange, colors.yellow, colors.yellow, colors.orange, colors.orange }, dead = false, putTrail = true } } end resetPlayers() local trail = {} local putTrail = function(p) trail[p.y] = trail[p.y] or {} trail[p.y][p.x] = { player = p, age = 0 } end local getTrail = function(x, y) if trail[y] then if trail[y][x] then if doAge then trail[y][x].age = trail[y][x].age + 1 end return trail[y][x].player.char, trail[y][x].player.color, trail[y][x].age end end return false end local ageTrails = function() for y,l in pairs(trail) do for x,v in pairs(l) do trail[y][x].age = trail[y][x].age + 1 end end end local toblit = { [0] = " ", [colors.white] = "0", [colors.orange] = "1", [colors.magenta] = "2", [colors.lightBlue] = "3", [colors.yellow] = "4", [colors.lime] = "5", [colors.pink] = "6", [colors.gray] = "7", [colors.lightGray] = "8", [colors.cyan] = "9", [colors.purple] = "a", [colors.blue] = "b", [colors.brown] = "c", [colors.green] = "d", [colors.red] = "e", [colors.black] = "f" } local you = 1 local nou = 2 local control = { up = keys.up, down = keys.down, left = keys.left, right = keys.right, lookUp = keys.w, lookDown = keys.s, lookLeft = keys.a, lookRight = keys.d, release = keys.space } -- keeps track of where you are local gamemode = "" -- foreground grid local gridFore = { "+-------", "| ", "| ", "| ", "| " } -- background grid local gridBack = { "+------------", "| ", "| ", "| ", "| ", "| ", "| ", "| " } local dirArrow = { [-1] = "^", [0] = ">", [1] = "V", [2] = "<" } local doesIntersectBorder = function(x, y) return x == grid.x1 or x == grid.x2 or y == grid.y1 or y == grid.y2 end --draws grid and background at scroll 'x' and 'y' local drawGrid = function(x, y) x, y = math.floor(x + 0.5), math.floor(y + 0.5) local bg = {{},{},{}} local foreX, foreY local backX, backY local adjX, adjY local trailChar, trailColor, trailAge, isPlayer for sy = 1, scr_y do bg[1][sy] = "" bg[2][sy] = "" bg[3][sy] = "" for sx = 1, scr_x do adjX = (sx + x) adjY = (sy + y) foreX = 1 + (sx + x) % #gridFore[1] foreY = 1 + (sy + y) % #gridFore backX = 1 + math.floor(sx + (x / 2)) % #gridBack[1] backY = 1 + math.floor(sy + (y / 2)) % #gridBack trailChar, trailColor, trailAge = getTrail(adjX, adjY) isPlayer = false for i = 1, #player do if player[i].x == adjX and player[i].y == adjY then isPlayer = i break end end if isPlayer and not (doesIntersectBorder(adjX, adjY)) then bg[1][sy] = bg[1][sy] .. dirArrow[player[isPlayer].direction] bg[2][sy] = bg[2][sy] .. toblit[player[isPlayer].color[1]] bg[3][sy] = bg[3][sy] .. grid.voidcol else if trailChar and trailColor then trailColor = trailColor[1 + ((trailAge - 1) % #trailColor)] bg[1][sy] = bg[1][sy] .. trailChar bg[2][sy] = bg[2][sy] .. toblit[trailColor] bg[3][sy] = bg[3][sy] .. grid.voidcol else if adjX < grid.x1 or adjX > grid.x2 or adjY < grid.y1 or adjY > grid.y2 then bg[1][sy] = bg[1][sy] .. " " bg[2][sy] = bg[2][sy] .. grid.voidcol bg[3][sy] = bg[3][sy] .. grid.voidcol elseif doesIntersectBorder(adjX, adjY) then bg[1][sy] = bg[1][sy] .. grid.border bg[2][sy] = bg[2][sy] .. grid.voidcol bg[3][sy] = bg[3][sy] .. grid.edgecol else if gridFore[foreY]:sub(foreX,foreX) ~= " " then bg[1][sy] = bg[1][sy] .. gridFore[foreY]:sub(foreX,foreX) bg[2][sy] = bg[2][sy] .. grid.forecol bg[3][sy] = bg[3][sy] .. grid.voidcol elseif gridBack[backY]:sub(backX,backX) ~= " " then bg[1][sy] = bg[1][sy] .. gridBack[backY]:sub(backX,backX) bg[2][sy] = bg[2][sy] .. grid.backcol bg[3][sy] = bg[3][sy] .. grid.voidcol else bg[1][sy] = bg[1][sy] .. " " bg[2][sy] = bg[2][sy] .. grid.voidcol bg[3][sy] = bg[3][sy] .. grid.voidcol end end end end end end for sy = 1, scr_y do term.setCursorPos(1,sy) term.blit(bg[1][sy], bg[2][sy], bg[3][sy]) end end local render = function() local p = player[you] drawGrid(scrollX + scrollAdjX, scrollY + scrollAdjY) end local deepCopy deepCopy = function(tbl, ...) local output = {} for k,v in pairs(tbl) do if type(v) == "table" then output[k] = deepCopy(v) else output[k] = v end end for i = 1, #arg do output[#output+1] = arg[i] end return output end local makeMenu = function(x, y, options) local cpos = 1 local cursor = "> " local render = function() for i = 1, #options do term.setCursorPos(x, y + (i - 1)) if i == cpos then term.setTextColor(colors.white) term.write(cursor .. options[i]) else term.setTextColor(colors.gray) term.write((" "):rep(#cursor) .. options[i]) end end end local evt while true do render() evt = {os.pullEvent()} if evt[1] == "key" then if evt[2] == keys.up then cpos = math.max(cpos - 1, 1) elseif evt[2] == keys.down then cpos = math.min(cpos + 1, #options) elseif evt[2] == keys.enter then return cpos end end end end local titleScreen = function() local logo = { { " •ƒƒƒƒƒƒƒƒƒ•—ƒƒƒƒƒƒƒ‹‹ ‡‡ƒƒƒ‹‹ Ÿ‹ •ƒƒ•", " •ƒƒƒ”€—ƒƒƒ•‚ƒƒƒƒƒ‹€€€Š —€Ÿƒƒƒ€” •‚‚ •€€•", " •€• ‚‚ƒƒ•€€—€€€”€€••€€‹‹ •€€•", " •€• —ƒ”‹“ƒƒ‹€€€•€€•€€€•€€••€•ˆƒ€€•", " •€• •€• ‚‹€€‹€Š€‹‡€Ÿ…•€• ‚‚€•", " •€• •€• ‹€‚‹ ‹‹€€€Ÿ‡‡ •€• ‹‹•", "   Š ‚‹‡  ‚…", }, { " f7777777777777777777f f77777f 7f f777", " f99979999979999999999f 799999799 77f7 f997", " 799 79999f997ffff9977997f f997", " 799 7797777fffff997ffff9977997797997", " 799 799 799977f7797fff7997799 79797", " 799 799 7797f 797999997 799 797", " 777 777 7777 7777777 777 77", }, { " 7999999999f9999999997 7999997 97 799f", " 7777997777f77777779997 997777997 997f 799f", " 997 f7777799ffff799f99997 799f", " 997 997f9997fff799ffff799f997ff7999f", " 997 997 f7999fff999777997f997 f799f", " 997 997 f9997 f7999977f 997 f7f", " fff fff ffff fffffff fff ff", } } local drawLogo = function(x, y, darkmod) local cx, cy = term.getCursorPos() for iy = 1, #logo[1] do term.setCursorPos(x,y+(iy-1)) term.blit(logo[1][iy], logo[2][iy], logo[3][iy]) end term.setCursorPos(cx,cy) end term.clear() drawLogo(3,3) local choice = makeMenu(2, scr_y - 4, { "Start Game", "Grid Demo", "Exit" }) if choice == 1 then return "start" elseif choice == 2 then return "demo" elseif choice == 3 then return "exit" end end local cleanExit = function() term.setBackgroundColor(colors.black) term.setTextColor(colors.white) term.clear() term.setCursorPos(1,1) print("Buh-bye.") end -- test background drawing local evt local keysDown = {} local getInput = function() os.pullEvent("new_game") while true do evt = {os.pullEvent()} if lockInput then keysDown = {} else if evt[1] == "key" then keysDown[evt[2]] = true elseif evt[1] == "key_up" then keysDown[evt[2]] = false end end end end scrollToPosition = function(x, y) for i = 1, 16 do scrollX = (scrollX + x - (scr_x/2)) / 2 scrollY = (scrollY + y - (scr_y/2)) / 2 render() sleep(0.05) end end local gridDemo = function() keysDown = {} while true do if keysDown[keys.left] then scrollX = scrollX - 1 end if keysDown[keys.right] then scrollX = scrollX + 1 end if keysDown[keys.up] then scrollY = scrollY - 1 end if keysDown[keys.down] then scrollY = scrollY + 1 end if keysDown[keys.q] then return "end" end drawGrid(scrollX, scrollY) ageTrails() sleep(0.05) end end local moveTick = function() local p local deadGuys = {} for i = 1, #player do p = player[i] if not p.dead then p.x = p.x + math.floor(math.cos(math.rad(p.direction * 90))) p.y = p.y + math.floor(math.sin(math.rad(p.direction * 90))) if getTrail(p.x, p.y) or (p.x == grid.x1 or p.x == grid.x2 or p.y == grid.y1 or p.y == grid.y2) then p.dead = true deadGuys[i] = true p.char = "X" lockInput = true else if p.putTrail then putTrail(p) end end end end if deadGuys[you] or deadGuys[nou] then term.setTextColor(colors.white) if deadGuys[you] and deadGuys[nou] then scrollToPosition(player[nou].x, player[nou].y) scrollToPosition(player[you].x, player[you].y) term.setCursorPos(1,scr_y) term.write("It's a tie!") sleep(1.5) return "end" else if deadGuys[you] then sleep(0.5) term.setCursorPos(1,scr_y) term.write("You're loser.") sleep(1.5) return "end" elseif deadGuys[nou] then scrollToPosition(player[nou].x, player[nou].y) term.setCursorPos(1,scr_y) term.write("You're winner!") sleep(1.5) return "end" end end end ageTrails() end if ccemux and not peripheral.find("modem") then ccemux.attach("top","wireless_modem") end local modem = peripheral.find("modem") if modem then modem.open(modemID) else error("You need a modem.") end local sendInfo = function(gameID) modem.transmit(modemID, modemID, { player = player, gameID = gameID }) end local game = function() local p = player[you] local outcome os.pullEvent("new_game") while true do p.putTrail = not keysDown[control.release] if keysDown[control.left] and p.direction ~= 0 then p.direction = 2 elseif keysDown[control.right] and p.direction ~= 2 then p.direction = 0 end if keysDown[control.up] and p.direction ~= 1 then p.direction = -1 elseif keysDown[control.down] and p.direction ~= -1 then p.direction = 1 end if keysDown[control.lookLeft] then scrollAdjX = scrollAdjX - 2 end if keysDown[control.lookRight] then scrollAdjX = scrollAdjX + 2 end if keysDown[control.lookUp] then scrollAdjY = scrollAdjY - 1.5 end if keysDown[control.lookDown] then scrollAdjY = scrollAdjY + 1.5 end scrollAdjX = scrollAdjX * 0.8 scrollAdjY = scrollAdjY * 0.8 outcome = moveTick() sendInfo(gameID) if outcome == "end" then return else scrollX = p.x - math.floor(scr_x / 2) scrollY = p.y - math.floor(scr_y / 2) render() sleep(0.05) end end end local decision local networking = function() local evt, side, channel, repchannel, msg, distance while true do evt, side, channel, repchannel, msg, distance = os.pullEvent("modem_message") if channel == modemID and repchannel == modemID and type(msg) == "table" then if type(msg.player) == "table" and type(msg.gameID) == "string" then if waitingForGame and (type(msg.new) == "number") then if msg.new < os.time() then you, nou = you, nou gamename = msg.gameID end waitingForGame = false os.queueEvent("new_game", gameID) end end end end end while true do decision = titleScreen() lockInput = false if decision == "start" then trail = {} resetPlayers() gamename = "" for i = 1, 32 do gamename = gamename .. string.char(math.random(1,126)) end modem.transmit(modemID, modemID, { player = player, gameID = gamename, new = os.time() }) parallel.waitForAny(getInput, game, networking) elseif decision == "demo" then parallel.waitForAny(getInput, gridDemo) elseif decision == "exit" then return cleanExit() end end