menu = {} menu.serverlist = { {description = "A localhost server", host = "::1", port = "11150"}, {description = "A localhost server [ipv4]", host = "127.0.0.1", port = "11150"} } local utils = require("shared.utils") local fonts = require("shared.fonts") local catalog = require("shared.catalog") local icon = require("shared.icon") local layout = require("lua.layout") local altPressed, enterPressed = false, false function menu.keyreleased(key, _) if key == "lalt" then altPressed = false end if key == "return" then enterPressed = false end end function menu.keypressed(key, _) if key == "return" then enterPressed = true end if key == "lalt" then altPressed = true end if key == "f11" or (altPressed and key == "return") or (enterPressed and key == "lalt") then fullscreen = not fullscreen love.window.setFullscreen(fullscreen, "desktop") end end function menu.resize() menu.width, menu.height = love.window.getMode() menu.Canvas = love.graphics.newCanvas(width, height) love.graphics.setCanvas(menu.Canvas) love.graphics.clear() drawMenu(w, h) love.graphics.setCanvas() end local firstClient = true function menu.mousepressed(mousex, mousey) for i, v in ipairs(layout.uiState.MainMenu) do if mousex >= v.x and mousex <= v.x2 and mousey >= v.y and mousey <= v.y2 then if v.kind == "localServer" then menuMusic[menuMusic.trac]:stop() love.graphics.reset() love.graphics.origin() love.graphics.clear(.6, 0, .6) love.graphics.setColor(1, 1, 1) love.graphics.present() local serverloop = require("server.main") serverloop.init(v.identifier) elseif v.kind == "server" then if firstClient then menuMusic[menuMusic.trac]:stop() dofile "lua/gameloop.lua" dofile "lua/layout.lua" dofile "lua/ui.lua" dofile "lua/camera.lua" dofile "lua/physics.lua" dofile "lua/drawing.lua" setmetatable(_G, { __index = function(self, idx) if rawget(self, idx) == nil then error("attempted to read implicit global:" .. idx) end end }) PHYSICS_DEBUG = true NETWORK_DEBUG = true firstclient = false end local textures = levelloop.textures local fullName = catalog.firstNames[love.math.random(1, #catalog.firstNames)] .. " " .. catalog.surNames[love.math.random(1, #catalog.surNames)] local serverID = v.identifier local serverEntry = menu.serverlist[serverID] local avatar = love.image.newImageData(catalog.default.avatar) local avatarHash = love.data.hash("sha512", avatar:getString()) levelloop.init({ adress = serverEntry.host, port = serverEntry.port }, fullName, avatarHash) layout.uiState.MainMenu = {} end end end end menu.serverentry = function(id, description, host, port) return {name = "cursorSelect", kind = "server", identifier = id, uiSelect = "MainMenu", {name = "horizontal", {name = "drawTexture", texture = icon.joinServer}, {name = "spacer", width = 10 }, {name = "labelWShadow", text = description }, {name = "spacer", width = 20 }, {name = "labelWShadow", text = "host: ".. host, font = fonts.smallFont}, {name = "spacer", width = 10 }, {name = "labelWShadow", text = "port:".. port, font = fonts.smallFont}, } } end menu.layoutServerList = function() local list = {} for i, v in ipairs(menu.serverlist) do table.insert(list, menu.serverentry(i, v.description, v.host, v.port)) end return unpack(list) end menu.layoutLocalServer = function() return {name = "vertical", {name = "cursorSelect", kind = "localServer", identifier = {"::1", "11150"}, uiSelect = "MainMenu", {name = "horizontal", {name = "spacer", width = 30}, {name = "drawTexture", texture = icon.startServer }, {name = "spacer", width = 5}, {name = "labelWShadow", text = "Create a local server"}, } }, {name = "cursorSelect", kind = "localServer", identifier = {"0.0.0.0", "11150"}, uiSelect = "MainMenu", {name = "horizontal", {name = "spacer", width = 30}, {name = "drawTexture", texture = icon.startServer }, {name = "spacer", width = 5}, {name = "labelWShadow", text = "Create a local server [IPV4]"}, } }, {name = "spacer", height = 20}, } end menu.layout = function(message) return {name ="vertical", {name = "spacer", height = 20}, {name = "horizontal", {name = "spacer", width = 20}, {name = "drawTexture", texture = icon.logo}, {name = "labelWShadow", font = fonts.bigFont, text = "Welcome to poppy!"}, }, {name = "horizontal", {name = "spacer", width = 50}, {name = "vertical", {name = "labelWShadow", text = "Pick a server to join!", font = fonts.headerFont}, {name = "spacer", height = 20}, {name = "horizontal", {name = "spacer", width = 10}, {name = "vertical", {name = "vertical", menu.layoutServerList(), }, {name = "vertical", {name = "spacer", height = 10}, {name = "horizontal", {name = "drawTexture", texture = icon.addServer}, {name = "spacer", width = 10 }, {name = "labelWShadow", text = "placeholder (new server)" }, {name = "spacer", width = 20 }, {name = "labelWShadow", text = "host: newhost", font = fonts.smallFont}, {name = "spacer", width = 10 }, {name = "labelWShadow", text = "port: newport", font = fonts.smallFont}, } } } } } } } end function drawMenu(message) utils.color_push() love.graphics.setCanvas(menu.Canvas) layout.uiState.MainMenu = {} love.graphics.clear( ) layout.handle(menu.layout(message), 0, 0) local sizex, sizey = layout.handle(menu.layoutLocalServer(), 0, 0, true) layout.handle(menu.layoutLocalServer(), 0, menu.height - sizey) love.graphics.setCanvas() utils.color_pop() end local bubbles = {} function menu.draw() for i=1, #bubbles do drawBubble(bubbles[i]) end love.graphics.draw(menu.Canvas) layout.handle(debugAudio(), 600, 300) end menuMusic = {} menuMusic[1] = love.audio.newSource("sound/Poppy Main Menu theme_2.ogg", "stream") menuMusic[2] = love.audio.newSource("sound/Poppy Main Menu theme_2.ogg", "stream") menuMusic.duration = menuMusic[1]:getDuration("seconds") menuMusic.samples = menuMusic[1]:getDuration("samples") menuMusic.fading = false menuMusic.trac = 1 menuMusic.nextTrac = 2 menuMusic.fadeStart = 0 menuMusic.fadeEnd = 0 menuMusic.fadeTime = 0 function musicUpdate(dt) if not menuMusic.fading then if menuMusic[menuMusic.trac]:tell("seconds") >= menuMusic.duration - 20 then menuMusic.fading = true menuMusic.fadeStart = menuMusic[menuMusic.trac]:tell("samples") menuMusic.fadeTime = menuMusic.samples - menuMusic.fadeStart menuMusic[menuMusic.nextTrac]:setVolume(1) menuMusic[menuMusic.nextTrac]:play() end else local fadefraction = ( menuMusic.fadeStart - menuMusic[menuMusic.trac]:tell("samples") ) / menuMusic.fadeTime menuMusic[menuMusic.trac]:setVolume(fadefraction) menuMusic[menuMusic.nextTrac]:setVolume(fadefraction - 1) if fadefraction > 0.95 then menuMusic[menuMusic.trac]:stop() menuMusic[menuMusic.nextTrac]:setVolume(1) local trac = menuMusic.trac menuMusic.trac = menuMusic.nextTrac menuMusic.nextTrac = trac menuMusic.fading = false end end end function debugAudio() return {name = "vertical", {name = "labelWShadow", text = "CUR: " .. menuMusic.trac, font = fonts.smallFont}, {name = "labelWShadow", text = "CUR " .. menuMusic.duration, font = fonts.smallFont}, {name = "labelWShadow", text = "CUR " .. menuMusic[menuMusic.trac]:tell("seconds"), font = fonts.smallFont}, {name = "labelWShadow", text = "CUR " .. menuMusic.samples, font = fonts.smallFont}, {name = "labelWShadow", text = "CUR " .. menuMusic[menuMusic.trac]:tell("samples"), font = fonts.smallFont}, {name = "labelWShadow", font = fonts.smallFont, text = "CUR volume:" .. menuMusic[menuMusic.trac]:getVolume()}, {name = "spacer", height = 20}, {name = "labelWShadow", text = "NXT: " .. menuMusic.nextTrac, font = fonts.smallFont}, {name = "labelWShadow", text = "NXT " .. menuMusic.duration, font = fonts.smallFont}, {name = "labelWShadow", text = "NXT " .. menuMusic[menuMusic.nextTrac]:tell("seconds"), font = fonts.smallFont}, {name = "labelWShadow", text = "NXT " .. menuMusic.samples, font = fonts.smallFont}, {name = "labelWShadow", text = "NXT " .. menuMusic[menuMusic.nextTrac]:tell("samples"), font = fonts.smallFont}, {name = "labelWShadow", font = fonts.smallFont, text = "NXT volume:" .. menuMusic[menuMusic.nextTrac]:getVolume()}, } end local elapsed = 0 function menu.update(dt) if elapsed > 1 / 60 then for i=1, #bubbles do local bubble = bubbles[i] local sx = bubble.sx * dt local sy = bubble.sy * dt local bubble = bubbles[i] bubble.x = bubble.x + sx bubble.y = bubble.y + sy if bubble.x + bubble.radius >= menu.width then bubble.x = menu.width - bubble.radius bubble.sx = -bubble.sx end if bubble.x - bubble.radius <= 0 then bubble.x = bubble.radius bubble.sx = -bubble.sx end if bubble.y - bubble.radius <= 0 then bubble.y = bubble.radius bubble.sy = -bubble.sy end if bubble.y + bubble.radius >= menu.height then bubble.y = menu.height - bubble.radius bubble.sy = -bubble.sy end end elapsed = 0 end elapsed = elapsed + dt musicUpdate(dt) end function drawBubble(bubble) utils.color_push() love.graphics.setColor(bubble.color[1]* .6, bubble.color[2] * .6, bubble.color[3] * .6, bubble.color[4]) love.graphics.circle("fill", bubble.x, bubble.y, bubble.radius ) love.graphics.setColor(bubble.color[1]* .9, bubble.color[2] * .9, bubble.color[3] * .9, bubble.color[4]) love.graphics.circle("fill", bubble.x, bubble.y, bubble.radius -3 ) --love.graphics.setColor(bubble.color) --love.graphics.circle("fill", bubble.x, bubble.y, bubble.radius/2 ) utils.color_pop() end function menu.init(message) menu.width, menu.height = love.window.getMode() math.randomseed(os.time()) for i=1,24 do local bubble = {} bubble.radius = 10 + math.floor(math.random() * 30) bubble.color = catalog.pastelColors[math.floor(1 + math.random() * #catalog.pastelColors - 0.001)] bubble.y = bubble.radius + math.floor(math.random() * (menu.height - (2* bubble.radius))) bubble.x = bubble.radius + math.floor(math.random() * (menu.width - (2* bubble.radius))) bubble.sx = 20 - math.random() * 40 bubble.sy = 20 - math.random() * 40 table.insert(bubbles, bubble) end menuMusic[menuMusic.trac]:play() menu.Canvas = love.graphics.newCanvas(menu.width, menu.height) drawMenu() love.draw = menu.draw love.update = menu.update love.keyreleased = menu.keyreleased love.keypressed = menu.keypressed love.mousepressed = menu.mousepressed end return menu