poppy-client/lua/gameloop.lua

314 lines
7.6 KiB
Lua

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