local gui, color, theme, utils, board, yaml, loader, scoreUpdater local activePlayer local playerList = {} local playerStaticList = {} local scoreboard = {} multi, thread = require("multi"):init({priority=true}) multi.setClock(require("socket").gettime) -- When on linux os.clock doesn't reture actual seconds the program has elapsed for GLOBAL, THREAD = require("multi.integration.loveManager"):init() gui = require("gui") color = require("gui.core.color") theme = require("gui.core.theme") utils = require("utils") board = require("board") yaml = require("yaml") loader = require("loader") require("gui.addons") scoreUpdater = gui:getProcessor():newProcessor("score-updater") scoreUpdater.Start() gui.registerExtension({ sayHello = function(self) print("Extended Hello World") end, sayBye = function(self) print("Extended Bye World") end, }) function love.load() gui:cacheImage({"assets/checked.png","assets/unchecked.png","assets/speaker.png"}) gui:setAspectSize(1920, 1080) gui.aspect_ratio = true local bg = gui:newFrame() bg:fullFrame() bg.color = color.new("#242f9b") local btn = bg:newImageButton("rainbow.jpg", 100, 100, 600, 450) btn.color = color.light_blue btn.align = gui.ALIGN_CENTER btn.direction = {1,0} btn:enableShaderTime() btn.OnEnter(function() btn:setShader(gui.SHADERS.blur) end) btn.OnExit(function() btn:setShader() end) -- btn:fitFont() -- btn:centerFont() -- bg:setBlur(10) bg:OnUpdate(function(self, dt) if self.__blur then -- pulse the blur between 2 and 12 local t = love.timer.getTime() self:setBlurRadius(7 + 5 * math.sin(t * 2)) end end) -- StartGame(bg) end function GetActivePlayer() if not activePlayer then return end return activePlayer.link end local function GetPlayerPos() for i,v in pairs(playerStaticList) do if v == GetActivePlayer() then return i end end end function GetNextPlayer() local pos = GetPlayerPos() if pos >= #playerStaticList then activePlayer = playerStaticList[1].Ref.Frame else activePlayer = playerStaticList[pos + 1].Ref.Frame end scoreboard:RenderPlayer(playerList) return GetActivePlayer() end function love.filedropped(file) file:open("r") local data = file:read() print("Load file? " .. file:getFilename()) end function ScoreBoard(frame, x, y, w, h, sx, sy, sw, sh) -- Colors local C_BG_PANEL = color.new("#1a1a2e") local C_BG_HEADER = color.new("#16213e") local C_ACCENT = color.new("#e94560") local C_ROW_TOP = color.new("#1c2641") local C_ROW_NORM = color.new("#121226") local C_BORDER_TOP = color.new("#323c6e") local C_BORDER_NRM = color.new("#1c1c37") local C_BAR_EMPTY = color.new("#232341") local C_TEXT_MUTED = color.new("#786e96") local C_WHITE = color.new("#ffffff") local C_GOLD = color.new("#ffd700") local C_SILVER = color.new("#C0C0C0") local C_BRONZE = color.new("#cd7f32") -- Config stuff local LEADER_HEIGHT_SCALE = .06 local HEIGHT_SCALE = .03 local PLAYER_HEIGHT = .05 -- local rankColors = { C_GOLD, C_SILVER, C_BRONZE } local leaderboard = frame:newFrame(x, y, w, h, sx, sy, sw, sh) leaderboard.color = C_BORDER_NRM local headernum = leaderboard:newTextLabel("#",0,0,0,0,0,LEADER_HEIGHT_SCALE,1/6,HEIGHT_SCALE) headernum.align = gui.ALIGN_CENTER local headerplayer = leaderboard:newTextLabel("PLAYER",0,0,0,0,1/6,LEADER_HEIGHT_SCALE,3/6,HEIGHT_SCALE) headerplayer.align = gui.ALIGN_LEFT local headerscore = leaderboard:newTextLabel("SCORE",0,0,0,0,4/6,LEADER_HEIGHT_SCALE,2/6,HEIGHT_SCALE) headerscore.align = gui.ALIGN_RIGHT local header = leaderboard:newTextLabel("LEADERBOARD",0,0,0,0,0,0,1,LEADER_HEIGHT_SCALE) header.borderColor = C_ACCENT header.textColor = C_ACCENT header.color = C_BG_HEADER header.align = gui.ALIGN_CENTER local BASE_HEIGHT = LEADER_HEIGHT_SCALE + HEIGHT_SCALE gui.apply({ drawBorder = false, color = color.new("#0f2a60"), textColor = C_TEXT_MUTED, }, headernum, headerplayer, headerscore) local updateList = {header, headernum, headerplayer, headerscore} local function ScoreResize() scoreUpdater:newThread(function() thread.skip(2) for _,object in pairs(updateList) do object:fitFont(nil, nil, {scale = 5/6}) object:centerFont() end for _,object in pairs(playerList) do if type(object) == "table" and object.Ref then for i, player in pairs(object.Ref) do if player:hasType(gui.TYPE_TEXT) then player:fitFont(nil, nil, {scale = 5/6}) player:centerFont() end end end end end) end function scoreboard:AddPlayer(name, score, icon) local player = { Name = name, Score = score, Icon = icon, UUID = multi.generate_uuid7(), Add = function(self, amt) self.Score = tostring(tonumber(self.Score) + amt) table.sort(playerList, function(a, b) if a.Score == b.Score then return a.Name < b.Name end return tonumber(a.Score) > tonumber(b.Score) end) scoreboard:RenderPlayer(playerList) ScoreResize() end, } table.insert(playerList, player) table.insert(playerStaticList, player) scoreboard:RenderPlayer(playerList) ScoreResize() return player end local colors = {C_GOLD, C_SILVER, C_BRONZE} local function MapColor(index) if index <=3 and index > 0 then return colors[index] else return C_WHITE end end local add_player = leaderboard:newFrame(5,-5,-10,0,0,1-PLAYER_HEIGHT,1,PLAYER_HEIGHT) local edit_player = leaderboard:newFrame(5,-10,-10,0,0,1-2*PLAYER_HEIGHT,1,PLAYER_HEIGHT) local remove_player = leaderboard:newTextButton("Remove Selected",5,-15,-10,0,0,1-3*PLAYER_HEIGHT,1,PLAYER_HEIGHT) remove_player:setFont(20) remove_player.align = gui.ALIGN_CENTER local embededWatch = {remove_player} scoreUpdater:newThread(function() while true do thread.sleep(.01) for i,v in pairs(embededWatch) do v:centerFont() end end end) local function embedTextEdit(reference, default, but_text, callback) reference.color = C_BORDER_NRM local textbox = reference:newTextBox(default,0,0,0,0,.015,.1,.8,.8) textbox.textColor = C_GOLD textbox.blink = false textbox.color = C_BORDER_TOP textbox.textColor = C_WHITE textbox:OnPressed(function() textbox.text = "" end) local button = reference:newTextButton(but_text,5,0,-10,0,.815,.1,.185,.8) button.color = color.new("#7eae5b") button:OnReleased(function() callback(textbox) end) gui.apply({ setFont = {20}, align = gui.ALIGN_CENTER },textbox,button,reference) table.insert(embededWatch,textbox) table.insert(embededWatch,button) end remove_player.color = color.new("#a13a3a") remove_player:OnReleased(function() local player = GetActivePlayer() uuid = player.UUID for i = 1, #playerList do if playerList[i].UUID == uuid then table.remove(playerList,i) break end end for i = 1, #playerStaticList do if playerStaticList[i].UUID == uuid then table.remove(playerStaticList,i) break end end scoreboard:RenderPlayer(playerList) player.Ref.Frame:destroy() end) embedTextEdit(add_player, "Player Name", "Add", function(self) scoreboard:AddPlayer(self.text, "0") end) embedTextEdit(edit_player, "Modify Score", "Edit", function(self) local player = GetActivePlayer() if player then player.Score = self.text scoreboard:RenderPlayer(playerList) end end) function scoreboard:RenderPlayer(list) for index, player in ipairs(list) do if player.Ref then player.Ref[1].text = player.Name or "" player.Ref[2].text = player.Score or "" player.Ref[3].text = tostring(index) player.Ref.Frame:setDualDim(nil,5*index,nil,nil,nil,BASE_HEIGHT + (index-1) * PLAYER_HEIGHT) player.Ref.Frame.link = player gui.apply({ visibility = 0, drawBorder = false, textColor = MapColor(index) }, unpack(player.Ref)) if activePlayer == nil then activePlayer = player.Ref.Frame end if player.Ref.Frame == activePlayer then player.Ref.Frame.borderColor = C_BORDER_NRM player.Ref.Frame.color = C_ROW_NORM else player.Ref.Frame.borderColor = C_BORDER_TOP player.Ref.Frame.color = C_ROW_TOP end else local playernum, playerName, playerIcon, playerScore, playerLine local playerFrame = leaderboard:newFrame(5,5*index,-10,0,0,BASE_HEIGHT + (index-1) * PLAYER_HEIGHT,1,PLAYER_HEIGHT) playerFrame:OnReleased(function(self) activePlayer = self scoreboard:RenderPlayer(playerList) end) playerFrame:respectHierarchy(false) playerFrame.borderColor = C_BORDER_TOP playerFrame.color = C_ROW_TOP playernum = playerFrame:newTextLabel(index,0,0,0,0,.015,.1,1/8,.8) playernum.align = gui.ALIGN_CENTER if player.Icon ~= nil then playerIcon = playerFrame:newImageLabel(player.Icon,0,0,0,0,.16,.1,.1,.8) playerIcon.square = "h" -- When working with scales squaring is trickier. (h/w) to switch on width or height playerName = playerFrame:newTextLabel(player.Name,0,0,0,0,.3,0,2/5,.8) playerName.align = gui.ALIGN_LEFT playerLine = playerFrame:newFrame(0,0,0,0,.3,.8,.69,.07) playerLine.color = C_GOLD else playerName = playerFrame:newTextLabel(player.Name,0,0,0,0,.16,0,7/13,.8) playerName.align = gui.ALIGN_LEFT playerLine = playerFrame:newFrame(0,0,0,0,.16,.8,7/13 + 2/7,.07) playerLine.color = C_GOLD end playerScore = playerFrame:newTextLabel(player.Score,0,0,0,0,.71,0,2/7,.8) playerScore.align = gui.ALIGN_CENTER playerLine.drawBorder = false gui.apply({ visibility = 0, drawBorder = false, textColor = MapColor(index) },playernum, playerName, playerScore, playerIcon, playerLine) player.Ref = {playerName, playerScore, playernum, playerIcon, playerLine, Frame = playerFrame} end end end gui.Events.OnResized(ScoreResize) ScoreResize() return scoreboard end function LandingPage(bg) end function StartGame(bg) local qframe = bg:newFrame(0, 0, 0, 0, .2, .05, .75, .9) qframe.color = color.new("#060ee9") local scoreboard = ScoreBoard(bg, 0, 0, 0, 0, .015, .05, .170, .9) board.buildBoard(qframe, "anime") end function love.update(dt) gui.update(dt) multi:uManager(dt) end function love.draw() gui.draw() end