2018-11-14 21:26:04 +00:00
|
|
|
|
--[[
|
|
|
|
|
TRON Light Cycle Game
|
|
|
|
|
programmed by LDDestroier
|
|
|
|
|
|
|
|
|
|
wget https://raw.githubusercontent.com/LDDestroier/CC/master/tron
|
|
|
|
|
--]]
|
|
|
|
|
|
2018-11-14 17:01:01 +00:00
|
|
|
|
local port = 701
|
|
|
|
|
|
2018-11-13 20:02:55 +00:00
|
|
|
|
local scr_x, scr_y = term.getSize()
|
2018-11-14 17:01:01 +00:00
|
|
|
|
local modem = peripheral.find("modem")
|
|
|
|
|
if (not modem) and ccemux then
|
|
|
|
|
ccemux.attach("top", "wireless_modem")
|
|
|
|
|
modem = peripheral.find("modem")
|
|
|
|
|
end
|
2018-11-14 04:01:14 +00:00
|
|
|
|
|
2018-11-14 17:01:01 +00:00
|
|
|
|
if modem then
|
|
|
|
|
modem.open(port)
|
|
|
|
|
else
|
2018-11-14 20:55:50 +00:00
|
|
|
|
error("You should attach a modem.")
|
2018-11-14 17:01:01 +00:00
|
|
|
|
end
|
2018-11-13 20:02:55 +00:00
|
|
|
|
|
2018-11-14 20:55:50 +00:00
|
|
|
|
local gamename = ""
|
|
|
|
|
local isHost
|
2018-11-14 22:27:21 +00:00
|
|
|
|
local squareGrid = true
|
2018-11-14 20:55:50 +00:00
|
|
|
|
|
|
|
|
|
local waitingForGame = true
|
|
|
|
|
|
2018-11-14 21:37:31 +00:00
|
|
|
|
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
|
|
|
|
|
|
2018-11-14 22:27:21 +00:00
|
|
|
|
local initGrid = {
|
|
|
|
|
x1 = -100,
|
|
|
|
|
y1 = -100,
|
|
|
|
|
x2 = 100,
|
|
|
|
|
y2 = 100,
|
2018-11-13 20:06:05 +00:00
|
|
|
|
border = "#",
|
2018-11-13 20:02:55 +00:00
|
|
|
|
voidcol = "f",
|
|
|
|
|
forecol = "8",
|
|
|
|
|
backcol = "7",
|
|
|
|
|
edgecol = "0"
|
|
|
|
|
}
|
2018-11-14 22:27:21 +00:00
|
|
|
|
grid = deepCopy(initGrid)
|
2018-11-13 20:02:55 +00:00
|
|
|
|
|
2018-11-14 20:55:50 +00:00
|
|
|
|
local you = 1
|
|
|
|
|
local nou = 2
|
|
|
|
|
|
|
|
|
|
local keysDown = {}
|
|
|
|
|
local netKeysDown = {}
|
|
|
|
|
|
2018-11-14 21:09:32 +00:00
|
|
|
|
-- the scrolling of the screen
|
2018-11-13 20:02:55 +00:00
|
|
|
|
local scrollX = 0
|
|
|
|
|
local scrollY = 0
|
|
|
|
|
|
2018-11-14 21:09:32 +00:00
|
|
|
|
-- used when panning with WASD
|
2018-11-14 01:09:15 +00:00
|
|
|
|
local scrollAdjX = 0
|
|
|
|
|
local scrollAdjY = 0
|
|
|
|
|
|
|
|
|
|
local lockInput = false
|
2018-11-14 21:37:31 +00:00
|
|
|
|
local gameDelayInit = 0.05
|
2018-11-14 01:09:15 +00:00
|
|
|
|
local player
|
|
|
|
|
|
|
|
|
|
local resetPlayers = function()
|
|
|
|
|
player = {
|
|
|
|
|
[1] = {
|
2018-11-14 01:34:28 +00:00
|
|
|
|
x = -2,
|
2018-11-14 01:09:15 +00:00
|
|
|
|
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] = {
|
2018-11-14 01:34:28 +00:00
|
|
|
|
x = 2,
|
2018-11-14 01:09:15 +00:00
|
|
|
|
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
|
2018-11-14 20:55:50 +00:00
|
|
|
|
|
2018-11-14 01:09:15 +00:00
|
|
|
|
resetPlayers()
|
|
|
|
|
|
2018-11-14 20:55:50 +00:00
|
|
|
|
local images = {
|
|
|
|
|
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",
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
win = {
|
|
|
|
|
{
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"
",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"fffffffffffffffffffffffffffffff",
|
|
|
|
|
"f55ffffff55f555555f5ffffff5f55f",
|
|
|
|
|
"f55ffffff5555f55f5f55f5fff5f55f",
|
|
|
|
|
"f55fff5ff55fff55fff5555fff5f55f",
|
|
|
|
|
"f55ff55ff55fff55fff55f5fff5f55f",
|
|
|
|
|
"f5f55f5ff55f5f55fff55fff555ff5f",
|
|
|
|
|
"f555ffff555f555555f55fffff5f55f",
|
|
|
|
|
"fffffffffffffffffffffffffffffff",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
" ",
|
|
|
|
|
" 5fffffff5f5555555f55ffff55f5ff",
|
|
|
|
|
" 5fffffff5ffff5ffff555fff55f5ff",
|
|
|
|
|
" 5fff5fff5ffff5ffff5ff55f55f5ff",
|
|
|
|
|
" 5f55f55f5ffff5ffff5fff5555f5ff",
|
|
|
|
|
" 555fff555f5ff5ff5f5fffff55f5ff",
|
|
|
|
|
" 5fffffff5f5555555f5fffff55f5ff",
|
|
|
|
|
" ",
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
lose = {
|
|
|
|
|
{
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"
",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"fffffffffffffffffffffffffffffffff",
|
|
|
|
|
"feeffffffffeeefeffeeeeeffeeeeeeef",
|
|
|
|
|
"feeffffffeeefefefeefffeefeefffeef",
|
|
|
|
|
"feeffffffeeffffefeeffffffeffffeff",
|
|
|
|
|
"feeffffffeeffffefeeeeefefeeeeeeff",
|
|
|
|
|
"feeffffffefefffeffeffffefeeffffff",
|
|
|
|
|
"feeeeeeefefeeeeeffeeeeeefeeeeeeef",
|
|
|
|
|
"fffffffffffffffffffffffffffffffff",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
" ",
|
|
|
|
|
" efffffffeeeeeeffeeeeeeefeeeeeeef",
|
|
|
|
|
" efffffffeffffeefefffffffefffffff",
|
|
|
|
|
" efffffffeffffeefeeeeeeefeeeeefff",
|
|
|
|
|
" efffffffeffffeeffffffeefefffffff",
|
|
|
|
|
" efffffffeeffeeefeffffeefeffffeef",
|
|
|
|
|
" eeeeeeeffeeeefffeeeeeeffeeeeeeef",
|
|
|
|
|
" ",
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
tie = {
|
|
|
|
|
{
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"ffffffffffffffffffffffffff",
|
|
|
|
|
"f77888800f0000000f0888877f",
|
|
|
|
|
"ffff88fff00ff0ff0f08ffff7f",
|
|
|
|
|
"ffff88fffffff0ffff0ffff7ff",
|
|
|
|
|
"ffff88fffffff0ffff088887ff",
|
|
|
|
|
"ffff88ffff0ff0ffff08ffffff",
|
|
|
|
|
"ffff88ffff0000000f0888877f",
|
|
|
|
|
"ffffffffffffffffffffffffff",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
" ",
|
|
|
|
|
" 7788880f00000000f0888877f",
|
|
|
|
|
" 8fffffff00ffff0fffffff",
|
|
|
|
|
" 8fffffff00ffff08888fff",
|
|
|
|
|
" 8fffffff00ffff0fffffff",
|
|
|
|
|
" 8ffff0ff00ff0f0fffff7f",
|
|
|
|
|
" 8ffff00000000f0888877f",
|
|
|
|
|
" ",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for k,v in pairs(images) do
|
|
|
|
|
v.x = #v[1][1]
|
|
|
|
|
v.y = #v[1]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local drawImage = function(im, x, y)
|
|
|
|
|
local cx, cy = term.getCursorPos()
|
|
|
|
|
for iy = 1, #im[1] do
|
|
|
|
|
term.setCursorPos(x,y+(iy-1))
|
|
|
|
|
term.blit(im[1][iy], im[2][iy], im[3][iy])
|
|
|
|
|
end
|
|
|
|
|
term.setCursorPos(cx,cy)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local deadGuys = {}
|
2018-11-14 01:09:15 +00:00
|
|
|
|
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"
|
2018-11-13 20:02:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 21:35:25 +00:00
|
|
|
|
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 = ""
|
|
|
|
|
|
2018-11-13 20:39:29 +00:00
|
|
|
|
|
2018-11-14 22:27:21 +00:00
|
|
|
|
local gridFore, gridBack
|
|
|
|
|
if squareGrid then
|
|
|
|
|
gridFore = {
|
|
|
|
|
"+-------",
|
|
|
|
|
"| ",
|
|
|
|
|
"| ",
|
|
|
|
|
"| ",
|
|
|
|
|
"| "
|
|
|
|
|
}
|
|
|
|
|
gridBack = {
|
|
|
|
|
"+------------",
|
|
|
|
|
"| ",
|
|
|
|
|
"| ",
|
|
|
|
|
"| ",
|
|
|
|
|
"| ",
|
|
|
|
|
"| ",
|
|
|
|
|
"| ",
|
|
|
|
|
"| "
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
gridFore = {
|
|
|
|
|
" / ",
|
|
|
|
|
" / ",
|
|
|
|
|
" / ",
|
|
|
|
|
" / ",
|
|
|
|
|
"/__________"
|
|
|
|
|
}
|
|
|
|
|
gridBack = {
|
|
|
|
|
" / ",
|
|
|
|
|
" / ",
|
|
|
|
|
" / ",
|
|
|
|
|
" / ",
|
|
|
|
|
" / ",
|
|
|
|
|
" / ",
|
|
|
|
|
" / ",
|
|
|
|
|
"/_______________"
|
|
|
|
|
}
|
|
|
|
|
end
|
2018-11-13 20:17:08 +00:00
|
|
|
|
|
2018-11-14 01:09:15 +00:00
|
|
|
|
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
|
|
|
|
|
|
2018-11-13 20:02:55 +00:00
|
|
|
|
--draws grid and background at scroll 'x' and 'y'
|
|
|
|
|
local drawGrid = function(x, y)
|
2018-11-13 20:11:07 +00:00
|
|
|
|
x, y = math.floor(x + 0.5), math.floor(y + 0.5)
|
2018-11-13 20:02:55 +00:00
|
|
|
|
local bg = {{},{},{}}
|
|
|
|
|
local foreX, foreY
|
|
|
|
|
local backX, backY
|
|
|
|
|
local adjX, adjY
|
2018-11-14 01:09:15 +00:00
|
|
|
|
local trailChar, trailColor, trailAge, isPlayer
|
2018-11-13 20:02:55 +00:00
|
|
|
|
for sy = 1, scr_y do
|
|
|
|
|
bg[1][sy] = ""
|
|
|
|
|
bg[2][sy] = ""
|
|
|
|
|
bg[3][sy] = ""
|
|
|
|
|
for sx = 1, scr_x do
|
2018-11-14 01:09:15 +00:00
|
|
|
|
adjX = (sx + x)
|
|
|
|
|
adjY = (sy + y)
|
|
|
|
|
foreX = 1 + (sx + x) % #gridFore[1]
|
|
|
|
|
foreY = 1 + (sy + y) % #gridFore
|
2018-11-14 01:40:32 +00:00
|
|
|
|
backX = 1 + math.floor(sx + (x / 2)) % #gridBack[1]
|
|
|
|
|
backY = 1 + math.floor(sy + (y / 2)) % #gridBack
|
2018-11-14 01:09:15 +00:00
|
|
|
|
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]]
|
2018-11-13 20:39:29 +00:00
|
|
|
|
bg[3][sy] = bg[3][sy] .. grid.voidcol
|
2018-11-13 20:02:55 +00:00
|
|
|
|
else
|
2018-11-14 01:09:15 +00:00
|
|
|
|
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]
|
2018-11-13 20:02:55 +00:00
|
|
|
|
bg[3][sy] = bg[3][sy] .. grid.voidcol
|
|
|
|
|
else
|
2018-11-14 01:09:15 +00:00
|
|
|
|
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
|
2018-11-13 20:02:55 +00:00
|
|
|
|
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
|
|
|
|
|
|
2018-11-14 01:09:15 +00:00
|
|
|
|
local render = function()
|
|
|
|
|
local p = player[you]
|
|
|
|
|
drawGrid(scrollX + scrollAdjX, scrollY + scrollAdjY)
|
2018-11-14 20:55:50 +00:00
|
|
|
|
term.setCursorPos(1,1)
|
|
|
|
|
term.setTextColor(player[you].color[1])
|
|
|
|
|
term.write("P" .. you)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local pleaseWait = function()
|
|
|
|
|
local periods = 1
|
|
|
|
|
local maxPeriods = 5
|
|
|
|
|
term.setBackgroundColor(colors.black)
|
|
|
|
|
term.setTextColor(colors.gray)
|
|
|
|
|
term.clear()
|
|
|
|
|
|
|
|
|
|
local tID = os.startTimer(0.2)
|
|
|
|
|
local evt
|
|
|
|
|
local txt = "Waiting for game"
|
|
|
|
|
|
|
|
|
|
while true do
|
|
|
|
|
term.setCursorPos(math.floor(scr_x / 2 - (#txt + maxPeriods) / 2), scr_y - 2)
|
|
|
|
|
term.write(txt .. ("."):rep(periods))
|
|
|
|
|
evt = {os.pullEvent()}
|
|
|
|
|
if evt[1] == "timer" and evt[2] == tID then
|
|
|
|
|
tID = os.startTimer(0.5)
|
|
|
|
|
periods = (periods % maxPeriods) + 1
|
|
|
|
|
term.clearLine()
|
|
|
|
|
elseif evt[1] == "new_game" then
|
2018-11-15 00:28:01 +00:00
|
|
|
|
sleep(0.1)
|
2018-11-14 20:55:50 +00:00
|
|
|
|
return evt[2]
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-11-14 01:09:15 +00:00
|
|
|
|
end
|
|
|
|
|
|
2018-11-15 00:28:01 +00:00
|
|
|
|
local startCountdown = function()
|
|
|
|
|
local cName = "PLAYER " .. you
|
|
|
|
|
local col = colors.white
|
|
|
|
|
for k,v in pairs(colors) do
|
|
|
|
|
if player[you].color[1] == v then
|
|
|
|
|
cName = k:upper()
|
|
|
|
|
col = v
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
local cMessage = "You are "
|
2018-11-15 00:30:05 +00:00
|
|
|
|
for i = 3, 1, -1 do
|
2018-11-15 00:28:01 +00:00
|
|
|
|
render()
|
|
|
|
|
term.setCursorPos(math.floor(scr_x / 2 - (#cMessage + #cName) / 2), math.floor(scr_y / 2))
|
|
|
|
|
term.setTextColor(colors.white)
|
|
|
|
|
term.write(cMessage)
|
|
|
|
|
term.setTextColor(col)
|
|
|
|
|
term.write(cName)
|
|
|
|
|
term.setTextColor(colors.white)
|
|
|
|
|
term.setCursorPos(math.floor(scr_x / 2 - 2), math.floor(scr_y / 2) + 2)
|
|
|
|
|
term.write(i .. "...")
|
|
|
|
|
sleep(1)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-11-14 01:09:15 +00:00
|
|
|
|
local makeMenu = function(x, y, options)
|
2018-11-13 21:35:25 +00:00
|
|
|
|
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
|
2018-11-14 01:09:15 +00:00
|
|
|
|
local evt
|
|
|
|
|
while true do
|
|
|
|
|
render()
|
|
|
|
|
evt = {os.pullEvent()}
|
|
|
|
|
if evt[1] == "key" then
|
|
|
|
|
if evt[2] == keys.up then
|
2018-11-14 22:27:21 +00:00
|
|
|
|
cpos = (cpos - 2) % #options + 1
|
2018-11-14 01:09:15 +00:00
|
|
|
|
elseif evt[2] == keys.down then
|
2018-11-14 21:42:14 +00:00
|
|
|
|
cpos = (cpos % #options) + 1
|
2018-11-14 01:09:15 +00:00
|
|
|
|
elseif evt[2] == keys.enter then
|
|
|
|
|
return cpos
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-11-13 21:35:25 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local titleScreen = function()
|
|
|
|
|
term.clear()
|
2018-11-14 20:55:50 +00:00
|
|
|
|
drawImage(images.logo, 3,3)
|
2018-11-13 21:35:25 +00:00
|
|
|
|
|
2018-11-14 01:09:15 +00:00
|
|
|
|
local choice = makeMenu(2, scr_y - 4, {
|
|
|
|
|
"Start Game",
|
2018-11-14 21:26:04 +00:00
|
|
|
|
"How to Play",
|
2018-11-14 01:09:15 +00:00
|
|
|
|
"Grid Demo",
|
|
|
|
|
"Exit"
|
|
|
|
|
})
|
|
|
|
|
if choice == 1 then
|
|
|
|
|
return "start"
|
|
|
|
|
elseif choice == 2 then
|
2018-11-14 21:26:04 +00:00
|
|
|
|
return "help"
|
2018-11-14 01:09:15 +00:00
|
|
|
|
elseif choice == 3 then
|
2018-11-14 21:26:04 +00:00
|
|
|
|
return "demo"
|
|
|
|
|
elseif choice == 4 then
|
2018-11-14 01:09:15 +00:00
|
|
|
|
return "exit"
|
|
|
|
|
end
|
2018-11-13 21:35:25 +00:00
|
|
|
|
end
|
|
|
|
|
|
2018-11-14 01:09:15 +00:00
|
|
|
|
local cleanExit = function()
|
|
|
|
|
term.setBackgroundColor(colors.black)
|
|
|
|
|
term.setTextColor(colors.white)
|
|
|
|
|
term.clear()
|
|
|
|
|
term.setCursorPos(1,1)
|
2018-11-14 21:31:24 +00:00
|
|
|
|
print("Thanks for playing!")
|
2018-11-14 01:09:15 +00:00
|
|
|
|
end
|
2018-11-13 21:35:25 +00:00
|
|
|
|
|
2018-11-13 20:39:29 +00:00
|
|
|
|
local getInput = function()
|
2018-11-14 20:55:50 +00:00
|
|
|
|
local evt
|
2018-11-13 20:39:29 +00:00
|
|
|
|
while true do
|
|
|
|
|
evt = {os.pullEvent()}
|
2018-11-14 01:09:15 +00:00
|
|
|
|
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
|
2018-11-13 20:39:29 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-11-14 01:09:15 +00:00
|
|
|
|
|
2018-11-14 21:31:24 +00:00
|
|
|
|
local scrollToPosition = function(x, y)
|
2018-11-14 01:09:15 +00:00
|
|
|
|
for i = 1, 16 do
|
|
|
|
|
scrollX = (scrollX + x - (scr_x/2)) / 2
|
|
|
|
|
scrollY = (scrollY + y - (scr_y/2)) / 2
|
|
|
|
|
render()
|
2018-11-14 21:37:31 +00:00
|
|
|
|
sleep(0.05)
|
2018-11-14 01:09:15 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-11-13 20:39:29 +00:00
|
|
|
|
local gridDemo = function()
|
2018-11-14 01:40:32 +00:00
|
|
|
|
keysDown = {}
|
2018-11-13 20:39:29 +00:00
|
|
|
|
while true do
|
|
|
|
|
if keysDown[keys.left] then
|
2018-11-14 01:09:15 +00:00
|
|
|
|
scrollX = scrollX - 1
|
2018-11-13 20:39:29 +00:00
|
|
|
|
end
|
|
|
|
|
if keysDown[keys.right] then
|
2018-11-14 01:09:15 +00:00
|
|
|
|
scrollX = scrollX + 1
|
2018-11-13 20:39:29 +00:00
|
|
|
|
end
|
|
|
|
|
if keysDown[keys.up] then
|
2018-11-14 01:09:15 +00:00
|
|
|
|
scrollY = scrollY - 1
|
2018-11-13 20:39:29 +00:00
|
|
|
|
end
|
|
|
|
|
if keysDown[keys.down] then
|
2018-11-14 01:09:15 +00:00
|
|
|
|
scrollY = scrollY + 1
|
2018-11-13 20:39:29 +00:00
|
|
|
|
end
|
2018-11-14 01:34:28 +00:00
|
|
|
|
if keysDown[keys.q] then
|
|
|
|
|
return "end"
|
|
|
|
|
end
|
2018-11-13 20:39:29 +00:00
|
|
|
|
drawGrid(scrollX, scrollY)
|
2018-11-14 01:09:15 +00:00
|
|
|
|
ageTrails()
|
2018-11-14 21:31:24 +00:00
|
|
|
|
sleep(gameDelay)
|
2018-11-13 20:39:29 +00:00
|
|
|
|
end
|
2018-11-13 20:02:55 +00:00
|
|
|
|
end
|
2018-11-14 01:09:15 +00:00
|
|
|
|
|
2018-11-14 20:55:50 +00:00
|
|
|
|
local sendInfo = function(gameID)
|
|
|
|
|
modem.transmit(port, port, {
|
|
|
|
|
player = player,
|
|
|
|
|
gameID = gameID,
|
|
|
|
|
keysDown = keysDown,
|
|
|
|
|
trail = isHost and trail or nil,
|
2018-11-14 21:31:24 +00:00
|
|
|
|
deadGuys = isHost and deadGuys or {},
|
2018-11-14 20:55:50 +00:00
|
|
|
|
})
|
|
|
|
|
end
|
|
|
|
|
|
2018-11-14 21:09:32 +00:00
|
|
|
|
local waitForKey = function(time)
|
|
|
|
|
sleep(time or 0.1)
|
2018-11-14 21:26:59 +00:00
|
|
|
|
os.pullEvent("key")
|
2018-11-14 21:09:32 +00:00
|
|
|
|
end
|
|
|
|
|
|
2018-11-14 20:55:50 +00:00
|
|
|
|
local deadAnimation = function(doSend)
|
|
|
|
|
for k,v in pairs(deadGuys) do
|
|
|
|
|
player[k].char = "X"
|
|
|
|
|
lockInput = true
|
|
|
|
|
end
|
|
|
|
|
if doSend then
|
|
|
|
|
sendInfo(gamename)
|
2018-11-14 01:09:15 +00:00
|
|
|
|
end
|
2018-11-14 01:34:28 +00:00
|
|
|
|
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)
|
2018-11-14 20:55:50 +00:00
|
|
|
|
drawImage(images.tie, math.floor(scr_x / 2 - images.tie.x / 2), math.floor(scr_y / 2 - images.tie.y / 2))
|
2018-11-14 21:09:32 +00:00
|
|
|
|
waitForKey(1)
|
2018-11-14 01:34:28 +00:00
|
|
|
|
return "end"
|
|
|
|
|
else
|
|
|
|
|
if deadGuys[you] then
|
2018-11-14 20:55:50 +00:00
|
|
|
|
scrollX, scrollY = player[nou].x - scr_x / 2, player[nou].y - scr_y / 2
|
|
|
|
|
scrollToPosition(player[you].x, player[you].y)
|
|
|
|
|
drawImage(images.lose, math.floor(scr_x / 2 - images.lose.x / 2), math.floor(scr_y / 2 - images.lose.y / 2))
|
2018-11-14 21:09:32 +00:00
|
|
|
|
waitForKey(1)
|
2018-11-14 01:34:28 +00:00
|
|
|
|
return "end"
|
|
|
|
|
elseif deadGuys[nou] then
|
|
|
|
|
scrollToPosition(player[nou].x, player[nou].y)
|
2018-11-14 20:55:50 +00:00
|
|
|
|
drawImage(images.win, math.floor(scr_x / 2 - images.win.x / 2), math.floor(scr_y / 2 - images.win.y / 2))
|
2018-11-14 21:09:32 +00:00
|
|
|
|
waitForKey(1)
|
2018-11-14 01:34:28 +00:00
|
|
|
|
return "end"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-11-14 20:55:50 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local moveTick = function(doSend)
|
|
|
|
|
local p
|
|
|
|
|
for i = 1, #player do
|
|
|
|
|
p = player[i]
|
|
|
|
|
if not p.dead then
|
|
|
|
|
if isHost 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)))
|
|
|
|
|
end
|
|
|
|
|
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
|
|
|
|
|
elseif isHost then
|
|
|
|
|
if p.putTrail then
|
|
|
|
|
putTrail(p)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-11-14 01:09:15 +00:00
|
|
|
|
ageTrails()
|
2018-11-14 20:55:50 +00:00
|
|
|
|
return deadAnimation(doSend)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local setDirection = function(keylist, p)
|
|
|
|
|
p.putTrail = not keylist[control.release]
|
|
|
|
|
if keylist[control.left] and p.direction ~= 0 then
|
|
|
|
|
p.direction = 2
|
|
|
|
|
elseif keylist[control.right] and p.direction ~= 2 then
|
|
|
|
|
p.direction = 0
|
|
|
|
|
end
|
|
|
|
|
if keylist[control.up] and p.direction ~= 1 then
|
|
|
|
|
p.direction = -1
|
|
|
|
|
elseif keylist[control.down] and p.direction ~= -1 then
|
|
|
|
|
p.direction = 1
|
|
|
|
|
end
|
2018-11-14 01:09:15 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local game = function()
|
2018-11-14 17:01:01 +00:00
|
|
|
|
local outcome
|
2018-11-14 20:55:50 +00:00
|
|
|
|
local p, np
|
2018-11-14 01:09:15 +00:00
|
|
|
|
while true do
|
2018-11-14 20:55:50 +00:00
|
|
|
|
p = player[you]
|
|
|
|
|
np = player[nou]
|
|
|
|
|
|
|
|
|
|
setDirection(keysDown, p)
|
|
|
|
|
if isHost then
|
|
|
|
|
setDirection(netKeysDown, np)
|
2018-11-14 01:09:15 +00:00
|
|
|
|
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
|
2018-11-14 20:55:50 +00:00
|
|
|
|
|
2018-11-14 01:09:15 +00:00
|
|
|
|
scrollAdjX = scrollAdjX * 0.8
|
|
|
|
|
scrollAdjY = scrollAdjY * 0.8
|
2018-11-14 20:55:50 +00:00
|
|
|
|
|
|
|
|
|
if isHost then
|
|
|
|
|
outcome = moveTick(true)
|
|
|
|
|
else
|
|
|
|
|
outcome = deadAnimation(true)
|
|
|
|
|
end
|
2018-11-14 01:09:15 +00:00
|
|
|
|
|
|
|
|
|
if outcome == "end" then
|
|
|
|
|
return
|
|
|
|
|
else
|
|
|
|
|
scrollX = p.x - math.floor(scr_x / 2)
|
|
|
|
|
scrollY = p.y - math.floor(scr_y / 2)
|
|
|
|
|
|
|
|
|
|
render()
|
2018-11-14 21:31:24 +00:00
|
|
|
|
sleep(gameDelay)
|
2018-11-14 01:09:15 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local decision
|
2018-11-14 04:01:14 +00:00
|
|
|
|
|
2018-11-14 20:55:50 +00:00
|
|
|
|
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 == port and repchannel == port 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
|
|
|
|
|
gamename = msg.gameID
|
|
|
|
|
isHost = false
|
2018-11-14 21:37:31 +00:00
|
|
|
|
gameDelay = tonumber(msg.gameDelay) or 0.05
|
2018-11-14 22:27:21 +00:00
|
|
|
|
grid = msg.grid or deepCopy(initGrid)
|
2018-11-14 20:55:50 +00:00
|
|
|
|
else
|
|
|
|
|
you, nou = nou, you
|
|
|
|
|
isHost = true
|
|
|
|
|
end
|
|
|
|
|
you, nou = nou, you
|
|
|
|
|
modem.transmit(port, port, {
|
|
|
|
|
player = player,
|
|
|
|
|
gameID = gamename,
|
2018-11-14 22:27:21 +00:00
|
|
|
|
new = isHost and (-math.huge) or (math.huge),
|
|
|
|
|
grid = initGrid
|
2018-11-14 20:55:50 +00:00
|
|
|
|
})
|
|
|
|
|
waitingForGame = false
|
|
|
|
|
netKeysDown = {}
|
|
|
|
|
os.queueEvent("new_game", gameID)
|
2018-11-14 22:27:21 +00:00
|
|
|
|
|
2018-11-14 20:55:50 +00:00
|
|
|
|
elseif msg.gameID == gamename then
|
|
|
|
|
if not isHost then
|
|
|
|
|
player = msg.player
|
|
|
|
|
trail = msg.trail
|
|
|
|
|
deadGuys = msg.deadGuys
|
|
|
|
|
elseif type(msg.keysDown) == "table" then
|
|
|
|
|
netKeysDown = msg.keysDown
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-11-14 21:26:04 +00:00
|
|
|
|
helpScreen = function()
|
|
|
|
|
term.setBackgroundColor(colors.black)
|
|
|
|
|
term.setTextColor(colors.white)
|
|
|
|
|
term.clear()
|
|
|
|
|
term.setCursorPos(1,2)
|
|
|
|
|
print([[
|
|
|
|
|
Move with arrow keys.
|
|
|
|
|
Pan the camera with WASD.
|
|
|
|
|
Hold SPACE to create gaps.
|
|
|
|
|
|
|
|
|
|
That's basically it.
|
|
|
|
|
Press any key to go back.
|
|
|
|
|
]])
|
|
|
|
|
waitForKey(0.25)
|
|
|
|
|
end
|
|
|
|
|
|
2018-11-14 01:09:15 +00:00
|
|
|
|
while true do
|
|
|
|
|
decision = titleScreen()
|
|
|
|
|
lockInput = false
|
|
|
|
|
if decision == "start" then
|
|
|
|
|
trail = {}
|
2018-11-14 20:55:50 +00:00
|
|
|
|
deadGuys = {}
|
2018-11-14 21:37:31 +00:00
|
|
|
|
gameDelay = gameDelayInit
|
2018-11-14 22:27:21 +00:00
|
|
|
|
grid = deepCopy(initGrid)
|
2018-11-14 01:09:15 +00:00
|
|
|
|
resetPlayers()
|
2018-11-14 20:55:50 +00:00
|
|
|
|
you, nou = 1, 2
|
2018-11-15 00:33:17 +00:00
|
|
|
|
scrollX, scrollY = player[you].x - math.floor(scr_x / 2), player[you].x - math.floor(scr_y / 2)
|
2018-11-14 20:55:50 +00:00
|
|
|
|
gamename = ""
|
|
|
|
|
for i = 1, 32 do
|
|
|
|
|
gamename = gamename .. string.char(math.random(1,126))
|
|
|
|
|
end
|
|
|
|
|
waitingForGame = true
|
|
|
|
|
modem.transmit(port, port, {
|
|
|
|
|
player = player,
|
|
|
|
|
gameID = gamename,
|
2018-11-14 21:39:44 +00:00
|
|
|
|
new = os.time(),
|
|
|
|
|
gameDelay = gameDelayInit,
|
2018-11-14 22:27:21 +00:00
|
|
|
|
grid = initGrid
|
2018-11-14 20:55:50 +00:00
|
|
|
|
})
|
|
|
|
|
parallel.waitForAny(pleaseWait, networking)
|
2018-11-15 00:28:01 +00:00
|
|
|
|
startCountdown()
|
2018-11-14 20:55:50 +00:00
|
|
|
|
parallel.waitForAny(getInput, game, networking)
|
2018-11-14 21:26:04 +00:00
|
|
|
|
elseif decision == "help" then
|
|
|
|
|
helpScreen()
|
2018-11-14 01:09:15 +00:00
|
|
|
|
elseif decision == "demo" then
|
|
|
|
|
parallel.waitForAny(getInput, gridDemo)
|
|
|
|
|
elseif decision == "exit" then
|
|
|
|
|
return cleanExit()
|
|
|
|
|
end
|
2018-11-14 21:09:32 +00:00
|
|
|
|
end
|