diff --git a/src/client/assets/SitkaB.ttc b/src/client/assets/SitkaB.ttc deleted file mode 100644 index a146f09..0000000 Binary files a/src/client/assets/SitkaB.ttc and /dev/null differ diff --git a/src/client/config.lua b/src/client/config.lua new file mode 100644 index 0000000..e7495d9 --- /dev/null +++ b/src/client/config.lua @@ -0,0 +1,15 @@ +return { + name = "Player Name", + pronoun = "they", + colour = {0.8, 0.4, 0.4, 0.7}, + gamma = 0.5, + keybinds = { + forward = "w", + back = "s", + left = "a", + right = "d", + chat = "t", + love = "q", + hate = "e", + } +} \ No newline at end of file diff --git a/src/client/game.lua b/src/client/game.lua index 716bc29..da493ac 100644 --- a/src/client/game.lua +++ b/src/client/game.lua @@ -7,14 +7,16 @@ local udp = socket.udp() local game = {} local t = 0 local tick = 0 +local serverTick = "0" function game.draw() - + lg.print( tick, 0, 0 ) + lg.print( serverTick, 0, 25 ) end function game.onPacket( data, msg ) - if data then print( data, msg ) end + if data then serverTick = data end end function game.update( dt ) @@ -36,9 +38,11 @@ function game.disconnect( ) return scene.mainmenu() end -function game.onLoad( ) +function game.onLoad( params ) + params = params or {} + local serverIP, serverPort = params.serverIP or "192.168.2.15", params.serverPort or 51312 udp:settimeout( 0 ) - udp:setpeername( "192.168.2.15", 51312 ) + udp:setpeername( serverIP, serverPort ) end function game.keypressed( key, code, isRepeat ) diff --git a/src/client/scene.lua b/src/client/scene.lua index 09c5927..c14f581 100644 --- a/src/client/scene.lua +++ b/src/client/scene.lua @@ -2,12 +2,12 @@ local scene = {} local love = assert( love ) local mt = {} -local function loadScene( scene ) +local function loadScene( scene, params ) print( "Loading Scene:", scene.name ) for k, v in pairs( scene ) do love[k] = v end - scene.onLoad() + scene.onLoad( params ) end local function newScene( scenes, name, t ) diff --git a/src/client/ui/browser.lua b/src/client/ui/browser.lua index b8e05ae..b89840e 100644 --- a/src/client/ui/browser.lua +++ b/src/client/ui/browser.lua @@ -1,9 +1,20 @@ local lg = assert( love.graphics ) local scene = assert( require 'client.scene' ) +local textInput = assert( require 'client.ui.textinput' ) +local button = assert( require 'client.ui.button' ) local browser = {} +local ti = textInput.new{ + width = 300, + length = 20, + x = 15, + y = 165 +} + function browser.draw() - lg.rectangle( "fill", 50, 50, 50, 50 ) + lg.setColor( 1, 1, 1, 1 ) + lg.print( "Server Browser", 15, 115 ) + ti:draw() end function browser.update( dt ) @@ -14,12 +25,26 @@ function browser.onLoad( ) lg.setColor( 1, 1, 1, 1 ) end -function browser.mousepressed() +function browser.mousepressed(x, y, button, istouch, pressed) + if ti:contains( x, y ) then return ti:enterText( browser.joinIPString ) end +end + +function browser.joinIPString( s ) + --Parse IP address and port from string. If it's valid, join the server. + if not s then return end + ti:clear() + local valid, ip, port + if valid then return browser.joinIP( ip, port ) end +end + +function browser.joinIP( ip, port ) + return scene.game{ serverIP = ip, serverPort = port } end function browser.keypressed( key, code, isRepeat ) if code == "escape" then return scene.mainmenu() end + if code == "return" then return ti:enterText( browser.joinIPString ) end end scene.browser = browser diff --git a/src/client/ui/menu.lua b/src/client/ui/menu.lua index a6737ca..c47eb9d 100644 --- a/src/client/ui/menu.lua +++ b/src/client/ui/menu.lua @@ -93,7 +93,7 @@ function menu.paint() end function menu.onLoad() - lg.setNewFont( "client/assets/SitkaB.ttc", 28 ) + lg.setNewFont( 28 ) return menu.resize( lg.getDimensions() ) end diff --git a/src/client/ui/options.lua b/src/client/ui/options.lua index bdab00f..4a4bb11 100644 --- a/src/client/ui/options.lua +++ b/src/client/ui/options.lua @@ -3,6 +3,7 @@ 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 t = 0 @@ -21,40 +22,46 @@ local gradientQuad = lg.newMesh{ local buttons = { - button{ + + button{ x = 15, w = 400, h = 50, y = 115, - text = strings.option_name, - color = { 0.5, 0.2, 0.2, 0.6 }, - callback = function() print("Adjust Name") end }, - + 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, - text = strings.option_pron, - color = { 0.5, 0.2, 0.4, 0.6 }, - callback = function() print("Adjust Name") end }, + option = 'name', + text = strings.option_name, + color = { 0.5, 0.2, 0.2, 0.6 }, + callback = menu.textOption }, button{ x = 15, w = 400, h = 50, y = 115 + 55 * 2, - text = strings.option_tint, - color = { 0.5, 0.2, 0.6, 0.6 }, - callback = function() print("Adjust Colour") end }, + option = 'pronoun', + text = strings.option_pron, + color = { 0.5, 0.2, 0.4, 0.6 }, + callback = menu.textOption }, - button{ + button{ x = 15, w = 400, h = 50, y = 115 + 55 * 3, - text = strings.mainmenu_button, - color = { 0.5, 0.2, 0.8, 0.6 }, - callback = function() print("Adjust Name") return scene.mainmenu() end }, + option = 'colour', + text = strings.option_tint, + color = { 0.5, 0.2, 0.6, 0.6 }, + 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 = function() end, + callback = menu.editKeybinds, } } @@ -78,7 +85,7 @@ local buttons = }]] function menu.onLoad() - lg.setNewFont( "client/assets/SitkaB.ttc", 28 ) + lg.setNewFont( 28 ) return menu.resize( lg.getDimensions() ) end @@ -137,7 +144,7 @@ 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 + if uiButton:contains( x, y ) then return uiButton( ) end return menu.paint() end @@ -149,7 +156,7 @@ function menu.keypressed( key, code, isrepeat ) end if code == "return" and selectedButtonIdx then - return buttons[selectedButtonIdx]() + return buttons[selectedButtonIdx].callback() end if code == "down" or code == "tab" or code == "up" then diff --git a/src/client/ui/textinput.lua b/src/client/ui/textinput.lua index f8b4841..6d25ea2 100644 --- a/src/client/ui/textinput.lua +++ b/src/client/ui/textinput.lua @@ -5,65 +5,107 @@ local lg = assert( love.graphics ) local utf8 = assert( require 'utf8' ) local string = assert( string ) - local _lt local _lkp +local _lmm +local _lmp +local _callback local textInput = { } local __mt = { __index = textInput } -local activeWidget -function textInput.new() - return setmetatable( {text = ""}, __mt ) +local font = lg.newFont( 36 ) + +-- There is only one active text input widget at a time. +-- It takes exclusive control of key input. +local activeWidget + +textInput.width = 200 +textInput.length = 20 +textInput.x = 0 +textInput.y = 0 + +function textInput.new( t ) + t = t or {} + t.text = lg.newText( font, "") + t.str = "" + return setmetatable( t, __mt ) end ---This is only called when a text input widget is active. function textInput.keypressed(key, code, isRepeat) - assert( activeWidget ) - if code == "escape" then return textInput.escape() end - if code == "return" then return textInput.return() end - - local text = activeWidget.text - if code == "backspace" then - local byteoffset = utf8.offset(text, -1) - - if byteoffset then - -- remove the last UTF-8 character. - -- string.sub operates on bytes rather than UTF-8 characters, so we couldn't do string.sub(text, 1, -2). - text = string.sub(text, 1, byteoffset - 1) - end - end -end - -function textInput:draw() - lg.rectangle( ) - lg.print(self.text, self.x or 0, self.y or 0) -end - -function textInput:getText() - return self.text -end - -function textInput.textInput( s ) - activeWidget.text = activeWidget.text..s -end - -function textInput:enable() - _lt = love.textinput - _lkp = love.keypressed - love.textinput = textInput.textInput - love.keypressed = textInput.keypressed - activeWidget = self + if activeWidget and textInput[code] then return textInput[code]() end end function textInput:clear() - + self.str = "" + self.text:set( self.str ) end -function textInput.disable() +function textInput:contains(x, y) + local mx, my, Mx, My = self.x, self.y, self.x + self.width, self.y + font:getHeight() + return (x < Mx and x > mx and y > my and y < My) +end + +function textInput:draw() + local w, h = self.text:getDimensions() + lg.setColor( 1, 1, 1, 0.5 ) + lg.rectangle( "fill", self.x, self.y, w, h ) + if activeWidget == self then lg.rectangle( "fill", self.x, self.y, self.width, font:getHeight(), 5 ) end + lg.rectangle( "line", self.x - 3, self.y - 3, self.width + 6, font:getHeight() + 6, 5 ) + lg.setColor( 0, 0, 0, 1 ) + lg.draw( self.text, self.x or 0, self.y or 0) +end + +function textInput:getText() + return self.str +end + +function textInput.textInput( s ) + activeWidget.str = activeWidget.str..s + activeWidget.text:set( activeWidget.str ) +end + +function textInput.backspace( ) + local str = activeWidget.str + local byteoffset = utf8.offset(str, -1) + if byteoffset then str = string.sub(str, 1, byteoffset - 1) + else return end + activeWidget.str = str + activeWidget.text:set( activeWidget.str ) +end + +function textInput:enterText( callback ) + _lt = love.textinput + _lkp = love.keypressed + _lmm = love.mousemoved + _lmp = love.mousepressed + _callback = assert( callback ) + love.textinput = textInput.textInput + love.keypressed = textInput.keypressed + self.oldStr = self.str + activeWidget = self +end + +local function disable() + activeWidget = nil love.textinput = _lt - love. + love.keypressed = _lkp + love.mousemoved = _lmm + love.mousepressed = _lmp +end + +function textInput.escape() + activeWidget.str = activeWidget.oldStr or "" + activeWidget.text:set( activeWidget.str ) + disable() + return _callback() +end + +textInput["return"] = function() --unusual decl because return is a keyword + local str = activeWidget.str + disable() + return _callback( str ) end return textInput \ No newline at end of file diff --git a/src/server.lua b/src/server.lua index 1e331fd..335346e 100644 --- a/src/server.lua +++ b/src/server.lua @@ -9,9 +9,7 @@ local server = { serverName = "dajjal-server", } -local clients = { - -} +local clients = {} do local _print = print @@ -32,7 +30,10 @@ end --Incoming packet. function server.Parse( packet, ip, port ) if not packet then return end - print( packet, ip, port ) + if not clients[ip] then + clients[ip] = { ip = ip, port = port } + end + clients[ip].tick = packet return server.Parse( udp:receivefrom() ) -- Process any packets we missed. end @@ -49,7 +50,7 @@ end function server.Advance() server.tick = server.tick + 1 - for id, client in ipairs( clients ) do + for id, client in pairs( clients ) do udp:sendto( string.format("server: %d client: %d", server.tick, client.tick), client.ip, client.port) end end