339 lines
11 KiB
Lua
339 lines
11 KiB
Lua
local gui, color, theme, utils, board, yaml, loader, system, elements, scoreUpdater
|
|
|
|
local activePlayer
|
|
local playerList = {}
|
|
local playerStaticList = {}
|
|
local scoreboard = {}
|
|
|
|
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 init()
|
|
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")
|
|
system = require("gui.addons.system")
|
|
elements = require("gui.elements")
|
|
|
|
scoreUpdater = gui:getProcessor():newProcessor("score-updater")
|
|
scoreUpdater.Start()
|
|
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 remove_player = leaderboard:newTextButton("Remove Selected",5,-10,-10,0,0,1-2*PLAYER_HEIGHT,1,PLAYER_HEIGHT)
|
|
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)
|
|
add_player.color = C_BORDER_NRM
|
|
local textbox = add_player:newTextBox("Player name",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)
|
|
|
|
-- A bit glitchy
|
|
-- gui:setHotKey({"return"})(function()
|
|
-- local object_focus = gui:getObjectFocus()
|
|
-- if object_focus:hasType(gui.TYPE_BOX) then
|
|
-- scoreboard:AddPlayer(textbox.text, "0")
|
|
-- end
|
|
-- end)
|
|
|
|
local addbutton = add_player:newTextButton("Add",5,0,-10,0,.815,.1,.185,.8)
|
|
addbutton.color = color.new("#7eae5b")
|
|
|
|
addbutton:OnReleased(function()
|
|
scoreboard:AddPlayer(textbox.text, "0")
|
|
end)
|
|
|
|
gui.apply({
|
|
setFont = {20},
|
|
align = gui.ALIGN_CENTER
|
|
},textbox,addbutton,remove_player)
|
|
|
|
thread:newThread(function()
|
|
while true do
|
|
thread.sleep(.01)
|
|
textbox:centerFont()
|
|
addbutton:centerFont()
|
|
remove_player:centerFont()
|
|
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
|
|
|
|
|
|
require("gui.addons.players")
|
|
-- local webp = require("webp")
|
|
function love.load()
|
|
init()
|
|
gui:cacheImage({"assets/checked.png","assets/unchecked.png"})
|
|
gui:setAspectSize(1920, 1080)
|
|
gui.aspect_ratio = true
|
|
local bg = gui:newFrame()
|
|
bg:fullFrame()
|
|
bg.color = color.new("#242f9b")
|
|
|
|
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, "ai-anime")
|
|
|
|
-- gui:newVideoPlayer("test.ogv",0,0,428,240)
|
|
-- local img = webp.load("test.webp")
|
|
-- gui:newImageLabel(img,0,0,735,1041)
|
|
end
|
|
|
|
function love.update(dt)
|
|
gui.update(dt)
|
|
multi:uManager(dt)
|
|
end
|
|
|
|
function love.draw()
|
|
gui.draw()
|
|
end
|
|
|