working on game

This commit is contained in:
Ryan Ward 2026-05-16 01:08:18 -07:00
parent 2d74ca0745
commit 3f1d83f790
16 changed files with 600 additions and 133 deletions

View File

Before

Width:  |  Height:  |  Size: 961 KiB

After

Width:  |  Height:  |  Size: 961 KiB

BIN
anime/assets/zanarkand.mp3 Normal file

Binary file not shown.

View File

@ -9,7 +9,7 @@ settings:
categories: # the name of each category should correspond to a yaml file with the same name
- name: shounen # name must be alphanumeric, cannot start with a number or contain special characters "-" and "." are ok if they are not at the beginning
displayName: "Shounen" # if blank will use name
image: "assets/14018-3193093789.gif" # if set will display image instead of name, categories are referenced by name which is required
image: "anime/assets/14018-3193093789.gif" # if set will display image instead of name, categories are referenced by name which is required
- name: openings
displayName: "Openings" # if blank will use name
- name: sadness

View File

@ -25,4 +25,11 @@ questions: # expects a list equal to the tier
time-limit: 10 # If omitted there is no time limit
answer: "Katsuhiro Otomo"
template: "whatis" # template to use
display-answer: true # displays the correct answer before returning to the main screen
- title: "What is this?"
answer: "Bunny shit"
video: "anime/assets/bunny.ogv"
start: 4
playFor: 3
template: "whatvideo" # template to use
display-answer: true # displays the correct answer before returning to the main screen

BIN
assets/speaker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

View File

@ -269,7 +269,9 @@ function LoadTemplate(name, path)
error = multi.error,
theme = theme,
gui = gui,
timer = timer
timer = timer,
-- love stuff
newSource = love.audio.newSource
}
env._G = env

View File

@ -3,24 +3,34 @@ local theme = require("gui.core.theme")
local color = require("gui.core.color")
local multi, thread = require("multi"):init()
local mediaProc = gui:newProcessor()
local miscProc = gui:newProcessor()
local function noOf(sx,sy,sw,sh)
return nil,nil,nil,nil,sx,sy,sw,sh
end
function gui:newVideoPlayer(source, x, y, w, h, sx, sy, sw, sh)
local window = gui:newWindow(x, y, w, h, source, true, theme:new({
function gui:newVideoPlayer(source, x, y, w, h, sx, sy, sw, sh, draggable, th)
local window = self:newWindow(x, y, w, h, sx, sy, sw, sh, "", draggable, th or theme:new({
primary = "#000000",
primaryDark = "#10465c",
primaryText = "#ffffff"
}))
local video = window:newVideo(source, 0, 0, 0, 0, 0, .05, 1, .75)
local play_pause = window:newImageButton("gui/assets/play.png",0,0,0,0,.45,.82,0,.175)
local seek = window:newFrame(0,0,0,0,0,.8,1,.015)
seek.color = color.new("#3c434c")
local seeker = seek:newFrame(0,0,0,0,0,.1,0,.8)
seeker.drawBorder = false
seeker.color = color.new("#0c278a")
local length = video:getDuration()
local play_pause = window:newImageButton("gui/assets/play.png",0,0,0,0,.45,.86,0,.14)
local seek = window:newProgressBar(0,0,0,0,0,.8,1,.05,length*100,0)
seek.OnProgressUpdated(function(self,_,value, drag)
if drag then
local status = video:isPlaying()
video:seek(value/100)
if status then
video:play()
else
video:stop()
end
end
end)
seek:isClickable(true)
play_pause.square = "h"
play_pause.isPaused = true
play_pause:OnReleased(function(self)
@ -34,16 +44,31 @@ function gui:newVideoPlayer(source, x, y, w, h, sx, sy, sw, sh)
self.isPaused = not self.isPaused
end)
local length = video:getDuration()
mediaProc:newThread(function()
while true do
thread.yield()
seeker:setDualDim(nil,nil,nil,nil,nil,nil,video:tell()/length)
thread.hold(function() return video:isPlaying() end)
local p = video:tell()
seek:update(p*100)
end
end)
-- print()
function window:seek(...)
video.video:seek(...)
end
function window:play()
video:play()
end
function window:stop()
video:stop()
end
window.OnClose(function()
video:pause()
end)
return window
end
function gui:newCheckbox(label, x, y, size, sx, sy, checked)
@ -117,21 +142,68 @@ end
function gui:newProgressBar(x, y, w, h, sx, sy, sw, sh, count, value)
local value = value or 0
local count = count or 100
local progressbar = self:newFrame(x,y,w,h,sx,sy,sw,sh)
local fillframe = progressbar:newFrame(noOf(.025, .1, .95, .8))
local fillframe = progressbar:newFrame(2,2,-4,-4,0,0,1,1)
local fill = fillframe:newFrame(noOf(0, 0, 1, 1))
local percentDisplay = fillframe:newTextLabel("",noOf(0,0,1,1))
percentDisplay.align = gui.ALIGN_CENTER
percentDisplay.textColor = color.new("#CC5500")
fillframe.visibility = 0
progressbar.color = color.new("#000000")
fill.color = color.new("#ffffff")
progressbar.fillframe = fillframe
progressbar.fill = fill
progressbar.display = percentDisplay
progressbar.OnProgressUpdated = multi:newConnection()
percentDisplay.visibility = 0
local displayPercent = false
function progressbar:update(value)
if value > count then value = count end
if value < 0 then value = 0 end
function progressbar:showPercent(bool)
displayPercent = bool
if bool then
miscProc:newThread(function()
thread.skip(2)
_,_,_h = percentDisplay:getAbsolutes()
percentDisplay:setFont(math.floor(h/1.3))
self:update()
end)
end
end
function progressbar:isClickable(bool)
fillframe:respectHierarchy(not bool)
-- Makes the bar updatable by clicking on it
fillframe:enableDragging(bool and gui.MOUSE_PRIMARY)
end
local calcFunc = function(self, dx, dy, x, y, istouch)
local sx, sy, sw, sh = self:getAbsolutes()
if x >= sx and x <= sx + sw then
progressbar:update((((x - sx)/sw) * count), true)
end
end
fillframe:OnDragStart(calcFunc)
fillframe.OnDragging(calcFunc)
fillframe.OnPressed(function(self, x, y, dx, dy, istouch)
calcFunc(self, dx, dy, x, y, istouch)
end)
function progressbar:update(v, drag)
v = v or value
if v > count then v = count end
if v < 0 then v = 0 end
local percent = value/count
fill:setDualDim(noOf(nil,nil,percent))
if displayPercent then
percentDisplay.text = math.floor((percent*100)+.5).. "%"
percentDisplay:centerFont()
end
value = v
self.OnProgressUpdated:Fire(self, percent, value, drag)
end
function progressbar:add(n)
@ -151,17 +223,27 @@ function gui:newProgressBar(x, y, w, h, sx, sy, sw, sh, count, value)
end
function progressbar:max()
value = count
self:update(value)
self:update(count)
end
function progressbar:min()
value = 0
self:update(value)
self:update(0)
end
function progressbar:half()
self:update(math.floor(count/2))
end
function progressbar:getPercent()
return math.floor(((value/count)*100)+.5)
end
function progressbar:getValue()
return value
end
progressbar:update(value)
-- to change colors and modify main components
return progressbar, fill, fillframe
return progressbar, fill, percentDisplay, fillframe
end

View File

@ -312,7 +312,7 @@ end
-- ── window constructor (unchanged from original) ──────────────────────────────
local windowCount = 0
function gui:newWindow(x, y, w, h, text, draggable, theme)
function gui:newWindow(x, y, w, h, sx, sy, sw, sh, text, draggable, theme)
local process = gui:newProcessor(text or "window_"..windowCount)
windowCount = windowCount + 1
local parent = self
@ -323,9 +323,9 @@ function gui:newWindow(x, y, w, h, text, draggable, theme)
local sizenwse = love.mouse.getSystemCursor("sizenwse")
local theme = theme or default_theme
local header = self:newFrame(x, y, w, 35)
local header = self:newFrame(x, y, w, 35, sx, sy, sw)
header:setRoundness(10, 10, nil, "top")
local window = header:newFrame(0, 35, 0, h - 35, 0, 0, 1)
local window = header:newFrame(0, 35, 0, h, sx, sy, 1, sh)
window.clipDescendants = true
local left = window:newFrame(0, -4, 4, 0, 0, 0, 0, 1):tag("left")
local right = window:newFrame(-4, -4, 4, 0, 1, 0, 0, 1):tag("right")
@ -384,8 +384,11 @@ function gui:newWindow(x, y, w, h, text, draggable, theme)
local X = header:newTextButton("", -25, -25, 20, 20, 1, 1)
X:setRoundness(10, 10)
X:respectHierarchy(false)
X.align = gui.ALIGN_CENTER
X.color = color.red
window.XButton = X
local darkenX = color.darken(color.red, .2)
X.OnEnter(function(self) self.color = darkenX end)
X.OnExit(function(self) self.color = color.red end)
@ -403,7 +406,10 @@ function gui:newWindow(x, y, w, h, text, draggable, theme)
end)
end
window.OnClose = function() return window end % X.OnPressed
window.OnClose = multi:newConnection()
X.OnPressed(function(self, ...)
window.OnClose:Fire(window, ...)
end)
window.OnClose(function()
header:setParent(gui.virtual)
love.mouse.setCursor(pointer)
@ -758,7 +764,7 @@ function gui:showTaskManager()
local WIN_W = TOTAL_W + 20
local WIN_H = 620
taskManager = gui:newWindow(0, 0, WIN_W, WIN_H, "Task Manager", true, TM_THEME)
taskManager = gui:newWindow(0, 0, WIN_W, WIN_H, nil, nil, nil, nil, "Task Manager", true, TM_THEME)
taskManager.clipDescendants = true
-- ── tab bar ──────────────────────────────────────────────────────────────

View File

@ -1,6 +1,6 @@
local gui = require("gui")
local multi, thread = require("multi"):init()
local processor = gui:newProcessor("Transistion Processor")
local processor = gui:newProcessor("Transition Processor")
local transition = {}
local width, height, flags = love.window.getMode()
@ -13,23 +13,26 @@ end
transition.__index = transition
transition.__call = function(t, start, stop, time, ...)
local args = {...}
return function(st, sp, ti) -- allow these values to be overridden
if not (st or start) or not (sp or stop) then return multi.error("start and stop must be supplied") end
if start == stop then
return function(st, sp, ti)
local s = st or start
local e = sp or stop
local dur = ti or time or 1
if not s or not e then return multi.error("start and stop must be supplied") end
if s == e then
local temp = {
OnStep = function() end,
OnStep = function() end,
OnStop = multi:newConnection()
}
proc:newTask(function()
processor:newTask(function()
temp.OnStop:Fire()
end)
return temp
end
local handle = t.func(t, start, stop, (ti or time) or 1, unpack(args))
local handle = t.func(t, s, e, dur, unpack(args))
return {
OnStep = handle.OnStatus,
OnStop = handle.OnReturn + handle.OnError,
Kill = t.Kill
Kill = function() t:Kill() end
}
end
end
@ -43,11 +46,11 @@ function transition:newTransition(func)
c.OnStop = multi:newConnection()
c.kill = false
function c:SetFPS(fps)
self.fps = fps
function c:SetFPS(f)
self.fps = f
end
function c:GetFPS(fps)
function c:GetFPS()
return self.fps
end
@ -60,17 +63,29 @@ function transition:newTransition(func)
return c
end
transition.glide = transition:newTransition(function(t, start, stop, time, ...)
local steps = t.fps*time
local piece = time/steps
local split = stop-start
transition.glide = transition:newTransition(function(t, start, stop, time)
local split = stop - start
local startTime = love.timer.getTime()
local endTime = startTime + time
local stepTime = 1 / t.fps
t.running = true
for i = 0, steps do
if not(t.kill) then
thread.sleep(piece)
thread.pushStatus(start + i*(split/steps),piece*i)
while not t.kill do
thread.sleep(stepTime)
local now = love.timer.getTime()
local elapsed = now - startTime
local clamped = math.min(elapsed, time)
local value = start + (clamped / time) * split
thread.pushStatus(value, clamped)
if now >= endTime then
break
end
end
t.running = false
t.kill = false
end)

View File

@ -136,6 +136,7 @@ updater:newTask(function()
Hook("joystickadded", gui.Events.OnJoystickAdded.Fire)
end)
-- Hotkeys
local function noOf(sx,sy,sw,sh)
@ -485,13 +486,13 @@ function gui:canPress(mx, my) -- Get the intersection of the clip area and the s
return not (mx > x + w or mx < x or my > y + h or my < y)
end
function gui:isBeingCovered(mx, my)
function gui:isBeingCovered(mx, my, respect)
-- if not respect then return false end
local children = gui:getAllChildren()
for i = #children, 1, -1 do
if children[i] == self then
if children[i] == self or not respect then
return false
elseif children[i]:canPress(mx, my) and not (children[i] == self) and
not (children[i].ignore) then
elseif children[i]:canPress(mx, my) and not (children[i] == self) and not (children[i].ignore) then
return true
end
end
@ -590,7 +591,8 @@ function gui:getUniques(tab)
color = self.color,
borderColor = self.borderColor,
drawBorder = self.drawborder,
rotation = self.rotation
rotation = self.rotation,
shader = self.shader
}
if tab then for i, v in pairs(tab) do base[i] = tab[i] end end
@ -619,6 +621,20 @@ local function testVisual(c, x, y, button, istouch, presses)
return not(c:hasTag("visual") or c:parentHasTag("visual"))
end
local extensions = {}
function gui.registerExtension(template)
table.insert(extensions, template)
end
function gui:extend(c)
for i,v in pairs(extensions) do
for key, value in pairs(v) do
c[key] = value
end
end
end
-- Base Library
function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
local c = {}
@ -633,7 +649,7 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
local function testHierarchy(c, x, y, button, istouch, presses)
if hierarchy then
return not (global_drag or c:isBeingCovered(x, y))
return not (global_drag or c:isBeingCovered(x, y, true))
end
return true
end
@ -723,6 +739,12 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
end)
local _mouseRelRef = gui.Events.OnMouseReleased(function(x, y, button, istouch, presses)
pressed = false -- we need to handle dragging stopped even if an element is not active
if dragging and button == dragbutton then
dragging = false
global_drag = false
c.OnDragEnd:Fire(c, dx, dy, x, y, istouch, presses)
end
if not c:isActive() then return end
if c:canPress(x, y) then
c.OnReleased:Fire(c, x, y, button, istouch, presses)
@ -731,12 +753,6 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
else
c.OnReleasedOther:Fire(c, x, y, button, istouch, presses)
end
pressed = false
if dragging and button == dragbutton then
dragging = false
global_drag = false
c.OnDragEnd:Fire(c, dx, dy, x, y, istouch, presses)
end
end)
local _mousePressRef = gui.Events.OnMousePressed(function(x, y, button, istouch, presses)
@ -751,7 +767,7 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
object_focus = c
end
if draggable and button == dragbutton and not c:isBeingCovered(x, y) and
if draggable and button == dragbutton and not c:isBeingCovered(x, y, hierarchy) and
not global_drag then
dragging = true
global_drag = true
@ -803,7 +819,9 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
return self
end
function c:respectHierarchy(bool) hierarchy = bool end
function c:respectHierarchy(bool)
hierarchy = bool
end
local function centerthread()
if centerX or centerY then
@ -914,6 +932,41 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
if typ == frame then
gui.Events.OnCreated:Fire(c) -- Trigger frame types instantly
end
-- shader stuff
function c:setShader(shader)
if type(shader) == "string" then
self.shader = love.graphics.newShader(shader)
else
self.shader = shader -- already a compiled love Shader object
end
return self
end
function c:clearShader()
self.shader = nil
end
function c:setShaderUniform(name, ...)
if not self.shader then return end
if self.shader:hasUniform(name) then
self.shader:send(name, ...)
end
end
function c:enableShaderTime()
self.__shaderTime = 0
mainupdater.OnLoop(function(_, _, dt)
if not self.shader then return end
self.__shaderTime = self.__shaderTime + dt
if self.shader:hasUniform("time") then
self.shader:send("time", self.__shaderTime)
end
end)
end
gui:extend(c, typ)
return c
end
@ -1122,6 +1175,7 @@ function gui:newTextBase(typ, txt, x, y, w, h, sx, sy, sw, sh)
textColor = c.textColor
})
end
return c
end
@ -1879,6 +1933,8 @@ function gui:newVideo(source, x, y, w, h, sx, sy, sw, sh)
function c:tell() return c.video:tell() end
function c:isPlaying() return c.video:isPlaying() end
updater:newThread("Video Handler",function()
local testCompletion = function() -- More intensive test
@ -2048,7 +2104,13 @@ local draw_handler = function(child, no_draw, dt)
end
end
if child.shader and band(ctype, image) == 2 then
if child.shader then
if child.shader:hasUniform("size") then
child.shader:send("size", {w, h})
end
if child.shader:hasUniform("position") then
child.shader:send("position", {x, y})
end
love.graphics.setShader(child.shader)
end
@ -2066,16 +2128,15 @@ local draw_handler = function(child, no_draw, dt)
love.graphics.setLineStyle("smooth")
love.graphics.setLineWidth(1)
if drawB then
love.graphics.setColor(bbg[1], bbg[2], bbg[3], vis)
draw_factor(child,"line", x, y, w, h, rx, ry, nil, nil, segments)
end
if drawB then
if roundness == "top" then
love.graphics.setColor(bg[1], bg[2], bg[3], vis)
draw_factor(child,"fill", x, y + ry / 2, w, h - ry / 2 + 1)
--love.graphics.rectangle("fill", x, y + ry / 2, w, h - ry / 2 + 1)
love.graphics.setLineStyle("rough")
love.graphics.setLineStyle("smooth")
love.graphics.setColor(bbg[1], bbg[2], bbg[3], 1)
love.graphics.setLineWidth(1)
love.graphics.line(x, y + ry, x, y + h + 1, x + 1 + w, y + h + 1,
@ -2087,9 +2148,10 @@ local draw_handler = function(child, no_draw, dt)
love.graphics.line(x - 1, y + ry / 2 + 2, x - 1, y + h + 2)
love.graphics.line(x + w + 2, y + ry / 2 + 2, x + w + 2, y + h + 2)
elseif roundness == "bottom" then
love.graphics.setColor(bg[1], bg[2], bg[3], vis)
draw_factor(child,"fill", x, y, w, h - ry + 2)
--love.graphics.rectangle("fill", x, y, w, h - ry + 2)
love.graphics.setLineStyle("rough")
love.graphics.setLineStyle("smooth")
love.graphics.setColor(bbg[1], bbg[2], bbg[3], 1)
love.graphics.setLineWidth(2)
love.graphics.line(x - 1, y + ry + 1, x - 1, y - 1, x + w + 1, y - 1,
@ -2123,14 +2185,114 @@ end
gui.draw_handler = draw_handler
local function has_blur_ancestor(child)
local parent = child.parent
while parent and parent ~= gui and parent ~= gui.virtual do
if parent.__blur then return parent end
parent = parent.parent
end
return nil
end
local function blur_draw(child, dt)
local x, y, w, h = child:getAbsolutes()
child.x = x
child.y = y
child.w = w
child.h = h
local b = child.__blur
local pw, ph = math.max(1, math.ceil(w)), math.max(1, math.ceil(h))
if not b.canvas1
or b.canvas1:getWidth() ~= pw
or b.canvas1:getHeight() ~= ph then
b.canvas1 = love.graphics.newCanvas(pw, ph)
b.canvas2 = love.graphics.newCanvas(pw, ph)
end
local prevCanvas = love.graphics.getCanvas()
local prevShader = love.graphics.getShader()
local pr, pg, pb, pa = love.graphics.getColor()
-- -------------------------------------------------------
-- Pass 1: draw the object AND all its descendants onto canvas1
-- -------------------------------------------------------
love.graphics.setCanvas(b.canvas1)
love.graphics.setShader()
love.graphics.clear(0, 0, 0, 0)
love.graphics.setScissor()
-- Shift everything into canvas space by offsetting by -x, -y
love.graphics.push()
love.graphics.translate(-x, -y)
-- Draw the parent object itself
draw_handler(child, nil, dt)
-- Draw all descendants in order
local descendants = child:getAllChildren()
for i = 1, #descendants do
local desc = descendants[i]
-- Recalculate absolutes so positions are correct
local dx, dy, dw, dh = desc:getAbsolutes()
desc.x = dx
desc.y = dy
desc.w = dw
desc.h = dh
draw_handler(desc, nil, dt)
end
love.graphics.pop()
-- -------------------------------------------------------
-- Pass 2: horizontal blur canvas1 → canvas2
-- -------------------------------------------------------
b.shader_h:send("size", {pw, ph})
b.shader_h:send("radius", b.radius)
love.graphics.setCanvas(b.canvas2)
love.graphics.clear(0, 0, 0, 0)
love.graphics.setShader(b.shader_h)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(b.canvas1, 0, 0)
-- -------------------------------------------------------
-- Pass 3: vertical blur canvas2 → screen
-- -------------------------------------------------------
b.shader_v:send("size", {pw, ph})
b.shader_v:send("radius", b.radius)
love.graphics.setCanvas(prevCanvas)
love.graphics.setShader(b.shader_v)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(b.canvas2, x, y)
-- Restore state
love.graphics.setShader(prevShader)
love.graphics.setColor(pr, pg, pb, pa)
love.graphics.setScissor()
end
local draw_loop = drawer:newLoop(function(self, dt)
local children = gui:getAllChildren()
for i = 1, #children do
local child = children[i]
if child.effect then
-- Skip if this child belongs to a blur parent
-- (blur_draw handles drawing it during the canvas capture pass)
if has_blur_ancestor(child) then
-- update x/y/w/h so layout still works, but don't draw
local x, y, w, h = child:getAbsolutes()
child.x = x
child.y = y
child.w = w
child.h = h
elseif child.__blur then
blur_draw(child, dt)
elseif child.effect then
child.effect(function() draw_handler(child, nil, dt) end)
else
draw_handler(child,nil,dt)
draw_handler(child, nil, dt)
end
end
first_loop = true
@ -2256,4 +2418,10 @@ gui.Events.OnResized(function(w, h)
end
end)
-- load shaders
files = love.filesystem.getDirectoryItems("gui/shaders")
for i,v in pairs(files) do
require("gui.shaders."..v:sub(1,-5)).init(gui)
end
return gui

70
gui/shaders/blur.lua Normal file
View File

@ -0,0 +1,70 @@
local blur_h = love.graphics.newShader([[
extern vec2 size;
extern float radius;
vec4 effect(vec4 color, Image tex, vec2 tc, vec2 sc) {
vec2 step = vec2(1.0 / size.x, 0.0);
vec4 result = vec4(0.0);
float total = 0.0;
float sigma = radius * 0.5;
float r = floor(radius);
float i = -r;
while (i <= r) {
float weight = exp(-0.5 * (i * i) / (sigma * sigma));
result += Texel(tex, tc + step * i) * weight;
total += weight;
i = i + 1.0;
}
return (result / total) * color;
}
]])
local blur_v = love.graphics.newShader([[
extern vec2 size;
extern float radius;
vec4 effect(vec4 color, Image tex, vec2 tc, vec2 sc) {
vec2 step = vec2(0.0, 1.0 / size.y);
vec4 result = vec4(0.0);
float total = 0.0;
float sigma = radius * 0.5;
float r = floor(radius);
float i = -r;
while (i <= r) {
float weight = exp(-0.5 * (i * i) / (sigma * sigma));
result += Texel(tex, tc + step * i) * weight;
total += weight;
i = i + 1.0;
}
return (result / total) * color;
}
]])
local c = {}
function c:setBlur(radius)
radius = radius or 8
c.__blur = {
radius = radius,
canvas1 = nil, -- populated on first draw
canvas2 = nil,
shader_h = blur_h,
shader_v = blur_v,
}
end
function c:clearBlur()
c.__blur = nil
end
function c:setBlurRadius(radius)
if c.__blur then
c.__blur.radius = radius
end
end
return {init = function(gui) gui.registerExtension(c) end}

110
main.lua
View File

@ -4,6 +4,52 @@ 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")
-- 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
@ -35,25 +81,6 @@ function love.filedropped(file)
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")
require("gui.addons")
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")
@ -313,56 +340,15 @@ function ScoreBoard(frame, x, y, w, h, sx, sy, sw, sh)
return scoreboard
end
function LandingPage(bg)
-- local webp = require("webp")
init()
local function noOf(sx,sy,sw,sh)
return nil,nil,nil,nil,sx,sy,sw,sh
end
function love.load()
gui:cacheImage({"assets/checked.png","assets/unchecked.png"})
gui:setAspectSize(1920, 1080)
gui.aspect_ratio = true
-- local ext = require("gui.addons.extensions")
local bg = gui:newFrame()
bg:fullFrame()
bg.color = color.new("#242f9b")
-- pb = bg:newProgressBar(0, 0, 200, 40, 0, 0, 0, 0, 200, 0)
-- thread:newThread(function()
-- for i=1,200 do
-- thread.sleep(.01)
-- pb:add(1)
-- end
-- end)
-- local group = bg:newRadioGroup({
-- padding = 5,
-- "Option A",
-- "Option B",
-- "Option C"
-- },0,0,0,0, 80)
-- group.OnSelectionChanged(function(group, selection)
-- print(selection:getLabel())
-- 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")
-- 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)

2
multi

@ -1 +1 @@
Subproject commit 4a52cd5e14abfc409bc82f6427d0cf79f8d2a894
Subproject commit c86413351c8e2fdd3b595d3df1ba0b9ac7d1f9b1

69
templates/whatsound.lua Normal file
View File

@ -0,0 +1,69 @@
--[[ Constants
* (all lua builtins that don't allow io/executing code)
color (interface)
gui (interface)
multi (interface bound to a processor) no thread module
callback true/false correct/wrong
]]
local label
local imageHolder
local function index(window, q, callback)
if not q.sound or q.sound == "" then
error("Missing 'sound' field for question!")
callback()
return
end
frame = window:newFrame(0,0,0,-200,0,.2,1,.8)
frame.visibility = 0
label = window:newTextLabel(" " ..q.title.. " ",0,0,0,0,0,0,1,.2)
label.align = ALIGN_CENTER
label.textColor = color.white
label.color = color.new("#060ce9")
imageHolder = frame:newImageButton("assets/speaker.png",0,0,0,0,0,0,.3,.4)
imageHolder:setAspectSize(imageHolder.imageWidth,imageHolder.imageHeight)
imageHolder:centerX(true)
imageHolder:centerY(true)
local sound = newSource(q.sound,"stream")
imageHolder:OnReleased(function()
if tonumber(q.start) then
sound:seek(q.start)
end
sound:play()
timer(tonumber(q.playFor) or 10, function()
sound:stop()
sound:seek(0)
end)
end)
local correct = window:newTextButton("Correct",0,-200,0,100,0,1,.5)
correct.color = color.new("#52b11b")
local wrong = window:newTextButton("Wrong",0,-200,0,100,.5,1,.5)
wrong.color = color.new("#bd2626")
local skip = window:newTextButton("Skip",0,-100,0,100,.25,1,.5)
skip.color = color.new("#5d5d5d")
window.apply({
fitFont={},
align=window.ALIGN_CENTER,
OnReleased=function(self)
sound:stop()
if self.text == "Skip" then
callback()
return
end
callback(self.text == "Correct")
end,
},correct,wrong,skip)
end
local function update(dt) -- time in seconds that has passed since
label:fitFont()
label:centerFont()
end
return {
index = index,
update = update
}

62
templates/whatvideo.lua Normal file
View File

@ -0,0 +1,62 @@
--[[ Constants
* (all lua builtins that don't allow io/executing code)
color (interface)
gui (interface)
multi (interface bound to a processor) no thread module
callback true/false correct/wrong
]]
local label
local video
local function index(window, q, callback)
if not q.video or q.video == "" then
error("Missing 'video' field for question!")
callback()
return
end
frame = window:newFrame(0,0,0,-200,0,.2,1,.8)
frame.visibility = 0
label = window:newTextLabel(" " ..q.title.. " ",0,0,0,0,0,0,1,.2)
label.align = ALIGN_CENTER
label.textColor = color.white
label.color = color.new("#060ce9")
local holder = frame:newFrame(-300, -200, 600, 400, .5, .5)
holder:centerX(true)
holder:centerY(true)
holder.visibility = 0
video = holder:newVideoPlayer(q.video, 0, 0, 600, 400, false)
video:setAspectSize(video.imageWidth,video.imageHeight)
video:OnReleased(function()
video:play()
end)
video.XButton.visible = false
local correct = window:newTextButton("Correct",0,-200,0,100,0,1,.5)
correct.color = color.new("#52b11b")
local wrong = window:newTextButton("Wrong",0,-200,0,100,.5,1,.5)
wrong.color = color.new("#bd2626")
local skip = window:newTextButton("Skip",0,-100,0,100,.25,1,.5)
skip.color = color.new("#5d5d5d")
window.apply({
fitFont={},
align=window.ALIGN_CENTER,
OnReleased=function(self)
video:stop()
if self.text == "Skip" then
callback()
return
end
callback(self.text == "Correct")
end,
},correct,wrong,skip)
end
local function update(dt) -- time in seconds that has passed since
label:fitFont()
label:centerFont()
end
return {
index = index,
update = update
}