poppy-client/lua/gameloop.lua

303 lines
7.7 KiB
Lua

levelloop = {}
levelloop.CLIENT = true
levelloop.world = nil
levelloop.textures = {}
levelloop.avatars = {}
commands = {}
require("lua.commands")(commands)
require("shared.commands")(commands)
local protocolVersion = "PPY\x03"
local socket = require "socket"
local utils = require("shared.utils")
local fonts = require("shared.fonts")
local errorHandler = require("shared.error")
local rpc = require("server.rpc")
local constants = require("server.constants")
local format = require("shared.networkFormat")
levelloop.nwChecklist = {}
levelloop.Canvas = {}
local count = 1
local function normalDraw()
if count == 1 then print("use canvas!") count = 2 end
local layerTransform = love.math.newTransform(math.floor(view.x) * scale, math.floor(view.y) * scale, 0, scale, scale)
-- Draw background
if drawBackground then
utils.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, levelloop.world.x * scale, levelloop.world.y * scale)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(levelloop.Canvas.bg, layerTransform)
utils.color_pop()
end
-- draw player
for i, player in pairs(participants) 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(fonts.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(levelloop.Canvas.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)
for i = 30, 120, 30 do
love.graphics.draw(ui.speedText[i/30], 400, i-30)
end
love.graphics.draw(levelloop.Canvas.dbg, layerTransform)
love.graphics.draw(levelloop.Canvas.dbg2, layerTransform)
love.graphics.setCanvas(levelloop.Canvas.dbg2)
love.graphics.clear()
love.graphics.setCanvas()
end
local function remoteCall(name, ...)
local request = protocolVersion .. format.encodeFunction(name, levelloop.clientID or 0, ...)
levelloop.client:send(request)
end
local function networkSync()
while true do
local message, fault = levelloop.client:receive()
if not message then
if fault == "timeout" then
return
else
error(fault)
end
end
local protocolVersion, index = string.unpack("<c4", message, 1)
if protocolVersion ~= "PPY\x03" then
print("Dropping packet with invalid protocol " .. protocolVersion)
else
print("got poppy package")
local DecoderType, index = string.unpack("<I1", message, index)
if (DecoderType == 0x81) then
name, clientID, args = format.decodeFunction(message, index)
print(name)
print(#args)
for i, val in pairs(args) do
print(i, val)
end
commands[name](clientID, table.unpack(args))
end
end
end
end
local function errorhandlerNetwork(msg)
levelloop.remoteCall("playerLeave")
return errorHandler.redscreen(msg)
end
function levelloop.mousepressed(mousex, mousey)
ui.mousepressed(mousex, mousey)
end
function levelloop.loadAvatars()
local container = {}
local entries = love.filesystem.getDirectoryItems("textures/player")
if #entries == 0 then return error("no avatars found") end
for i, file in pairs(entries) do
local path = "textures/player" .."/".. file
local entry = love.filesystem.getInfo(path)
if entry.type == "directory" then
local textures = love.filesystem.getDirectoryItems(path)
for i, texture in pairs(textures) do
print(path)
local imageData = love.image.newImageData(path .. "/" .. texture)
local image = love.graphics.newImage(path .. "/" .. texture)
local imageHash = love.data.hash("sha512", imageData:getString())
container[imageHash] = {data = imageData, image = image}
end
end
end
levelloop.avatars = container
end
function levelloop.init(server, nickname, avatarHash)
love.errorhandler = errorHandler.redscreen
assert(server, "levelloop called without server to connect to?")
assert(nickname, "levelloop called without nickname?")
assert(avatarHash, "levelloop called without avatar?")
levelloop.server = server
scale = 1
love.graphics.setDefaultFilter("nearest", "nearest", 0)
layer = true
grid = 16
color = {}
mouse = {}
window = {}
window.x, window.y = love.graphics.getDimensions()
participants = {}
textures = {}
view = {}
view.x = 0
view.y = 0
clientID = "0"
-- Must be done now because it has to be ready before "init" returns from the server
-- which is /before/ the game world is loaded
levelloop.loadAvatars()
levelloop.client = socket.udp()
levelloop.client:setpeername(server.adress, server.port)
levelloop.client:settimeout(0)
CLIENT = true
SERVER = false
print("Socketnname: " .. levelloop.client:getsockname())
print("Connecting to [" .. server.adress .."]:" .. server.port)
remoteCall("init", nickname, avatarHash)
levelloop.remoteCall = remoteCall
levelloop.networkSync = networkSync
love.update = function(dt)
networkSync(dt)
love.timer.sleep((1/60) -dt)
end
local infoFont
if love.filesystem.getInfo("fonts/font.ttf") then
infoFont = love.graphics.newFont("fonts/font.ttf", 45)
else
infoFont = love.graphics.newFont(45)
end
local message = love.graphics.newText(infoFont, "Connecting...")
love.graphics.draw(message, 40, 40, 0, 1, 1)
love.draw = function(dt)
love.graphics.setColor(0.05, 0.05, 0.05)
love.graphics.rectangle("fill", 0, 0, window.x, window.y)
love.graphics.setColor(1, 1, 1)
love.graphics.draw(message, 40, 40, 0, 1, 1)
end
end
function levelloop.normalVisible(dt)
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 levelloop.reducedVisible(dt)
networkSync(dt)
physics.update(dt)
love.timer.sleep((1/60) -dt)
end
function levelloop.keypressed(key, _)
physics.keypressed(key, _)
camera.keypressed(key, _)
end
function levelloop.keyreleased(key, _)
if key == "r" then
drawBackground = not drawBackground
end
ui.keyreleased(key, _)
camera.keyreleased(key, _)
drawing.keyreleased(key, _)
end
function levelloop.loadworld(world)
-- Game connected!
--love.errorhandler = errorhandlerNetwork
print("make canvas!")
levelloop.Canvas.fg = love.graphics.newCanvas(world.x, world.y)
levelloop.Canvas.bg = love.graphics.newCanvas(world.x, world.y)
if PHYSICS_DEBUG then
levelloop.Canvas.dbg = love.graphics.newCanvas(world.x, world.y)
levelloop.Canvas.dbg2 = love.graphics.newCanvas(world.x, world.y)
end
levelloop.Canvas.physics = {}
levelloop.world = world
ui.init()
drawing.init()
love.update = levelloop.normalVisible
love.visible = function(visible)
if visible then
love.update = levelloop.normalVisible
else
love.update = levelloop.reducedVisible
end
end
drawBackground = true
love.keyreleased = levelloop.keyreleased
love.keypressed = levelloop.keypressed
love.mousepressed = levelloop.mousepressed
if not PHYSICS_DEBUG then
love.draw = normalDraw
else
love.draw = debugDraw
end
love.resize = function()
normalDraw()
ui.resize()
camera.resize()
end
love.quit = function()
levelloop.remoteCall("playerLeave")
end
levelloop.world = world
end