Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- os.loadAPI("grid")
- -- map drawing offsets map draw starts at xoff and yoff and ends at
- -- "visplanew" (width) and "visplaneh" (height)
- local xoff = 0
- local yoff = 0
- -- how fast things in the game update
- local gameloop = os.startTimer(0.05)
- -- how many food items to spawn on first map load
- local dif = 10000
- -- creating the level grid
- local level = grid.create(1000, 1000)
- -- weather or not to use a screen buffer (faster) or not (slower)
- local usebuffer = true
- -- fill the level with empty tiles.
- level:fill("0")
- -- set the visplanes equal to the width and height of the screen
- local visplanew, visplaneh = term.getSize()
- -- a table to store all block related functions
- local blocks = {
- -- creates a food item with a random x, y and color
- newFood = function()
- local food = {}
- local x = math.ceil(math.random(1,1000))
- local y = math.ceil(math.random(1,1000))
- local color = math.ceil(math.random(1,15))
- -- colors can be converted easily from numbers like 1,15 by simply
- -- have 2 to the power of the number.
- color = 2^tonumber(color)
- food.color = color
- food.x = x
- food.y = y
- return food
- end,
- }
- function foodSpawn()
- for i = 1, dif do --how many we spawn at once
- local f = blocks.newFood()
- -- put the food item in the level at the
- -- random x and y of the returned food item
- level:set(f.x,f.y,f)
- end
- end
- -- The players table player[1] is client and all other players are the other people playing,
- -- with the client on the server.
- local players = {
- {name="player1",size=1,food=0,x=math.ceil(math.random(visplanew,1000-visplanew)),
- y=math.ceil(math.random(visplaneh,1000-visplaneh))},
- }
- --]] Player drawing methods [[--
- -- the draw x and y is equal to an equation used to display the player in the middle
- -- or close to the middle of the screen as the player grows in size
- -- clearing the player from the screen.
- local function undrawplayer()
- local px, py, ps = visplanew/2 - math.floor((players[1].size+1)/2)+2,
- ((visplaneh/2)-1) - math.floor((players[1].size)/2)+2,
- players[1].size
- paintutils.drawFilledBox(px-ps,py-ps,px+ps,py+ps,colors.white)
- -- drawplayerS
- end
- -- used for drawing the player
- local function drawplayer()
- term.current().setVisible(false)
- local px, py, ps = visplanew/2 - math.floor((players[1].size-2)/2)+2,
- ((visplaneh/2)-1) - math.floor((players[1].size)/4)+3,
- players[1].size
- term.setTextColor(colors.white)
- paintutils.drawFilledBox(px-ps,py-ps,px+ps,py+ps,colors.lightBlue)
- term.setCursorPos(px,py)
- write("P")
- term.current().setVisible(true)
- end
- -- The update function used to update players positions and client players movement
- -- also used to keep the view centered when the player grows
- local function update(ev)
- local x, y, size = players[1].x,players[1].y,players[1].size
- -- attempt to grow if we have enough food
- -- make sure the players grown size isnt bigger than the map
- -- if it is then recenter the player away from the edge of the map
- -- so that the player can grow.
- -- the reason we do this is because of the constant collision check
- -- reverencing the level map at the players coords plus players size.
- -- if we try to reference a point that doesnt exist the game crashes.
- if(players[1].food >= 10 * players[1].size)then
- while players[1].x+players[1].size+2 > level:getWidth() do
- players[1].x = players[1].x - 1
- end
- while players[1].y+players[1].size+2 > level:getHeight() do
- players[1].y = players[1].y - 1
- end
- players[1].size = players[1].size + 2
- drawplayer()
- centercam()
- end
- -- Movement and level edge check.
- if(ev[1] == "key")then
- if(ev[2] == keys.w and y-size > 1)then
- players[1].y = players[1].y - 1
- yoff = yoff - 1
- render()
- elseif(ev[2] == keys.s and y+size < level:getHeight())then
- players[1].y = players[1].y + 1
- yoff = yoff + 1
- render()
- elseif(ev[2] == keys.a and x-size > 1)then
- players[1].x = players[1].x - 1
- xoff = xoff - 1
- render()
- elseif(ev[2] == keys.d and x+size < level:getWidth())then
- players[1].x = players[1].x + 1
- xoff = xoff + 1
- render()
- -- developer keys
- elseif(ev[2] == keys.x)then
- run = false
- term.setCursorPos(1,1)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- return false
- end
- end
- checkfoodcollide(players[1].x,players[1].y,players[1].size)
- end
- -- setup the buffer on first run
- local buffer = grid.create(visplanew,visplaneh)
- buffer:fill("0")
- local bxoff = 0
- local byoff = 0
- -- renders blocks in the level
- function render()
- term.current().setVisible(false)
- if(usebuffer)then
- for by = 1, buffer:getHeight() do
- for bx = 1, buffer:getWidth() do
- term.setBackgroundColor(colors.white)
- if(buffer:get(bx,by) ~= "0")then
- -- if there is a item in the buffer
- -- draw over it to remove it from the screen.
- local bitem = buffer:get(bx,by)
- term.setCursorPos(bitem.x - bxoff,bitem.y -byoff)
- write(" ")
- end
- end
- end
- end
- -- loop through the blocks visible to the client
- for y = 1+yoff, visplaneh+yoff do
- for x = 1+xoff, visplanew+xoff do
- term.setBackgroundColor(colors.white)
- -- if theres a spot on the buffer that shouldnt have a block but does
- -- clear that spot.
- if(usebuffer and (level:get(x,y) == "0" or level:get(x,y) == nil) and buffer:get(x-xoff,y-yoff) ~= "0")then
- buffer:set(x-xoff,y-yoff,"0")
- end
- -- if the block we are at is not empty and has a color then draw it
- if(level:get(x,y) ~= "0" and level:get(x,y).color ~= nil)then
- --render code ...
- -- it doesnt see a correct background color
- local item = level:get(x,y)
- term.setBackgroundColor(item.color)
- term.setCursorPos(x-xoff,y-yoff)
- write(" ")
- term.setBackgroundColor(colors.white)
- -- add the drawn block to the buffer
- buffer:set(x-xoff,y-yoff,item)
- elseif(not usebuffer)then
- term.setBackgroundColor(colors.white)
- term.setCursorPos(x-xoff,y-yoff)
- write(" ")
- elseif(level:get(x,y) ~= "0" and level:get(x,y).color == nil)then
- -- if we are at the end of the map draw a lightGray background
- term.setBackgroundColor(colors.lightGray)
- term.setCursorPos(x-xoff,y-yoff)
- write(" ")
- -- add a block to the buffer if it is at the end of the map
- -- because other wise the block will draw over the light gray background
- buffer:set(x-xoff,y-yoff,{x=x,y=y})
- end
- end
- end
- -- set the screen to visible and set the buffer offsets
- -- the buffer offsets are equal to the previous offsets so that the buffer
- -- knows to undraw the previous frame
- term.current().setVisible(true)
- bxoff = xoff
- byoff = yoff
- drawplayer()
- end
- function renderplayers()
- for i = 1, #players do
- end
- end
- -- checks collision between 2 points and there size.
- function checkCollision(x,y,size,ex,ey,esize)
- --local ex, ey = players[i].x, players[i].y
- --local esize = players[i].size
- local left = x-size
- local right = x+size
- local top = y-size
- local down = x-size
- local eleft = ex-esize
- local eright = ex+esize
- local etop = ey-esize
- local edown = ey+esize
- local topdown = (top >= edown or bottom <= ebottom)
- if(left >= eright and topdown)then
- return true
- end
- if(right <= eleft and topdown)then
- return true
- end
- return false
- end
- -- check if players collide
- function checkpcollide(x,y,size)
- for i = 1, #players do
- local collides = checkCollision(x,y,size,players[i].x,players[i].y,players[i].size)
- end
- return collides
- end
- -- check if there is a collision with the food
- -- if there is give the food to the player and take the food
- -- from the map
- -- this is the reason the buffer check is needed, it will
- -- remove the instance of that food from the buffer
- function checkfoodcollide(x,y,size)
- for iy = y-size, y+size do
- for ix = x-size, x+size do
- if(level:get(ix,iy) ~= "0")then
- players[1].food = players[1].food + 1
- level:set(ix,iy,"0")
- end
- end
- end
- end
- -- clear the screen
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.black)
- term.clear()
- -- centers the camera onto the players bounding box
- -- important note, the player will ALWAYS be in near the center of the screen
- -- but the bounding box's collision x and y's always change so we have to constantly
- -- line up the bounding box with the drawn player.
- function centercam()
- xoff = math.ceil((players[1].x) - ( visplanew/2 - math.floor((players[1].size-2)/2)+2) )
- yoff = math.ceil((players[1].y) - ( ((visplaneh/2)-1) - math.floor((players[1].size)/4)+3) )
- end
- local run = true
- -- center the camera spawn the food and render the screen and player.
- centercam()
- foodSpawn()
- render()
- function loop()
- while run do
- -- wait for events and use the event to
- -- update the game.
- local e = {os.pullEvent()}
- if(e[1] == "timer")then
- gameloop = os.startTimer(0.05)
- end
- update(e)
- end
- end
- loop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement