Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local map = {} --not a path, rather a paint file turned into a table
- local mapname = "map" --THIS is a path
- local mapX, mapY --X and Y sizes of map
- local mappaint = nil --the 'paintutils.loadImage()' of the map
- xscroll = 0 --changes the view X (higher moves everything left)
- yscroll = 0 --changes the view Y (higher moves everything down)
- Xmaxspeed = 4
- Ymaxspeed = 4
- gravity = 1
- local controls = {
- ["up"] = keys.up,
- ["down"] = keys.down,
- ["left"] = keys.left,
- ["right"] = keys.right,
- ["jump"] = keys.x,
- ["action"] = keys.z,
- }
- log = {} --debug log
- logadd = function(data)
- local time = os.clock()
- log[#log+1] = "["..time.."] "..tostring(data or "Nil")
- end
- local keysDown = {}
- local miceDown = {}
- getInput = function() --makes key/mouse input better
- local evt
- while true do
- evt = {os.pullEvent()}
- if evt[1] == "mouse_click" or evt[1] == "mouse_drag" then
- miceDown[evt[2]] = {x = evt[3],y = evt[4]}
- elseif evt[1] == "mouse_up" then
- miceDown[evt[2]] = nil
- end
- if evt[1] == "key" then
- keysDown[evt[2]] = true
- elseif evt[1] == "key_up" then
- keysDown[evt[2]] = false
- end
- end
- end
- setNewMap = function(name)
- local oldname = mapname
- if fs.exists(name) then
- mappaint = paintutils.loadImage(name)
- local file = fs.open(name,"r")
- local line = ""
- mapX = 0
- mapY = 0
- map = {}
- repeat
- line = file.readLine()
- if line then
- mapY = mapY + 1
- mapX = (#line > mapX) and #line or mapX
- map[#map+1] = line
- end
- until not line
- file.close()
- logadd("changed map to '"..name.."' from '"..oldname.."' (X:"..mapX.."/Y:"..mapY..")")
- else
- logadd("tried to change map to nonexistant '"..name.."'")
- end
- end
- makeNewPlayer = function(name,x,y,txt,bg,char,direction)
- local player = {
- name = name or "Player",
- x = x or 0, --x position relative to map
- y = y or 0, --x position relative to map
- xv = 0, --x velocity, higher is more rightwards
- yv = 0, --y velocity, higher is more downwards
- txt = txt or colors.white,
- bg = bg or colors.gray,
- char = char or "o",
- direction = direction or 1, -- 1 is right, -1 is left
- grounded = false,
- stat = { --in case I use them
- hp = 100, --Hit Points
- mp = 30, --Magic Points
- str = 5, --Attack Strength
- def = 4, --Defence
- }
- }
- logadd("defined new player '"..name.."'")
- return player
- end
- players = {
- [1] = makeNewPlayer("P1",6,5,colors.lime,colors.green,"o",1),
- [2] = makeNewPlayer("P@",8,5,colors.yellow,colors.orange,"o",-1),
- }
- local youPlayer = 1 --you is player 1
- local isOnscreen = function(x,y,scx,scy)
- local sx,sy = term.getSize()
- sx,sy = scx or sx, scy or sy
- x,y = math.floor(x),math.floor(y)
- if (x < 1) or (x > sx) then return false end
- if (y < 1) or (y > sy) then return false end
- return true
- end
- getMapBit = function(x,y)
- if y > #map then
- return true, "#"
- elseif (x < 1) or (x > mapX) then
- return true, "#"
- else
- local bit = string.sub(map[y] or "#",x,x) or " "
- if bit:gsub(" ","") == "" then
- return false, bit
- else
- return true, bit
- end
- end
- end
- checkDistance = function(player,direction,distance)
- --direction: 0 is down, 1 is left, 2 is up, 3 is right
- --this function checks to see if you can freely move a certain amount of steps without hitting the map, and then returns the max distance you can go
- local x,y = player.x,player.y
- local endMultiply = 1 --1 if not inverting, -1 if it is
- distance = math.floor(distance)
- if distance == 0 then
- return true, 0
- end
- if distance < 0 then
- distance = math.abs(distance)
- direction = direction + 2
- endMultiply = -1
- end
- direction = (math.rad((math.floor(direction) % 4) * 90))
- for a = 1, distance do
- if getMapBit(x+(math.sin(direction)*a), y+(math.cos(direction)*a)) then
- return false, (a-1)*endMultiply
- end
- end
- if getMapBit(x+(math.sin(direction)*distance), y+(math.cos(direction)*distance)) then
- return false, (distance-1)*endMultiply
- else
- return true, distance*endMultiply
- end
- end
- doPhysics = function()
- for k,v in pairs(players) do
- if math.abs(v.xv) > Xmaxspeed then
- if v.xv > 0 then
- players[k].xv = Xmaxspeed
- else
- players[k].xv = -Xmaxspeed
- end
- end
- if math.abs(v.yv) > Ymaxspeed then
- if v.yv > 0 then
- players[k].yv = Ymaxspeed
- else
- players[k].yv = -Ymaxspeed
- end
- end
- --do Y map collision
- players[k].yv = v.yv + gravity
- local isClear, dist = checkDistance(v,0,v.yv)
- players[k].y = v.y + dist
- if not isClear then
- players[k].yv = 0
- end
- --do X map collision
- local isClear, dist = checkDistance(v,3,v.xv)
- players[k].x = v.x + dist
- if not isClear then
- players[k].xv = 0
- end
- players[k].grounded = not checkDistance(v,1,0)
- end
- end
- render = function()
- local cTXT,cBG = term.getTextColor(),term.getBackgroundColor()
- term.setBackgroundColor(colors.black)
- term.clear()
- paintutils.drawImage(mappaint,xscroll or 0,yscroll or 0)
- local dx,dy --drawnX, drawnY
- for k,v in pairs(players) do
- dx = v.x-xscroll
- dy = v.y-yscroll
- if isOnscreen(dx,dy) then
- term.setCursorPos(dx,dy)
- term.setTextColor(v.txt)
- term.setBackgroundColor(v.bg)
- term.write(v.char)
- end
- end
- term.setTextColor(cTXT)
- term.setBackgroundColor(cBG)
- end
- mapPrompt = function()
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- print("Select map:")
- local doopmap = read()
- setNewMap(doopmap)
- end
- doEverything = function()
- while true do
- if keysDown[controls.right] then
- players[youPlayer].xv = players[youPlayer].xv + 1
- elseif keysDown[controls.left] then
- players[youPlayer].xv = players[youPlayer].xv - 1
- else
- if players[youPlayer].xv > 0 then
- players[youPlayer].xv = players[youPlayer].xv - 1
- else
- players[youPlayer].xv = players[youPlayer].xv + 1
- end
- end
- if keysDown[controls.jump] and players[youPlayer].grounded then
- players[youPlayer].yv = -4
- end
- doPhysics()
- sleep(0) --yes I fucking know that sleep(0.05) is the same as sleep(0) stop fucking telling me for christs sake
- end
- end
- alwaysRender = function()
- while true do
- render()
- sleep(0)
- end
- end
- while true do
- mapPrompt()
- parallel.waitForAny(doEverything,getInput,alwaysRender)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement