fixed package so it contains templates, updated config for more control
@@ -0,0 +1,3 @@
|
||||
bin/*
|
||||
love/*
|
||||
game.love
|
||||
@@ -1,20 +0,0 @@
|
||||
settings:
|
||||
increment: 100
|
||||
start: 100
|
||||
tiers: 5
|
||||
dailyDouble:
|
||||
enabled: true
|
||||
minQuestions: 7
|
||||
count: 2
|
||||
|
||||
categories:
|
||||
- name: shounen
|
||||
displayName: "Shounen"
|
||||
- name: villains
|
||||
displayName: "Villains"
|
||||
- name: openings
|
||||
displayName: "Openings"
|
||||
- name: studios
|
||||
displayName: "Studios & Staff"
|
||||
- name: plot-twists
|
||||
displayName: "Plot Twists"
|
||||
@@ -1,33 +0,0 @@
|
||||
questions:
|
||||
- title: "The iconic opening 'Guren no Yumiya' by Linked Horizon belongs to this anime."
|
||||
time-limit: 15
|
||||
answer: "Attack on Titan"
|
||||
template: "whatis"
|
||||
|
||||
- title: "Which anime features the opening 'Unravel' by TK from Ling Tosite Sigure?"
|
||||
answer: 2
|
||||
choices:
|
||||
- "Parasyte"
|
||||
- "Tokyo Ghoul"
|
||||
- "Deadman Wonderland"
|
||||
- "Elfen Lied"
|
||||
template: "multiplechoice"
|
||||
|
||||
- title: "'Cruel Angel's Thesis' is the legendary opening theme of this 1995 mecha anime."
|
||||
time-limit: 20
|
||||
answer: "Neon Genesis Evangelion"
|
||||
template: "whatis"
|
||||
|
||||
- title: "Which of these bands performed 'Again', the first opening of Fullmetal Alchemist: Brotherhood?"
|
||||
answer: 4
|
||||
choices:
|
||||
- "Asian Kung-Fu Generation"
|
||||
- "Flow"
|
||||
- "Scandal"
|
||||
- "YUI"
|
||||
template: "multiplechoice"
|
||||
|
||||
- title: "This artist performed 'Gurenge', the first opening of Demon Slayer: Kimetsu no Yaiba, which became a massive hit in Japan."
|
||||
time-limit: 25
|
||||
answer: "LiSA"
|
||||
template: "whatis"
|
||||
@@ -1,33 +0,0 @@
|
||||
questions:
|
||||
- title: "In Code Geass, Lelouch's Geass ability compels anyone who makes direct eye contact with him to do this."
|
||||
time-limit: 20
|
||||
answer: "Obey any one order he gives them"
|
||||
template: "whatis"
|
||||
|
||||
- title: "At the end of Madoka Magica, Madoka's wish rewrites the laws of the universe to do what?"
|
||||
answer: 2
|
||||
choices:
|
||||
- "Destroy all witches that have ever existed and will ever exist"
|
||||
- "Erase all witches before they are born, taking herself out of existence"
|
||||
- "Turn every magical girl back into a normal human"
|
||||
- "Destroy Kyubey and the incubator race"
|
||||
template: "multiplechoice"
|
||||
|
||||
- title: "In Fullmetal Alchemist: Brotherhood, Edward and Alphonse discover their mother was not actually revived — what they created during their human transmutation was this."
|
||||
time-limit: 30
|
||||
answer: "A soulless body / failed homunculus (not their mother)"
|
||||
template: "whatis"
|
||||
|
||||
- title: "Which of these correctly describes the twist at the end of Assassination Classroom?"
|
||||
answer: 3
|
||||
choices:
|
||||
- "Koro-sensei was always a government weapon and willingly lets himself be killed"
|
||||
- "The students refuse to kill Koro-sensei and he escapes to space"
|
||||
- "Koro-sensei asks his students to be the ones to kill him as his final wish"
|
||||
- "Nagisa kills the minister of defense and Koro-sensei is freed"
|
||||
template: "multiplechoice"
|
||||
|
||||
- title: "In Gurren Lagann, Simon discovers that the key to piloting Lagann is not a special device but actually this."
|
||||
time-limit: 25
|
||||
answer: "His own drill / fighting spirit (spiral power)"
|
||||
template: "whatis"
|
||||
@@ -1,33 +0,0 @@
|
||||
questions:
|
||||
- title: "This is the name of the signature technique Naruto Uzumaki uses to create physical copies of himself."
|
||||
time-limit: 15
|
||||
answer: "Shadow Clone Jutsu"
|
||||
template: "whatis"
|
||||
|
||||
- title: "In Dragon Ball Z, Goku achieved this transformation for the first time during his battle against Frieza on Namek."
|
||||
time-limit: 20
|
||||
answer: "Super Saiyan"
|
||||
template: "whatis"
|
||||
|
||||
- title: "Which of these is the name of Ichigo Kurosaki's Zanpakuto in Bleach?"
|
||||
answer: 3
|
||||
choices:
|
||||
- "Zangetsu"
|
||||
- "Senbonzakura"
|
||||
- "Tensa Zangetsu"
|
||||
- "Ryujin Jakka"
|
||||
template: "multiplechoice"
|
||||
|
||||
- title: "In Hunter x Hunter, this is the name of the system of power that allows users to manipulate their life energy."
|
||||
time-limit: 25
|
||||
answer: "Nen"
|
||||
template: "whatis"
|
||||
|
||||
- title: "Which of these Devil Fruits did Monkey D. Luffy eat, giving him his rubber powers?"
|
||||
answer: 2
|
||||
choices:
|
||||
- "Mera Mera no Mi"
|
||||
- "Gomu Gomu no Mi"
|
||||
- "Hana Hana no Mi"
|
||||
- "Bara Bara no Mi"
|
||||
template: "multiplechoice"
|
||||
@@ -1,33 +0,0 @@
|
||||
questions:
|
||||
- title: "This animation studio, co-founded by Hayao Miyazaki, produced Spirited Away, My Neighbor Totoro, and Princess Mononoke."
|
||||
time-limit: 15
|
||||
answer: "Studio Ghibli"
|
||||
template: "whatis"
|
||||
|
||||
- title: "Which studio produced Fullmetal Alchemist: Brotherhood, Sword of the Stranger, and Mob Psycho 100?"
|
||||
answer: 1
|
||||
choices:
|
||||
- "Bones"
|
||||
- "Madhouse"
|
||||
- "White Fox"
|
||||
- "A-1 Pictures"
|
||||
template: "multiplechoice"
|
||||
|
||||
- title: "This director is known for helming Cowboy Bebop, Samurai Champloo, and Space Dandy."
|
||||
time-limit: 25
|
||||
answer: "Shinichiro Watanabe"
|
||||
template: "whatis"
|
||||
|
||||
- title: "Which studio is responsible for the long-running adaptations of One Piece and Dragon Ball Super?"
|
||||
answer: 3
|
||||
choices:
|
||||
- "Pierrot"
|
||||
- "Sunrise"
|
||||
- "Toei Animation"
|
||||
- "TMS Entertainment"
|
||||
template: "multiplechoice"
|
||||
|
||||
- title: "This legendary animator, known as 'the god of manga', created Astro Boy and is considered the father of modern anime and manga."
|
||||
time-limit: 20
|
||||
answer: "Osamu Tezuka"
|
||||
template: "whatis"
|
||||
|
Before Width: | Height: | Size: 961 KiB |
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 256 KiB |
|
Before Width: | Height: | Size: 1.8 MiB |
@@ -1,24 +0,0 @@
|
||||
settings:
|
||||
increment: 100 # how much each tier increases by
|
||||
start: 100 # starting amount see tier's comment
|
||||
tiers: 5 # 5 tiers 100, 200, 300, 400, 500 based on above settings
|
||||
dailyDouble:
|
||||
enabled: true # should daily double be enabled?
|
||||
minQuestions: 7 # how many questions need to be answered before a daily double can appear?
|
||||
count: 2 # how many daily doubles should there be?
|
||||
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: "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
|
||||
displayName: "Sadness" # if blank will use name
|
||||
- name: random
|
||||
displayName: Random # if blank will use name
|
||||
- name: you-would-have-though
|
||||
displayName: "You would have\nthought" # if blank will use name
|
||||
- name: wtf-is-that
|
||||
displayName: "Wtf is that!?" # if blank will use name
|
||||
- name: owo
|
||||
displayName: "owo" # if blank will use name
|
||||
@@ -1,35 +0,0 @@
|
||||
questions: # expects a list equal to the tier
|
||||
- title: "Name at least 10 of the characters here"
|
||||
time-limit: 60 # If omitted there is no time limit
|
||||
answer: 10
|
||||
image: "anime/assets/shounen_name_characters.png"
|
||||
template: "one-image" # template to use
|
||||
display-answer: true # displays the correct answer before returning to the main screen
|
||||
- title: "What anime is this?"
|
||||
time-limit: 30 # If omitted there is no time limit
|
||||
answer: "steins;gate"
|
||||
imageA: "anime/assets/beer.jpg"
|
||||
imageB: "anime/assets/gate.jpg"
|
||||
display-answer: true # displays the correct answer before returning to the main screen
|
||||
template: "imageword" # template to use
|
||||
- title: "What is 2+2"
|
||||
answer: 2 # positon of correct answer
|
||||
choices:
|
||||
- "22"
|
||||
- "4" # this is 2
|
||||
- "9000"
|
||||
- "-4"
|
||||
- "wack"
|
||||
template: "multiplechoice"
|
||||
- title: "Who directed the groundbreaking film 'Akira',\nwhich helped introduce anime to Western audiences?"
|
||||
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
|
||||
|
After Width: | Height: | Size: 613 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
@@ -1,290 +0,0 @@
|
||||
local gui = require("gui")
|
||||
local color = require("gui.core.color")
|
||||
local loader = require("loader")
|
||||
local theme = require("gui.core.theme")
|
||||
local fmt = require("fmt")
|
||||
local timer = require("utils")
|
||||
local multi, thread = require("multi"):init()
|
||||
|
||||
local timesup = love.audio.newSource("assets/sounds/timesup.mp3", "static")
|
||||
local double = love.audio.newSource("assets/sounds/double.mp3", "static")
|
||||
|
||||
local boardUpdater = gui:getProcessor():newProcessor("board-updater")
|
||||
boardUpdater.Start()
|
||||
|
||||
local activePlayer
|
||||
local playerList = {}
|
||||
local playerStaticList = {}
|
||||
local scoreboard = {}
|
||||
|
||||
-- Create a table to manage GUI elements
|
||||
local manage = {}
|
||||
|
||||
-- Function to resize fonts for all managed elements
|
||||
local function resizeFonts()
|
||||
-- Use multi-threading to improve performance
|
||||
multi:newThread(function()
|
||||
-- Introduce a small delay to avoid too many iterations at once
|
||||
thread.skip(2)
|
||||
-- Iterate over each element in the 'manage' table
|
||||
for i = 1, #manage do
|
||||
local elem = manage[i]
|
||||
|
||||
-- Check if the current element has a centerFont property
|
||||
if elem.centerFont then
|
||||
-- Adjust font size and re-center the text
|
||||
elem:fitFont(nil, nil, {scale = 2/3})
|
||||
elem:centerFont()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
gui.Events.OnResized(resizeFonts)
|
||||
|
||||
local completed_questions = 0
|
||||
local min_questions = 0
|
||||
local dd_count = 0
|
||||
local dd_enabled = false
|
||||
local applied_dd = false
|
||||
local board, question
|
||||
|
||||
function gui:cleanup()
|
||||
for i = #self.children, 1, -1 do
|
||||
self.children[i]:destroy()
|
||||
end
|
||||
self.children = {}
|
||||
completed_questions = completed_questions + 1
|
||||
end
|
||||
|
||||
local function pickUniqueIndices(t, count)
|
||||
assert(#t >= count, "Not enough elements to pick " .. count .. " unique items")
|
||||
|
||||
local indices = {}
|
||||
for i = 1, #t do indices[i] = i end
|
||||
|
||||
-- partial Fisher-Yates shuffle
|
||||
for i = 1, count do
|
||||
local j = math.random(i, #indices)
|
||||
indices[i], indices[j] = indices[j], indices[i]
|
||||
end
|
||||
|
||||
return unpack(indices, 1, count)
|
||||
end
|
||||
|
||||
local function pickFiltered(items, count)
|
||||
-- Filter to only elements whose text contains "$"
|
||||
local filtered = {}
|
||||
for _, item in ipairs(items) do
|
||||
if item.text:find("%$") then
|
||||
filtered[#filtered + 1] = item
|
||||
end
|
||||
end
|
||||
|
||||
-- Use pickUniqueIndices to select from filtered results
|
||||
local picks = { pickUniqueIndices(filtered, count) }
|
||||
local results = {}
|
||||
for _, idx in ipairs(picks) do
|
||||
results[#results + 1] = filtered[idx]
|
||||
end
|
||||
|
||||
return unpack(results)
|
||||
end
|
||||
|
||||
function applyDD()
|
||||
if not applied_dd and completed_questions > min_questions then
|
||||
local dd = 0
|
||||
local dd_list = {}
|
||||
local dds = {pickFiltered(board.children, dd_count)}
|
||||
for i,v in pairs(dds) do
|
||||
print(i,v)
|
||||
v.isDouble = true
|
||||
end
|
||||
applied_dd = true
|
||||
end
|
||||
end
|
||||
|
||||
local function buildBoard(frame, path)
|
||||
local data = loader:new(path)
|
||||
board, question, dailydouble = frame:newFrame(), frame:newFrame(), frame:newImageLabel("assets/images/double.jpg")
|
||||
index = data.index
|
||||
board:fullFrame()
|
||||
question:fullFrame()
|
||||
dailydouble:fullFrame()
|
||||
dailydouble.visible = false
|
||||
question.visible = false
|
||||
question.color = color.new("#060ce9")
|
||||
local tiers = index.settings.tiers or 5
|
||||
local start = index.settings.start or 100
|
||||
local inc = index.settings.increment or 100
|
||||
|
||||
if index.settings.dailyDouble and index.settings.dailyDouble.enabled then
|
||||
local dd = index.settings.dailyDouble
|
||||
dd_enabled = dd.enabled
|
||||
min_questions = dd.minQuestions
|
||||
dd_count = dd.count
|
||||
end
|
||||
for cat,v in pairs(index.categories) do
|
||||
local c
|
||||
if v.image then
|
||||
c = board:newImageLabel(v.image, 0, 0, 0, 0,(1/#index.categories)*(cat-1),0,1/#index.categories,1/(tiers+1))
|
||||
else
|
||||
c = board:newTextLabel(v.displayName or v.name,0,0,0,0,(1/#index.categories)*(cat-1),0,1/#index.categories,1/(tiers+1))
|
||||
c.align = gui.ALIGN_CENTER
|
||||
c.textColor = color.new("#ffffff")
|
||||
c.color = color.new("#060ce9")
|
||||
end
|
||||
|
||||
c.UUID = multi.generate_uuid7() -- Each otpion gets a unique UUID
|
||||
|
||||
img = c:newImageButton("assets/images/placeholder.jpg")
|
||||
img.visibility = 0
|
||||
|
||||
img:OnReleased(function(self)
|
||||
self.visible = false
|
||||
end)
|
||||
|
||||
img:fullFrame()
|
||||
table.insert(manage,c)
|
||||
for tier = 1,tiers do
|
||||
local t = board:newTextButton("$" .. start + inc*(tier-1),0,0,0,0,(1/#index.categories)*(cat-1),1/(tiers+1)*tier,(1/#index.categories),1/(tiers+1))
|
||||
t.textColor = color.new("#9b9024")
|
||||
t.align = gui.ALIGN_CENTER
|
||||
t.color = color.new("#060ce9")
|
||||
t.category = v.name
|
||||
t.index = tier
|
||||
t.price = start + inc*(tier-1)
|
||||
t:OnReleased(boardUpdater:newFunction(function(self)
|
||||
if self.text == "" or GetActivePlayer() == nil then return end
|
||||
if dd_enabled then
|
||||
applyDD() -- check and run DD if conditions meet
|
||||
end
|
||||
if index.categories[cat].questions == nil then fmt.Printf("Question not defined: File: %v Category: %v - %v\n",path,index.categories[cat].name,start + inc*(tier-1)) return end
|
||||
local q = index.categories[cat].questions[self.index]
|
||||
if q == nil then fmt.Printf("Question contains no data: File: %v Category: %v Tier: %v\n",path,index.categories[cat].name,start + inc*(tier-1)) return end
|
||||
self.textVisibility = 0
|
||||
local template = LoadTemplate(q.template, path)
|
||||
question.visible = true
|
||||
local player = GetActivePlayer()
|
||||
local tm
|
||||
local stop
|
||||
fmt.Printf("--------------------\nQuestion: %v \nAnswer: %v\n--------------------\n",q["title"],q["answer"])
|
||||
local mul = 1
|
||||
boardUpdater:newThread(function()
|
||||
if self.isDouble then
|
||||
mul = 2
|
||||
double:play()
|
||||
dailydouble.visible = true
|
||||
thread.hold(function()
|
||||
return not double:isPlaying()
|
||||
end)
|
||||
dailydouble.visible = false
|
||||
end
|
||||
if q["time-limit"] then
|
||||
tm = timer.startTimer({duration = q["time-limit"]})
|
||||
tm.OnStop(function()
|
||||
-- Make sound? Subtract if daily double
|
||||
if stop then return end
|
||||
timesup:play()
|
||||
end)
|
||||
end
|
||||
local finished = false
|
||||
template.index(question, q, function(ans)
|
||||
if finished then return end
|
||||
player = GetActivePlayer()
|
||||
if tm then
|
||||
tm:Cleanup()
|
||||
end
|
||||
stop = true
|
||||
if ans then
|
||||
player:Add(self.price*mul)
|
||||
finished = true
|
||||
question.visible = false
|
||||
question:cleanup()
|
||||
elseif ans == false then
|
||||
player:Add(-self.price*mul)
|
||||
player = GetNextPlayer()
|
||||
else
|
||||
finished = true
|
||||
question.visible = false
|
||||
question:cleanup()
|
||||
end -- nil is a valid option where you weren't right or wrong, you just skipped
|
||||
self.text = ""
|
||||
end)
|
||||
boardUpdater:newThread("QuestionUpdater",function()
|
||||
while true do
|
||||
template.update(dt)
|
||||
thread.yield()
|
||||
if self.text == "" then return end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end))
|
||||
table.insert(manage,t)
|
||||
end
|
||||
end
|
||||
resizeFonts()
|
||||
resizeFonts()
|
||||
end
|
||||
|
||||
local qUpdater = gui:getProcessor():newProcessor("question-updater")
|
||||
qUpdater.Start()
|
||||
|
||||
function LoadTemplate(name, path)
|
||||
|
||||
if love.filesystem.getInfo("templates/" .. name .. ".lua") then
|
||||
data = love.filesystem.read("templates/" .. name .. ".lua")
|
||||
elseif love.filesystem.getInfo(path .."/templates/" .. name .. ".lua") then
|
||||
data = love.filesystem.read(path .."/templates/" .. name .. ".lua")
|
||||
end
|
||||
|
||||
local template, err = loadstring(data)
|
||||
|
||||
if err ~= nil then
|
||||
error(err)
|
||||
end
|
||||
|
||||
local timer = function(wait, callback)
|
||||
multi:newAlarm(wait):OnRing(callback)
|
||||
end
|
||||
|
||||
local env = { -- lua built-ins except io/os code execution
|
||||
pairs=pairs,
|
||||
print=print,
|
||||
tostring=tostring,
|
||||
tonumber=tonumber,
|
||||
type=type,
|
||||
assert=assert,
|
||||
ipairs=ipairs,
|
||||
table=table,
|
||||
math=math,
|
||||
string=string,
|
||||
next=next,
|
||||
pcall=pcall,
|
||||
select=select,
|
||||
xpcall=xpcall,
|
||||
utf8=utf8,
|
||||
clock = require("socket").gettime,
|
||||
ALIGN_CENTER = gui.ALIGN_CENTER,
|
||||
ALIGN_LEFT = gui.ALIGN_LEFT,
|
||||
ALIGN_RIGHT = gui.ALIGN_RIGHT,
|
||||
ALIGN_JUSTIFY = gui.ALIGN_JUSTIFY,
|
||||
-- Global vars
|
||||
color = color,
|
||||
error = multi.error,
|
||||
theme = theme,
|
||||
gui = gui,
|
||||
timer = timer,
|
||||
-- love stuff
|
||||
newSource = love.audio.newSource
|
||||
}
|
||||
|
||||
env._G = env
|
||||
local isoTemplate = multi.isolateFunction(template, env)
|
||||
|
||||
return isoTemplate()
|
||||
end
|
||||
|
||||
return {
|
||||
buildBoard = buildBoard
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
function love.conf(t)
|
||||
t.identity = nil -- The name of the save directory (string)
|
||||
t.identity = "Jeopardy"
|
||||
t.version = "11.5" -- The LOVE version this game was made for (string)
|
||||
t.console = true -- Attach a console (boolean, Windows only)
|
||||
|
||||
t.window.title = "GuiManagerTest" -- The window title (string)
|
||||
t.window.title = "Jeopardy" -- The window title (string)
|
||||
t.window.icon = nil -- Filepath to an image to use as the window's icon (string)
|
||||
t.window.width = 1920 -- The window width (number)
|
||||
t.window.height = 1080 -- The window height (number)
|
||||
@@ -13,7 +13,7 @@ function love.conf(t)
|
||||
t.window.minheight = 1 -- Minimum window height if the window is resizable (number)
|
||||
t.window.fullscreen = false -- Enable fullscreen (boolean)
|
||||
t.window.fullscreentype = "desktop" -- Standard fullscreen or desktop fullscreen mode (string)
|
||||
t.window.vsync = false -- Enable vertical sync (boolean)
|
||||
t.window.vsync = true -- Enable vertical sync (boolean)
|
||||
t.window.fsaa = 4 -- The number of samples to use with multi-sampled antialiasing (number)
|
||||
t.window.display = 1 -- Index of the monitor to show the window in (number)
|
||||
t.window.highdpi = true -- Enable high-dpi mode for the window on a Retina display (boolean)
|
||||
@@ -29,7 +29,7 @@ function love.conf(t)
|
||||
t.modules.keyboard = true -- Enable the keyboard module (boolean)
|
||||
t.modules.math = true -- Enable the math module (boolean)
|
||||
t.modules.mouse = true -- Enable the mouse module (boolean)
|
||||
t.modules.physics = true -- Enable the physics module (boolean)
|
||||
t.modules.physics = false -- Enable the physics module (boolean)
|
||||
t.modules.sound = true -- Enable the sound module (boolean)
|
||||
t.modules.system = true -- Enable the system module (boolean)
|
||||
t.modules.timer = true -- Enable the timer module (boolean)
|
||||
|
||||
@@ -18,6 +18,8 @@ function loader:new(path_or_file)
|
||||
else
|
||||
local category = yaml.parse(link)
|
||||
c.index.categories[i].questions = category.questions
|
||||
c.index.categories[i].global = category.global or {}
|
||||
c.index.categories[i].cosmetics = category.cosmetics or {}
|
||||
end
|
||||
end
|
||||
return c
|
||||
|
||||
@@ -1,40 +1,48 @@
|
||||
local gui, color, theme, utils, board, yaml, loader, scoreUpdater
|
||||
|
||||
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")
|
||||
local gui = require("gui")
|
||||
local color = require("gui.core.color")
|
||||
local title = require("menus.title")
|
||||
local menu = require("gui.core.menus")
|
||||
|
||||
color.indexColor("bg","#2b348b")
|
||||
color.indexColor("tile_bg","#5459e4")
|
||||
color.indexColor("header_tile","#2a2e91")
|
||||
color.indexColor("status_font", "#e4b82a")
|
||||
color.indexColor("title_font","#b16d24")
|
||||
color.indexColor("question_bg","#363ac8")
|
||||
color.indexColor("tile_font","#ffffff")
|
||||
color.indexColor("header_font","#fef6eeda")
|
||||
|
||||
require("gui.addons")
|
||||
|
||||
title = require("menus.title")
|
||||
gui:setHotKey({"f11"})(function()
|
||||
fullscreen, fstype = love.window.getFullscreen()
|
||||
love.window.setFullscreen(not fullscreen, "desktop")
|
||||
end)
|
||||
|
||||
local old = multi.error
|
||||
|
||||
multi.error = function(...)
|
||||
old(...)
|
||||
os.exit()
|
||||
end
|
||||
|
||||
function love.load()
|
||||
love.filesystem.setIdentity("jeopardy")
|
||||
success = love.filesystem.createDirectory("")
|
||||
gui:cacheImage({"assets/images/checked.png","assets/images/unchecked.png","assets/images/speaker.png"})
|
||||
gui:setAspectSize(1920, 1080)
|
||||
gui.aspect_ratio = true
|
||||
|
||||
local bg = gui:newFrame()
|
||||
local bg = gui:newImageLabel("assets/images/background.png")
|
||||
bg:fullFrame()
|
||||
bg.color = color.new("#242f9b")
|
||||
|
||||
require("menus.menus").init(bg)
|
||||
menu.init(bg)
|
||||
|
||||
title:visible(true)
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
function love.update(dt)
|
||||
|
||||
@@ -5,13 +5,14 @@ local theme = require("gui.core.theme")
|
||||
local fmt = require("fmt")
|
||||
local timer = require("utils")
|
||||
local multi, thread = require("multi"):init()
|
||||
local menu = require("menus.menus")
|
||||
local menu = require("gui.core.menus")
|
||||
|
||||
local timesup = love.audio.newSource("assets/sounds/timesup.mp3", "static")
|
||||
local double = love.audio.newSource("assets/sounds/double.mp3", "static")
|
||||
|
||||
local boardUpdater = gui:getProcessor():newProcessor("board-updater")
|
||||
boardUpdater.Start()
|
||||
local scoreUpdater = gui:getProcessor():newProcessor("score-updater")
|
||||
local qUpdater = gui:getProcessor():newProcessor("question-updater")
|
||||
|
||||
local activePlayer
|
||||
local playerList = {}
|
||||
@@ -50,14 +51,6 @@ local dd_enabled = false
|
||||
local applied_dd = false
|
||||
local board, question
|
||||
|
||||
function gui:cleanup()
|
||||
for i = #self.children, 1, -1 do
|
||||
self.children[i]:destroy()
|
||||
end
|
||||
self.children = {}
|
||||
completed_questions = completed_questions + 1
|
||||
end
|
||||
|
||||
local function pickUniqueIndices(t, count)
|
||||
assert(#t >= count, "Not enough elements to pick " .. count .. " unique items")
|
||||
|
||||
@@ -98,22 +91,32 @@ function applyDD()
|
||||
local dd_list = {}
|
||||
local dds = {pickFiltered(board.children, dd_count)}
|
||||
for i,v in pairs(dds) do
|
||||
print(i,v)
|
||||
v.isDouble = true
|
||||
end
|
||||
applied_dd = true
|
||||
end
|
||||
end
|
||||
|
||||
local qUpdater = gui:getProcessor():newProcessor("question-updater")
|
||||
qUpdater.Start()
|
||||
|
||||
function LoadTemplate(name, path)
|
||||
|
||||
if love.filesystem.getInfo("templates/" .. name .. ".lua") then
|
||||
data = love.filesystem.read("templates/" .. name .. ".lua")
|
||||
elseif love.filesystem.getInfo(path .."/templates/" .. name .. ".lua") then
|
||||
if love.filesystem.getInfo(path .."/templates/" .. name .. ".lua") then
|
||||
data = love.filesystem.read(path .."/templates/" .. name .. ".lua")
|
||||
elseif love.filesystem.getInfo("templates/" .. name .. ".lua") then
|
||||
data = love.filesystem.read("templates/" .. name .. ".lua")
|
||||
else
|
||||
print("Error Loading Template: " .. name, path)
|
||||
gui:newMessageBox({
|
||||
title = "Error!",
|
||||
message = "Unable to load template: " .. name,
|
||||
buttons = { "Yes", "No" },
|
||||
onChoice = function(label, idx)
|
||||
if label == "Yes" then
|
||||
doCallback(selected)
|
||||
pickerWindow.visible = false
|
||||
pickerWindow:setTag("visual")
|
||||
end
|
||||
end,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
local template, err = loadstring(data)
|
||||
@@ -163,22 +166,96 @@ function LoadTemplate(name, path)
|
||||
return isoTemplate()
|
||||
end
|
||||
|
||||
local function manageCosmetics(frame, cosmetics)
|
||||
if cosmetics["bg-img"] then
|
||||
frame:setImage(cosmetics["bg-img"])
|
||||
else
|
||||
frame:setImage("assets/images/background.png")
|
||||
end
|
||||
if type(cosmetics.colors) == "table" then
|
||||
for i,v in pairs(cosmetics.colors) do
|
||||
color.reindexColor((i:gsub("-","_")),v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function gui:cleanup()
|
||||
for i = #self.children, 1, -1 do
|
||||
self.children[i]:destroy()
|
||||
end
|
||||
self.children = {}
|
||||
completed_questions = completed_questions + 1
|
||||
end
|
||||
|
||||
local reset = boardUpdater:newConnection()
|
||||
|
||||
local default_text = "Pick a Category"
|
||||
|
||||
function Menu(frame, path)
|
||||
local qframe = frame:newFrame(0, 0, 0, 0, .2, .05, .75, .9)
|
||||
qframe.color = color.new("#060ee9")
|
||||
local scoreboard = ScoreBoard(frame, 0, 0, 0, 0, .015, .05, .170, .9)
|
||||
if path:match(".zip") then
|
||||
-- local basename = path:match("([^/\\]+)$")
|
||||
print(path)
|
||||
local success = love.filesystem.mount(path, "quiz", true)
|
||||
if not success then
|
||||
gui:newMessageBox({
|
||||
title = "Return to the main menu?",
|
||||
message = "Couldn't load file: " .. path,
|
||||
buttons = { "Return", "Quit" },
|
||||
onChoice = function(label, idx)
|
||||
if label == "Return" then
|
||||
return menu.getMenu("title"):visible(true)
|
||||
else
|
||||
os.exit()
|
||||
end
|
||||
end,
|
||||
})
|
||||
return
|
||||
end
|
||||
path = "quiz"
|
||||
end
|
||||
|
||||
-- Start the processors now
|
||||
boardUpdater.Start()
|
||||
qUpdater.Start()
|
||||
scoreUpdater.Start()
|
||||
|
||||
local scoreboard = ScoreBoard(frame, 0, 0, 0, 0, .06, .1, .170, .8)
|
||||
|
||||
local qframe = frame:newFrame(0, 0, 0, 0, .24, .1, .70, .8)
|
||||
|
||||
local label = frame:newTextLabel(default_text, 0, 10, 0, -20, .29, 0, .6, .1)
|
||||
label.visibility = .85
|
||||
label.drawBorder = false
|
||||
label.align = gui.ALIGN_CENTER
|
||||
label.color = color.bg
|
||||
label.textColor = color.status_font
|
||||
label:setRoundness(20,20,60)
|
||||
|
||||
boardUpdater:newThread(function()
|
||||
local test = function()
|
||||
return label.text ~= ""
|
||||
end
|
||||
while true do
|
||||
thread.hold(test)
|
||||
label:centerFont()
|
||||
label:fitFont(nil, nil, {scale = 2/3})
|
||||
end
|
||||
end)
|
||||
|
||||
local data = loader:new(path)
|
||||
board, question, dailydouble = qframe:newFrame(), qframe:newFrame(), qframe:newImageLabel("assets/images/double.jpg")
|
||||
index = data.index
|
||||
|
||||
local cosmetics = index.cosmetics or {}
|
||||
manageCosmetics(frame, cosmetics)
|
||||
|
||||
board:fullFrame()
|
||||
question:fullFrame()
|
||||
dailydouble:fullFrame()
|
||||
|
||||
dailydouble.visible = false
|
||||
question.visible = false
|
||||
question.color = color.new("#060ce9")
|
||||
question.color = color.question_bg
|
||||
|
||||
local tiers = index.settings.tiers or 5
|
||||
local start = index.settings.start or 100
|
||||
@@ -190,6 +267,29 @@ function Menu(frame, path)
|
||||
min_questions = dd.minQuestions
|
||||
dd_count = dd.count
|
||||
end
|
||||
|
||||
local autoreveal = false
|
||||
if index.dev and index.dev.enabled then
|
||||
if index.dev["auto-reveal"] then
|
||||
autoreveal = true
|
||||
end
|
||||
if type(index.dev.players) == "table" then
|
||||
for i,v in ipairs(index.dev.players) do
|
||||
if type(v) == "string" then
|
||||
scoreboard:AddPlayer(v, 0)
|
||||
elseif type(v) == "table" then
|
||||
scoreboard:AddPlayer(v.name, v.score, v.icon)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reset(function()
|
||||
question:cleanup()
|
||||
manageCosmetics(frame, cosmetics, true)
|
||||
label.text = default_text
|
||||
end)
|
||||
|
||||
for cat,v in pairs(index.categories) do
|
||||
local c
|
||||
if v.image then
|
||||
@@ -197,26 +297,30 @@ function Menu(frame, path)
|
||||
else
|
||||
c = board:newTextLabel(v.displayName or v.name,0,0,0,0,(1/#index.categories)*(cat-1),0,1/#index.categories,1/(tiers+1))
|
||||
c.align = gui.ALIGN_CENTER
|
||||
c.textColor = color.new("#ffffff")
|
||||
c.color = color.new("#060ce9")
|
||||
c.textColor = color.header_font
|
||||
c.color = color.header_tile
|
||||
end
|
||||
|
||||
c.UUID = multi.generate_uuid7() -- Each otpion gets a unique UUID
|
||||
|
||||
img = c:newImageButton("assets/images/placeholder.jpg")
|
||||
img.visibility = 0
|
||||
if not autoreveal then
|
||||
img = c:newImageButton("assets/images/placeholder.jpg")
|
||||
img.visibility = 0
|
||||
|
||||
img:OnReleased(function(self)
|
||||
self.visible = false
|
||||
end)
|
||||
img:OnReleased(function(self)
|
||||
self.visible = false
|
||||
end)
|
||||
|
||||
img:fullFrame()
|
||||
end
|
||||
|
||||
img:fullFrame()
|
||||
table.insert(manage,c)
|
||||
|
||||
for tier = 1,tiers do
|
||||
local t = board:newTextButton("$" .. start + inc*(tier-1),0,0,0,0,(1/#index.categories)*(cat-1),1/(tiers+1)*tier,(1/#index.categories),1/(tiers+1))
|
||||
t.textColor = color.new("#9b9024")
|
||||
t.textColor = color.tile_font
|
||||
t.align = gui.ALIGN_CENTER
|
||||
t.color = color.new("#060ce9")
|
||||
t.color = color.tile_bg
|
||||
t.category = v.name
|
||||
t.index = tier
|
||||
t.price = start + inc*(tier-1)
|
||||
@@ -226,8 +330,22 @@ function Menu(frame, path)
|
||||
applyDD() -- check and run DD if conditions meet
|
||||
end
|
||||
if index.categories[cat].questions == nil then fmt.Printf("Question not defined: File: %v Category: %v - %v\n",path,index.categories[cat].name,start + inc*(tier-1)) return end
|
||||
local globals = index.categories[cat].global
|
||||
if not globals then
|
||||
globals = {}
|
||||
end
|
||||
local q = index.categories[cat].questions[self.index]
|
||||
if not q then return end
|
||||
label.text = t.category .. ": " .. t.price
|
||||
local mt = debug.getmetatable(q)
|
||||
if mt then
|
||||
mt.__metatable = nil
|
||||
end
|
||||
setmetatable(q, {__index = globals})
|
||||
if q == nil then fmt.Printf("Question contains no data: File: %v Category: %v Tier: %v\n",path,index.categories[cat].name,start + inc*(tier-1)) return end
|
||||
if q.cosmetics then
|
||||
manageCosmetics(frame, q.cosmetics)
|
||||
end
|
||||
self.textVisibility = 0
|
||||
local template = LoadTemplate(q.template, path)
|
||||
question.visible = true
|
||||
@@ -255,7 +373,8 @@ function Menu(frame, path)
|
||||
end)
|
||||
end
|
||||
local finished = false
|
||||
template.index(question, q, function(ans)
|
||||
template.index(question, q, function(ans, m)
|
||||
local m = m or 1
|
||||
if finished then return end
|
||||
player = GetActivePlayer()
|
||||
if tm then
|
||||
@@ -263,17 +382,17 @@ function Menu(frame, path)
|
||||
end
|
||||
stop = true
|
||||
if ans then
|
||||
player:Add(self.price*mul)
|
||||
player:Add((self.price*mul)*m)
|
||||
finished = true
|
||||
question.visible = false
|
||||
question:cleanup()
|
||||
reset:Fire()
|
||||
elseif ans == false then
|
||||
player:Add(-self.price*mul)
|
||||
player = GetNextPlayer()
|
||||
else
|
||||
finished = true
|
||||
question.visible = false
|
||||
question:cleanup()
|
||||
reset:Fire()
|
||||
end -- nil is a valid option where you weren't right or wrong, you just skipped
|
||||
self.text = ""
|
||||
end)
|
||||
@@ -296,8 +415,7 @@ function Menu(frame, path)
|
||||
return background
|
||||
end
|
||||
|
||||
scoreUpdater = gui:getProcessor():newProcessor("score-updater")
|
||||
scoreUpdater.Start()
|
||||
|
||||
|
||||
function GetActivePlayer()
|
||||
if not activePlayer then return end
|
||||
@@ -407,7 +525,7 @@ function ScoreBoard(frame, x, y, w, h, sx, sy, sw, sh)
|
||||
function scoreboard:AddPlayer(name, score, icon)
|
||||
local player = {
|
||||
Name = name,
|
||||
Score = score,
|
||||
Score = score or 0,
|
||||
Icon = icon,
|
||||
UUID = multi.generate_uuid7(),
|
||||
Add = function(self, amt)
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
local gui = require("gui")
|
||||
local menu = {}
|
||||
local menus = {}
|
||||
local frame
|
||||
local menuRef = {}
|
||||
local mt = {
|
||||
__index = menuRef
|
||||
}
|
||||
|
||||
function menu.registerMenu(name, menu, delete)
|
||||
local c = {}
|
||||
c.MenuFunc = menu
|
||||
c.Delete = delete
|
||||
setmetatable(c, mt)
|
||||
menus[name] = c
|
||||
return c
|
||||
end
|
||||
|
||||
function menu.getMenu(name)
|
||||
return menus[name] or nil, "Menu ".. name .. " not found."
|
||||
end
|
||||
|
||||
function menu.init(f)
|
||||
frame = f
|
||||
end
|
||||
|
||||
function menu.hideMenus()
|
||||
for k,v in pairs(menus) do
|
||||
if v.frame then
|
||||
if v.Delete then
|
||||
v.frame:destroy()
|
||||
menus[k] = nil
|
||||
else
|
||||
v.frame.visible = false
|
||||
v.frame.active = false
|
||||
v.frame:setParent(gui.virtual)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function menuRef:visible(value, ...)
|
||||
menu.hideMenus()
|
||||
if self.__menuConfigured and self.frame then
|
||||
self.frame.visible = true
|
||||
self.frame.active = true
|
||||
self.frame:setParent(frame)
|
||||
else
|
||||
self.__menuConfigured = true
|
||||
self.frame = self.MenuFunc(frame, ...)
|
||||
end
|
||||
end
|
||||
|
||||
return menu
|
||||
@@ -1,6 +1,6 @@
|
||||
local gui = require("gui")
|
||||
local color = require("gui.core.color")
|
||||
local menu = require("menus.menus")
|
||||
local menu = require("gui.core.menus")
|
||||
-- local proc = gui:getProcessor():newProcessor("settings")
|
||||
|
||||
function Menu(frame)
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
local gui = require("gui")
|
||||
local color = require("gui.core.color")
|
||||
local menu = require("menus.menus")
|
||||
local menu = require("gui.core.menus")
|
||||
local proc = gui:getProcessor():newProcessor("main-title")
|
||||
|
||||
local APP_VERSION = love.filesystem.read("version.txt")
|
||||
|
||||
local board = require("menus.board")
|
||||
|
||||
function Menu(frame)
|
||||
local background = frame:newImageLabel("assets/images/background.jpg")
|
||||
background:fullFrame()
|
||||
local title = frame:newTextLabel("Jeopardy",0,0,0,0,0,.1,1,.25)
|
||||
local title = background:newTextLabel("Jeopardy",0,0,0,0,0,.1,1,.25)
|
||||
title:setFont("assets/fonts/gyparody.ttf",300)
|
||||
|
||||
title:setShader(gui.SHADERS.vignette,{
|
||||
@@ -18,7 +20,7 @@ function Menu(frame)
|
||||
|
||||
title.align = gui.ALIGN_CENTER
|
||||
title.visibility = 0
|
||||
title.textColor = color.new("#b16d24")
|
||||
title.textColor = color.title_font
|
||||
title.drawBorder = false
|
||||
|
||||
proc:newThread(function()
|
||||
@@ -62,10 +64,44 @@ function Menu(frame)
|
||||
},play,settings,quit)
|
||||
|
||||
play:OnReleased(function()
|
||||
background.visible = false
|
||||
menu.getMenu("board"):visible(true,"anime")
|
||||
if love.filesystem.getInfo("quiz") then
|
||||
menu.getMenu("board"):visible(true, "quiz")
|
||||
return
|
||||
else
|
||||
gui:newFilePicker("File picker test",nil, {".zip"}, function(file)
|
||||
menu.getMenu("board"):visible(true, file:gsub("\\","/"):gsub(love.filesystem.getSaveDirectory(),""):sub(2,-1))
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
quit:OnReleased(function()
|
||||
local f = frame:newFrame()
|
||||
f:fullFrame()
|
||||
f.visibility = .8
|
||||
f.color = color.black
|
||||
local cm = menu.getCurrentMenu()
|
||||
cm:setTag("visual")
|
||||
quit:setShader()
|
||||
gui:newMessageBox({
|
||||
title = "Confirm",
|
||||
message = "Are you sure you want to exit the game?",
|
||||
buttons = { "Yes", "No" },
|
||||
onChoice = function(label, idx)
|
||||
if label == "Yes" then os.exit() end
|
||||
cm:removeTag("visual")
|
||||
f:destroy()
|
||||
end,
|
||||
})
|
||||
end)
|
||||
|
||||
local version = frame:newTextLabel("Version: " .. APP_VERSION, -150,-30, 150, 30, 1, 1)
|
||||
thread:newThread(function()
|
||||
thread.skip(2)
|
||||
version:fitFont()
|
||||
end)
|
||||
version.textColor = color.new("#b16d24")
|
||||
version.visibility = 0
|
||||
|
||||
return background
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
:: Read the first line of version.txt and assign it to the MY_VERSION variable
|
||||
for /f "usebackq delims=" %%i in ("version.txt") do (
|
||||
set "userInput=%%i"
|
||||
goto :done
|
||||
)
|
||||
|
||||
:done
|
||||
"C:\Program Files\7-Zip\7z.exe" a -tzip game.love templates version.txt assets multi\integration\loveManager multi\integration\sharedExtensions multi\init.lua gui menus conf.lua fmt.lua loader.lua main.lua utils.lua yaml.lua
|
||||
rd /s /q "bin\%userInput%"
|
||||
if not exist "bin\%userInput%" mkdir "bin\%userInput%"
|
||||
copy /b love\love.exe + game.love "bin\%userInput%\Jeopardy.exe"
|
||||
copy /b love\love.dll "bin\%userInput%\love.dll"
|
||||
copy /b lovel\lua51.dll "bin\%userInput%\lua51.dll"
|
||||
copy /b love\mpg123.dll "bin\%userInput%\mpg123.dll"
|
||||
copy /b love\msvcp120.dll "bin\%userInput%\msvcp120.dll"
|
||||
copy /b love\msvcr120.dll "bin\%userInput%\msvcr120.dll"
|
||||
copy /b love\OpenAL32.dll "bin\%userInput%\OpenAL32.dll"
|
||||
copy /b love\SDL2.dll "bin\%userInput%\SDL2.dll"
|
||||
copy /b love\license.txt "bin\%userInput%\license.txt"
|
||||
|
Before Width: | Height: | Size: 29 KiB |
@@ -9,8 +9,8 @@ local function index(window, q, callback)
|
||||
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")
|
||||
label.borderColor = color.new("#060ce9")
|
||||
label.color = color.new("#363ac8")
|
||||
label.borderColor = color.new("#363ac8")
|
||||
|
||||
if not q.imageA or q.imageA == "" then
|
||||
error("Missing 'imageA' field for question!")
|
||||
|
||||
@@ -21,10 +21,10 @@ local function index(window, q, callback)
|
||||
label = window:newTextLabel(" " ..q.title.. " ",noOf(0,0,1,.3))
|
||||
label.align = ALIGN_CENTER
|
||||
label.textColor = color.white
|
||||
label.color = color.new("#060ce9")
|
||||
label.color = color.new("#363ac8")
|
||||
label:setFont(50)
|
||||
choices = window:newFrame(noOf(0,.3,1,.7))
|
||||
choices.color = color.new("#060ce9")
|
||||
choices.color = color.new("#363ac8")
|
||||
|
||||
function choices:newChoice(choice, i)
|
||||
local c = choices:newFrame(noOf(.25,(i-1)/#q.choices,.5,1/#q.choices))
|
||||
|
||||
@@ -15,7 +15,7 @@ local function index(window, q, callback)
|
||||
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")
|
||||
label.color = color.new("#363ac8")
|
||||
if not q.image or q.image == "" then
|
||||
error("Missing 'image' field for question!")
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ local function index(window, q, callback)
|
||||
label.align = ALIGN_CENTER
|
||||
label:fullFrame()
|
||||
label.textColor = color.white
|
||||
label.color = color.new("#060ce9")
|
||||
label.color = color.new("#363ac8")
|
||||
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)
|
||||
|
||||
@@ -20,7 +20,7 @@ local function index(window, q, callback)
|
||||
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")
|
||||
label.color = color.new("#363ac8")
|
||||
imageHolder = frame:newImageButton("assets/images/speaker.png",0,0,0,0,0,0,.3,.4)
|
||||
imageHolder:setAspectSize(imageHolder.imageWidth,imageHolder.imageHeight)
|
||||
imageHolder:centerX(true)
|
||||
|
||||
@@ -20,7 +20,7 @@ local function index(window, q, callback)
|
||||
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")
|
||||
label.color = color.new("#363ac8")
|
||||
local holder = frame:newFrame(-300, -200, 600, 400, .5, .5)
|
||||
holder:centerX(true)
|
||||
holder:centerY(true)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1.0.1
|
||||