From fc0bd44a1c77f3263e4a88369e325a484ae46f15 Mon Sep 17 00:00:00 2001 From: wan-may Date: Fri, 8 Sep 2023 23:05:26 -0300 Subject: [PATCH] Add font. New menu abstraction. Tweak colours. Placeholder buttons. --- src/client/assets/CinzelDecorative-Black.otf | Bin 0 -> 73920 bytes src/client/assets/OFL.txt | 92 +++++++++ src/client/assets/strings.lua | 14 +- src/client/scene.lua | 27 ++- src/client/ui/button.lua | 53 +++-- src/client/ui/mainmenu.lua | 48 +++++ src/client/ui/menu.lua | 206 ++++++++----------- src/client/ui/options.lua | 205 ++++-------------- src/main.lua | 8 +- 9 files changed, 337 insertions(+), 316 deletions(-) create mode 100644 src/client/assets/CinzelDecorative-Black.otf create mode 100644 src/client/assets/OFL.txt create mode 100644 src/client/ui/mainmenu.lua diff --git a/src/client/assets/CinzelDecorative-Black.otf b/src/client/assets/CinzelDecorative-Black.otf new file mode 100644 index 0000000000000000000000000000000000000000..e4aeef4d98bedfec91a7ce6700ac7d3ff74d0499 GIT binary patch literal 73920 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 literal 0 HcmV?d00001 diff --git a/src/client/assets/OFL.txt b/src/client/assets/OFL.txt new file mode 100644 index 0000000..0f1e2d1 --- /dev/null +++ b/src/client/assets/OFL.txt @@ -0,0 +1,92 @@ +Copyright (c) 2012 Natanael Gama (info@ndiscovered.com), with Reserved Font Name 'Cinzel' +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/client/assets/strings.lua b/src/client/assets/strings.lua index dc6ef64..ee18cf0 100644 --- a/src/client/assets/strings.lua +++ b/src/client/assets/strings.lua @@ -1,11 +1,11 @@ return setmetatable({ - ["newgame_button"] = "New Game", - ["join_button"] = "Join Server", + ["newgame_button"] = "New game", + ["join_button"] = "Join server", ["quit_button"] = "Quit", ["option_button"] = "Settings", - ["mainmenu_button"] = "Main Menu", - ["option_name"] = "Player Name", - ["option_pron"] = "Player Pronouns", - ["option_tint"] = "Player Colour", - ["option_keybinds"] = "Edit Keybindings", + ["mainmenu_button"] = "Main menu", + ["option_name"] = "Player name", + ["option_pron"] = "Player pronouns", + ["option_tint"] = "Player colour", + ["option_keybinds"] = "Edit keybindings", }, {__index = function( t, k ) return k end } ) \ No newline at end of file diff --git a/src/client/scene.lua b/src/client/scene.lua index c14f581..030d208 100644 --- a/src/client/scene.lua +++ b/src/client/scene.lua @@ -1,23 +1,36 @@ local scene = {} local love = assert( love ) + +local callbacks = { + draw = true, + mousepressed = true, + mousemoved = true, + keypressed = true, + update = true, + resize = true, +} + local mt = {} -local function loadScene( scene, params ) - print( "Loading Scene:", scene.name ) - for k, v in pairs( scene ) do - love[k] = v +print( 'scene', scene ) + +function scene.loadScene( scen, params ) + print( "Loading Scene:", scen.name ) + for k, v in pairs( callbacks ) do + if not scen[k] then print( "Warning: scene missing callback.", scen.name, k ) end + love[k] = scen[k] or love[k] end - scene.onLoad( params ) + scen:onLoad( params ) end local function newScene( scenes, name, t ) t.name = t.name or name print( "Adding Scene:", t.name ) - setmetatable( t, { __call = function() return loadScene( t ) end } ) + setmetatable( t, { __call = function() return scene.loadScene( t ) end } ) rawset( scenes, name, t ) end return setmetatable( scene, - {__call = loadScene, + {__call = scene.loadScene, __newindex = newScene } ) \ No newline at end of file diff --git a/src/client/ui/button.lua b/src/client/ui/button.lua index b142974..b130d5a 100644 --- a/src/client/ui/button.lua +++ b/src/client/ui/button.lua @@ -1,21 +1,34 @@ -local button = {} -local lg = assert( love.graphics ) -function button:new( t, x, y, w, h, text, color, callback ) - --print( t.x, t.y, t.w, t.h, t.text, t.color, t.callback ) - return setmetatable( t or - { - x = 0, y = 0, - w = 100, h = 100, - text = text, color = color, - callback = callback, - selected = false - }, - { - __index = button, - __call = t.callback or callback - } - ) +local lg = assert( love.graphics ) +local button = { + h = lg.getFont():getHeight() + 12, + y = 0, + x = 0, + w = 100, + space = 15, +} +local mt = { __index = button } + +function button:new( t ) + t = t or {} + + if t.y then button.y = t.y end + if t.h then button.h = t.h end + if t.w then button.w = t.w end + if t.x then button.x = t.x end + + t.x = t.x or button.x + t.y = t.y or button.y + t.w = t.w or button.w + t.h = t.h or button.h + t.text = t.text or "" + t.color = t.color or { 0.5, 0.5, 0.5, 0.5 } + t.callback = t.callback or function() print( "Clicked button:", t.text ) end + t.selected = t.selected or false + + button.y = button.y + t.h + button.space + + return setmetatable( t, mt ) end function button:contains( x, y ) @@ -33,8 +46,10 @@ function button:draw( ) lg.rectangle( "fill", self.x + 3, self.y + 3, self.w - 6, self.h - 6, 10 ) end -lg.setColor( 0, 0, 0, 0.7 ) - lg.print( self.text, self.x + 15, self.y + 10 ) + lg.setColor( 0, 0, 0, 0.8 ) + lg.print( self.text, self.x + 15, self.y + 6) + lg.setColor( 0, 0, 0, 0.2 ) + lg.print( self.text, self.x + 18, self.y + 8) end return setmetatable( button, { __call = button.new } ) \ No newline at end of file diff --git a/src/client/ui/mainmenu.lua b/src/client/ui/mainmenu.lua new file mode 100644 index 0000000..0c347a1 --- /dev/null +++ b/src/client/ui/mainmenu.lua @@ -0,0 +1,48 @@ +local lg = assert( love.graphics ) +local love = assert( love ) +local scene = assert( require 'client.scene' ) +local strings = assert( require 'client.assets.strings' ) +local button = assert( require 'client.ui.button' ) +local menu = assert( require 'client.ui.menu' ) + +return menu.new( + "mainmenu", + + { + + button{ + x = 15, w = lg.getWidth(), y = 115, + text = strings.newgame_button, + color = { 0.6, 0.6, 0.6, 0.9 }, + callback = function() return scene.game() end }, + + button{ + text = strings.join_button, + color = { 0.6, 0.6, 0.6, 0.9 }, + callback = function() return scene.browser() end }, + + button{ + text = strings.option_button, + color = { 0.6, 0.6, 0.6, 0.9 }, + callback = function() return scene.options() end }, + + button{ + text = strings.quit_button, + color = { 0.6, 0.6, 0.6, 0.9 }, + callback = love.event.quit }, + + }, + + lg.newMesh{ + { 0, 0, 0, 0, 1, 1, 1, 0.01 }, + { 1, 0, 1, 0, 1, 1, 1, 0.1 }, + { 1, 1, 1, 1, 0, 0, 0, 0.1 }, + { 0, 1, 0, 1, 0, 0, 0, 0.01 }, + }, + + lg.newMesh{ + { 0, 0, 0, 0, 0.4, 0.05, 0.0, 0.1 }, + { 1, 0, 1, 0, 0.8, 0.3, 0.1, 0.8 }, + { 1, 1, 1, 1, 0.7, 0.4, 0.1, 0.8 }, + { 0, 1, 0, 1, 0.4, 0.05, 0.05, 0.1 }, + } ) \ No newline at end of file diff --git a/src/client/ui/menu.lua b/src/client/ui/menu.lua index c47eb9d..9615458 100644 --- a/src/client/ui/menu.lua +++ b/src/client/ui/menu.lua @@ -1,74 +1,36 @@ -local lg = assert( love.graphics ) local love = assert( love ) +local lg = assert( love.graphics ) local scene = assert( require 'client.scene' ) -local strings = assert( require 'client.assets.strings' ) -local button = assert( require 'client.ui.button' ) +print( 'scene', scene ) local menu = {} -local t = 0 -local wWidth = 800 -local wHeight = 600 +--Static variables. +local selectedButtonIdx +local canvas +local wWidth, wHeight +local currentMenu -local selectedButtonIdx = nil +function menu.new( name, buttons, fg, bg ) + local t = { buttons = buttons, fg = fg, bg = bg } + scene[name] = t + print( 'scene', scene ) + getmetatable( t ).__index = menu + return t +end -local canvas = lg.newCanvas() -local buttons = - { - button{ - x = 15, w = 400, h = 50, - y = 115, - text = strings.newgame_button, - color = { 0.3, 0.2, 0.9, 0.5 }, - callback = function() return scene.game() end }, - - button{ - x = 15, w = 400, h = 50, - y = 115 + 55, - text = strings.join_button, - color = { 0.3, 0.2, 0.8, 0.5 }, - callback = function() return scene.browser() end }, - - button{ - x = 15, w = 400, h = 50, - y = 115 + 55 * 2, - text = strings.option_button, - color = { 0.3, 0.2, 0.9, 0.5 }, - callback = function() return scene.options() end }, - - button{ - x = 15, w = 400, h = 50, - y = 115 + 55 * 3, - text = strings.quit_button, - color = { 0.3, 0.2, 1.0, 0.5 }, - callback = love.event.quit }, - } +function menu:onLoad() + print( 'loading:', self.name ) + currentMenu = self + return menu.resize( lg.getDimensions() ) +end -local gradientQuad = lg.newMesh{ - { - -- top-left corner (red-tinted) - 0, 0, -- position of the vertex - 0, 0, -- texture coordinate at the vertex position - 0.4, 0.1, 0.4, 0.0 -- color of the vertex - }, - { - -- top-right corner (green-tinted) - 1, 0, - 1, 0, -- texture coordinates are in the range of [0, 1] - 0.8, 0.3, 0.1, 1.0 - }, - { - -- bottom-right corner (blue-tinted) - 1, 1, - 1, 1, - 0.7, 0.4, 0.1, 1.0 - }, - { - -- bottom-left corner (yellow-tinted) - 0, 1, - 0, 1, - 0.4, 0.15, 0.3, 0.0 - }, - } +function menu.update( dt ) end + +function menu.resize( w, h ) + wWidth, wHeight = w, h + canvas = lg.newCanvas() + return currentMenu:paint() +end function menu.draw() lg.setCanvas() @@ -76,89 +38,101 @@ function menu.draw() lg.draw( canvas ) end -function menu.paint() - lg.setCanvas( canvas ) - - --bg - lg.setColor( 0.8, 0.6, 0.3, 1 ) - lg.rectangle( "fill", 0, 0, wWidth, wHeight ) - - --buttons - for id, button in pairs( buttons ) do button:draw( ) end - - --gradient - lg.setColor( 1, 1, 1, 1 ) - lg.draw( gradientQuad, 0, 0, 0, wWidth, wHeight ) - lg.setCanvas() -end - -function menu.onLoad() - lg.setNewFont( 28 ) - return menu.resize( lg.getDimensions() ) -end - -function menu.update( dt ) - t = t + dt -end - -function menu.resize( w, h ) - wWidth, wHeight = w, h - canvas = lg.newCanvas() - for id, uiButton in pairs( buttons ) do - uiButton.w = wWidth - end - menu.paint() -end - function menu.mousemoved( x, y, dx, dy, istouch ) - if selectedButtonIdx then - buttons[selectedButtonIdx].selected = false - selectedButtonIdx = nil - end + if not currentMenu then return end + local buttons = currentMenu.buttons + + local selectedButton = buttons[selectedButtonIdx or 0] for id, menuButton in ipairs( buttons ) do if menuButton:contains( x, y ) then + if selectedButton then selectedButton.selected = false end menuButton.selected = true selectedButtonIdx = id - return menu.paint() + if menuButton ~= selectedButton then + return currentMenu:paint() + else return end end end + + --deselect button + if selectedButton then + selectedButtonIdx = nil + selectedButton.selected = false + return currentMenu:paint() + end end + function menu.mousepressed( x, y, button, istouch, presses ) - if not selectedButtonIdx then return end - local uiButton = buttons[selectedButtonIdx] - if uiButton:contains( x, y ) then return uiButton() end - return menu.paint() + + if not selectedButtonIdx and currentMenu then return end + local uiButton = currentMenu.buttons[selectedButtonIdx] + if uiButton:contains( x, y ) then + selectedButtonIdx = nil + uiButton.selected = false + return uiButton:callback() + end + return currentMenu:paint() end function menu.keypressed( key, code, isrepeat ) + assert( currentMenu ) + if code == "escape" then return love.event.quit() end + local buttons = currentMenu.buttons + if code == "return" and selectedButtonIdx then - return buttons[selectedButtonIdx]() + local button = buttons[selectedButtonIdx] + selectedButtonIdx = nil + button.selected = false + return button:callback() end - + if code == "down" or code == "tab" or code == "up" then local sbi = (selectedButtonIdx or 1) buttons[sbi].selected = false - + --Increment / decrement sbi = sbi + ((code == "up") and -1 or 1) if sbi > #buttons then sbi = 1 end if sbi < 1 then sbi = #buttons end - + --Assign - print( "selecting button: ", sbi ) selectedButtonIdx = sbi buttons[selectedButtonIdx].selected = true end - - - return menu.paint() + + + return currentMenu:paint() end -scene.mainmenu = menu +function menu:paint() + lg.setCanvas( canvas ) + + --bg + lg.setColor( 1, 1, 1, 1 ) + lg.draw( self.bg, 0, 0, 0, wWidth, wHeight ) + + --buttons + for i = #self.buttons, 1, -1 do self.buttons[i]:draw( ) end + + --gradient + lg.setColor( 1, 1, 1, 1 ) + local r = math.random + local v = r() * 0.4 + 0.6 + + local fg = self.fg + fg:setVertexAttribute( 2, 3, v * (0.7 + 0.2 * r()), v * (0.1 + 0.4 * r()), v * (0.1 * r()), 1 ) + fg:setVertexAttribute( 1, 3, 1 - v, 0, 0, 0.1 * (1 - v) ) + fg:setVertexAttribute( 4, 3, 1 - v, 0, 0, 0.1 * (1 - v) ) + fg:setVertexAttribute( 3, 3, v * (0.7 + 0.2 * r()), v * (0.1 + 0.4 * r()), v * (0.1 * r()), 1 ) + lg.draw( fg, 0, 0, 0, wWidth, wHeight ) + lg.setCanvas() +end + + return menu \ No newline at end of file diff --git a/src/client/ui/options.lua b/src/client/ui/options.lua index 4a4bb11..dfd2602 100644 --- a/src/client/ui/options.lua +++ b/src/client/ui/options.lua @@ -3,179 +3,56 @@ local love = assert( love ) local scene = assert( require 'client.scene' ) local strings = assert( require 'client.assets.strings' ) local button = assert( require 'client.ui.button' ) -local textinput = assert( require 'client.ui.textinput' ) -local menu = {} +local menu = assert( require 'client.ui.menu' ) -local t = 0 -local wWidth = 800 -local wHeight = 600 -local canvas = lg.newCanvas() +return menu.new( + "options", -local selectedButtonIdx = nil + { -local gradientQuad = lg.newMesh{ - { 0, 0, 0, 0, 0.4, 0.1, 0.4, 0.0 }, - { 1, 0, 1, 0, 0.8, 0.3, 0.1, 1.0 }, - { 1, 1, 1, 1, 0.7, 0.4, 0.1, 1.0 }, - { 0, 1, 0, 1, 0.4, 0.1, 0.3, 0.0 }, -} + button{ + x = 15, y = 115, w = 800, + text = strings.mainmenu_button, + color = { 0.6, 0.6, 0.6, 0.8 }, + callback = function() return scene.mainmenu() end }, -local buttons = -{ - - button{ - x = 15, w = 400, h = 50, - y = 115, - text = strings.mainmenu_button, - color = { 0.5, 0.2, 0.8, 0.6 }, - callback = function() return scene.mainmenu() end }, - - button{ - x = 15, w = 400, h = 50, - y = 115 + 55, - option = 'name', - text = strings.option_name, - color = { 0.5, 0.2, 0.2, 0.6 }, - callback = menu.textOption }, + button{ + option = 'name', + text = strings.option_name, + color = { 0.6, 0.6, 0.6, 0.8 }, + callback = menu.textOption }, - button{ - x = 15, w = 400, h = 50, - y = 115 + 55 * 2, - option = 'pronoun', - text = strings.option_pron, - color = { 0.5, 0.2, 0.4, 0.6 }, - callback = menu.textOption }, + button{ + option = 'pronoun', + text = strings.option_pron, + color = { 0.6, 0.6, 0.6, 0.8 }, + callback = menu.textOption }, - button{ - x = 15, w = 400, h = 50, - y = 115 + 55 * 3, - option = 'colour', - text = strings.option_tint, - color = { 0.5, 0.2, 0.6, 0.6 }, - callback = menu.colourOption }, + button{ + option = 'colour', + text = strings.option_tint, + color = { 0.6, 0.6, 0.6, 0.8 }, + callback = menu.colourOption }, - - button{ - x = 15, w = 400, h = 50, - y = 115 + 55 * 4, - option = 'keybinds', - text = strings.keybinding_button, - color = { 0.8, 0.0, 0.4, 0.8 }, - callback = menu.editKeybinds, + + button{ + option = 'keybinds', + text = strings.option_keybinds, + color = { 0.6, 0.6, 0.6, 0.8 }, + callback = menu.editKeybinds, } -} - ---[[local keybindButtons = { - button{ - x = wWidth / 2, w = 400, h = 50 - y = 115, - text = options:get( 'forward_key' ), - color = { 0.8, 0.0, 0.4, 0.8 }, - callback = function() options:set( 'forward_key' ) end, }, - - button{ - x = wWidth / 2, w = 400, h = 50 - y = 115, - text = strings.backward_key, - color = { 0.8, 0.0, 0.4, 0.8 }, - callback = function() return setOption( 'backward_key' ) end, - } - -}]] -function menu.onLoad() - lg.setNewFont( 28 ) - return menu.resize( lg.getDimensions() ) -end + lg.newMesh{ + { 0, 0, 0, 0, 0.4, 0.1, 0.05, 0.0 }, + { 1, 0, 1, 0, 0.8, 0.3, 0.1, 0.8 }, + { 1, 1, 1, 1, 0.7, 0.4, 0.1, 0.8 }, + { 0, 1, 0, 1, 0.4, 0.1, 0.03, 0.0 },}, -function menu.draw() - lg.setCanvas() - lg.setColor( 1,1,1,1 ) - lg.draw( canvas ) -end -function menu.paint() - - lg.setCanvas( canvas ) - - --bg - lg.setColor( 0.8, 0.6, 0.3, 1 ) - lg.rectangle( "fill", 0, 0, wWidth, wHeight ) - - --buttons - for id, button in pairs( buttons ) do button:draw( ) end - - --gradient - lg.setColor( 1, 1, 1, 1 ) - lg.draw( gradientQuad, 0, 0, 0, wWidth, wHeight ) - lg.setCanvas() - -end - -function menu.update( dt ) - t = t + dt -end - -function menu.resize( w, h ) - wWidth, wHeight = w, h - canvas = lg.newCanvas() - for id, uiButton in pairs( buttons ) do - uiButton.w = wWidth - end - return menu.paint() -end - -function menu.mousemoved( x, y, dx, dy, istouch ) - if selectedButtonIdx then - buttons[selectedButtonIdx].selected = false - selectedButtonIdx = nil - end - for id, menuButton in ipairs( buttons ) do - if menuButton:contains( x, y ) then - menuButton.selected = true - selectedButtonIdx = id - return menu.paint() - end - end - -end - -function menu.mousepressed( x, y, button, istouch, presses ) - if not selectedButtonIdx then return end - local uiButton = buttons[selectedButtonIdx] - if uiButton:contains( x, y ) then return uiButton( ) end - - return menu.paint() -end - -function menu.keypressed( key, code, isrepeat ) - - if code == "escape" then - return scene.mainmenu() - end - - if code == "return" and selectedButtonIdx then - return buttons[selectedButtonIdx].callback() - end - - if code == "down" or code == "tab" or code == "up" then - local sbi = (selectedButtonIdx or 1) - buttons[sbi].selected = false - - --Increment / decrement - sbi = sbi + ((code == "up") and -1 or 1) - if sbi > #buttons then sbi = 1 end - if sbi < 1 then sbi = #buttons end - - --Assign - print( "selecting button: ", sbi ) - selectedButtonIdx = sbi - buttons[selectedButtonIdx].selected = true - end - - return menu.paint() -end - -scene.options = menu -return menu \ No newline at end of file + lg.newMesh{ + { 0, 0, 0, 0, 1, 1, 1, 0.01 }, + { 1, 0, 1, 0, 1, 1, 1, 0.1 }, + { 1, 1, 1, 1, 0, 0, 0, 0.1 }, + { 0, 1, 0, 1, 0, 0, 0, 0.01 },} +) \ No newline at end of file diff --git a/src/main.lua b/src/main.lua index c34ffde..65418e6 100644 --- a/src/main.lua +++ b/src/main.lua @@ -3,10 +3,12 @@ local shared = assert( require 'shared' ) local love = assert( love ) function love.load() + love.graphics.setNewFont( "client/assets/CinzelDecorative-Black.otf", 36 ) local scenes = assert( require 'client.scene' ) - assert( require 'client.ui.menu' ) + + assert( require 'client.ui.options' ) assert( require 'client.ui.browser' ) assert( require 'client.game' ) - assert( require 'client.ui.options' ) - scenes.mainmenu() + assert( require 'client.ui.mainmenu' ) + scenes.loadScene( scenes.mainmenu ) end