gameloop = {} gameloop.world = nil gameloop.textures = {} local rpc = require("server.rpc") local v2_message = require("lua.network") local socket = require "socket" local util = require("server.utils") local function normalDraw() local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale) -- Draw background if drawBackground then color_push() love.graphics.setColor(0.05, 0.05, 0.05) love.graphics.rectangle("fill", math.floor(view.x) * scale, math.floor(view.y) * scale, gameloop.world.x * scale, gameloop.world.y * scale) love.graphics.setColor(1, 1, 1, 1) love.graphics.draw(gameloop.buffer.pixel.bg, layerTransform) color_pop() end -- draw player for i, player in pairs(players) do local playerTransform = love.math.newTransform( math.floor(player.x) * scale + math.floor(view.x) * scale, math.floor(player.y) * scale + math.floor(view.y) * scale, 0, scale, scale) love.graphics.draw(player.avatar, playerTransform) if player.name then if not player.label then player.label = love.graphics.newText(ui.smallFont, player.name) end local labelTransform = love.math.newTransform( math.floor(player.x - (player.label:getWidth() / 2) + (player.avatar:getPixelWidth() /2)) * scale + math.floor(view.x) * scale, math.floor(player.y - (player.label:getHeight())) * scale + math.floor(view.y) * scale, 0, scale, scale) love.graphics.draw(player.label, labelTransform) end end -- Draw foreground love.graphics.draw(gameloop.buffer.pixel.fg, layerTransform) -- Draw UI love.graphics.draw(ui.buffer) end local function debugDraw() normalDraw() local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale) love.graphics.draw(gameloop.buffer.pixel.dbg, layerTransform) love.graphics.draw(gameloop.buffer.pixel.dbg2, layerTransform) love.graphics.setCanvas(gameloop.buffer.pixel.dbg2) love.graphics.clear() love.graphics.setCanvas() end local function normalNetworkSend(args) if clientID == "0" then print("Invalid clientID?") end local request = "poppyV002" ..US.. clientID ..US.. args gameloop.client:send(request) end local function debugNetworkSend(args) assert(clientID ~= 0) local request = "poppyV002" ..US.. clientID ..US.. args print("=> " .. util.pprint(request)) gameloop.client:send(request) end function normalNetworkSync() local message, errorString = nil, false while not errorString do local message, errorString = gameloop.client:receive() if not message then if errorString == "timeout" then return else error(errorString) end end local response = rpc.validate(message) if not response.errorMsg then rpc.execute(v2_message, response.clientID, response.record) message = nil else error(errorMsg) end end end function debugNetworkSync() local message, errorString = nil, false while not errorString do local message, errorString = gameloop.client:receive() if message then print("<= " .. util.pprint(message)) end if not message then if errorString == "timeout" then return else menu.init() return end end local response = rpc.validate(message) if not response.errorMsg then rpc.execute(v2_message, response.clientID, response.record) message = nil else error(errorMsg) end end end local function errorhandlerNetwork(msg) gameloop.networkSend(unit("playerLeave")) return errorhandler(msg) end function errorhandler(msg) local errorfont if love.filesystem.getInfo("fonts/font.ttf") then errorfont = love.graphics.newFont("fonts/font.ttf", 45) else errorfont = love.graphics.getFont(45) end love.graphics.reset() love.graphics.origin() love.graphics.clear(.4, 0, 0) love.graphics.setColor(1, 1, 1) local message = love.graphics.newText(errorfont, "Poppy has encountered a critical fault") local message2 = love.graphics.newText(errorfont, "Press q to exit") local message3 = love.graphics.newText(errorfont, msg) love.graphics.draw(message, 40, 40, 0, 1, 1) love.graphics.draw(message2, 40, 95, 0, 1, 1) love.graphics.draw(message3, 40, 145, 0, 1, 1) local indent = 0 local messageline for line in debug.traceback():gmatch("([^\n]*)\n?") do messageline = love.graphics.newText(errorfont, line) love.graphics.draw(messageline, 40, 255 + indent, 0, 1, 1) indent = indent + 55 end love.graphics.present() return function() love.event.pump() for event, action in love.event.poll() do if event == "quit" then return 1 end if event == "keypressed" then if action == "q" then love.event.quit( 1 ) end end end love.timer.sleep(0.1) end end function gameloop.mousepressed(mousex, mousey) ui.mousepressed(mousex, mousey) end function gameloop.init(server, nickname) love.errorhandler = errorhandler assert(server, "Gameloop called without server to connect to?") assert(nickname, "Gameloop called without nickname?") gameloop.server = server scale = 1 love.graphics.setDefaultFilter("nearest", "nearest", 0) layer = true grid = 16 color = {} mouse = {} window = {} window.x, window.y = love.graphics.getDimensions() players = {} textures = {} view = {} view.x = 0 view.y = 0 clientID = "0" gameloop.client = socket.udp() gameloop.client:setpeername(server.adress, server.port) gameloop.client:settimeout(0) print("Socketnname: " .. gameloop.client:getsockname()) print("Connecting to [" .. server.adress .."]:" .. server.port) local request = "poppyV002" ..US.. "0" ..US.. unit("init", nickname) gameloop.client:send(request) if NETWORK_DEBUG then print("=> " .. util.pprint(request)) end if not NETWORK_DEBUG then gameloop.networkSend = normalNetworkSend gameloop.networkSync = normalNetworkSync else gameloop.networkSend = debugNetworkSend gameloop.networkSync = debugNetworkSync end love.update = function(dt) gameloop.networkSync(dt) love.timer.sleep((1/60) -dt) end love.draw = function(dt) love.graphics.present() end end function gameloop.normalVisible(dt) gameloop.networkSync(dt) camera.input(dt) physics.input(dt) drawing.input(dt) physics.update(dt) camera.update(dt) love.timer.sleep((1/60) -dt) end function gameloop.reducedVisible(dt) gameloop.networkSync(dt) physics.update(dt) love.timer.sleep((1/60) -dt) end function gameloop.keypressed(key, _) physics.keypressed(key, _) camera.keypressed(key, _) end function gameloop.keyreleased(key, _) if key == "r" then drawBackground = not drawBackground end ui.keyreleased(key, _) camera.keyreleased(key, _) drawing.keyreleased(key, _) end function gameloop.loadworld(world) -- Game connected! love.errorhandler = errorhandlerNetwork local buffer = {} buffer.pixel = {} buffer.pixel.fg = love.graphics.newCanvas(world.x, world.y) buffer.pixel.bg = love.graphics.newCanvas(world.x, world.y) if PHYSICS_DEBUG then buffer.pixel.dbg = love.graphics.newCanvas(world.x, world.y) buffer.pixel.dbg2 = love.graphics.newCanvas(world.x, world.y) end buffer.physics = {} gameloop.buffer = buffer ui.init() drawing.init() love.update = gameloop.normalVisible love.visible = function(visible) if visible then love.update = gameloop.normalVisible else love.update = gameloop.reducedVisible end end drawBackground = true love.keyreleased = gameloop.keyreleased love.keypressed = gameloop.keypressed love.mousepressed = gameloop.mousepressed if not PHYSICS_DEBUG then love.draw = normalDraw else love.draw = debugDraw end love.resize = function() ui.resize() camera.resize() end love.quit = function() gameloop.networkSend(unit("playerLeave")) end gameloop.world = world end