From 67b6482c3e3294b94b486ec21c063685a09a08b4 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Sat, 6 Feb 2021 18:36:36 -0600 Subject: [PATCH] Add lobby system --- main.lua | 354 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 312 insertions(+), 42 deletions(-) diff --git a/main.lua b/main.lua index c46a4e0..25b575f 100644 --- a/main.lua +++ b/main.lua @@ -3,14 +3,17 @@ class = require "lib/middleclass" wind = require "lib/windfield" stalker = require "lib/STALKER-X" -startSwordLength = 40; startKnifeLength = 10 +SWORDLENGTH = 40; KNIFELENGTH = 10 +SWORDWIDTH = 3 +SHIELDWIDTH = 16 +SHIELDHEIGHT = 5 -- GAME STATES -------------------------------------------------------------------------------- -- LOVE ---------------------------------------- -function love.load () +function love.load() math.randomseed(os.time()) love.graphics.setDefaultFilter("nearest", "nearest") @@ -54,13 +57,9 @@ end -- MAIN-MENU ---------------------------------------- -function mainmenu_load () - mainMenu = makeMainMenu() - - updateFunction = function (dt) mainMenu:update(dt) end - drawFunction = function () mainMenu:draw() end - keypressedFunction = function(key) mainMenu:keypressed(key) end - keyreleasedFunction = function(key) mainMenu:keyreleased(key) end +function mainmenu_load() + local mainMenu = makeMainMenu() + mainMenu:install() camera = stalker() end @@ -69,27 +68,27 @@ end function makeMainMenu() return Menu:new(100, 100, 30, 50, 3, { {love.graphics.newText(a_ttf, "Local"), - function () - local lobbiest1 = LocalLobbiest:new(nil, KEYMAPS[1]) - local lobbiest2 = LocalLobbiest:new(nil, KEYMAPS[2]) - game_load({lobbiest1, lobbiest2}) - end}, + function () lobby_load(LocalLobby) end}, {love.graphics.newText(a_ttf, "Quit"), function () love.event.quit(0) end }}) end +-- GAME LOBBY +---------------------------------------- +function lobby_load(lobbyClass) + lobby = lobbyClass:new() + lobby:install() +end + + -- IN-GAME ---------------------------------------- Game = class("Game") function game_load(lobbiests) game = Game:new(lobbiests) - - updateFunction = function (dt) game:update(dt) end - drawFunction = function () game:draw() end - keypressedFunction = function(key) game:keypressed(key) end - keyreleasedFunction = function(key) game:keyreleased(key) end + game:install() end @@ -103,12 +102,13 @@ function Fighter:initialize(game, x, y, character, swordType, swordSide) self.game = game self.swordType = swordType or 'normal' self.swordSide = swordSide or 'top' - self.character = character or "jellyfish-lion.png" + self.character = character or math.random(1, table.maxn(CHARACTERS)) self.directionals = {} self.deadPieces = {} - self.sprite = love.graphics.newImage("art/sprites/" .. self.character) + self.sprite = love.graphics.newImage("art/sprites/" + .. CHARACTERS[self.character]["file"]) self:initBody(x, y) self:initSword() @@ -127,14 +127,14 @@ function Fighter:update(dt) end -function Fighter:draw () +function Fighter:draw() local x,y = self.body:getWorldPoints(self.body.shape:getPoints()) love.graphics.draw(self.sprite, x, y, self.body:getAngle(), 1, 1) end -function Fighter:movement () +function Fighter:movement() end @@ -156,12 +156,12 @@ end function Fighter:initSword() - self.swordLength = startSwordLength + self.swordLength = SWORDLENGTH if (self.swordType == 'normal') then self.sword = self.game.world:newRectangleCollider(0, 0, 3, self.swordLength); else - self.sword = self.game.world:newRectangleCollider(0, 0, 3, startKnifeLength); + self.sword = self.game.world:newRectangleCollider(0, 0, 3, KNIFELENGTH); end self.sword:setCollisionClass('Sword') self.sword:setObject(self) @@ -169,7 +169,7 @@ function Fighter:initSword() end -function Fighter:glueSwordAndShield () +function Fighter:glueSwordAndShield() local x, y = self.body:getPosition() local angle = self.body:getAngle() @@ -225,7 +225,7 @@ function LocalPlayer:initialize(game, x, y, keymap, character, swordType, swordS end -function LocalPlayer:movement () +function LocalPlayer:movement() local x, y = self.body:getPosition() local dir = self.directionals local angle = self.body:getAngle() @@ -285,6 +285,7 @@ function LocalPlayer:keyreleased(key) end end + -- LocalBot andddd for bots too ---------------------------------------- LocalBot = class("LocalBot", Fighter) @@ -294,8 +295,6 @@ function LocalBot:initialize(x, y, character, swordType, swordSide) end - - -- GAME superclass for matches ---------------------------------------- function Game:initialize(lobbiests) @@ -312,7 +311,8 @@ function Game:initialize(lobbiests) for k,lobbiest in pairs(lobbiests) do if (lobbiest.class.name == "LocalLobbiest") then local i = self.localPlayersN + 1 - self.localPlayers[i] = LocalPlayer:new(self, 0 + i * 50, 0 + i * 50, KEYMAPS[i]) + self.localPlayers[i] = LocalPlayer:new(self, 0 + i * 50, 0 + i * 50, + KEYMAPS[i], lobbiest.character) self.localPlayersN = i end end @@ -327,6 +327,15 @@ function Game:initialize(lobbiests) end +function Game:install(update, draw, press, release) + hookInstall(function (dt) self:update(dt) end, + function () self:draw() end, + function (key) self:keypressed(key) end, + function (key) self:keyreleased(key) end, + update, draw, press, release) +end + + function Game:update(dt) self.world:update(dt) @@ -338,7 +347,7 @@ function Game:update(dt) end -function Game:draw () +function Game:draw() self.world:draw() for i, fighter in pairs(self.fighters) do fighter:draw() @@ -377,27 +386,181 @@ end ---------------------------------------- Lobby = class("Lobby") +function Lobby:initialize() + self.localLobbiests = {} + self.localLobbiestsN = 0 + self.remoteLobbiests = {} + self.remoteLobbiestsN = 0 + + self.ttf = r_ttf + self.scale = 3 +end + + +function Lobby:draw() + love.graphics.draw(love.graphics.newText(self.ttf, self.class.name), 10, 10, 0, self.scale) + love.graphics.draw(love.graphics.newText(self.ttf, + self:lobbiestsN() .. " players"), 500, 10, 0, self.scale) + + for i,lobbiest in pairs(self:lobbiests()) do + local rowX = 10 + local rowY = (25 * i) + 50 + + love.graphics.draw(lobbiest.sprite, rowX, rowY, 0, 1, 1) + if (lobbiest.swordType == "normal") then + love.graphics.rectangle("fill", rowX + 18, rowY + SWORDWIDTH, + SWORDLENGTH, SWORDWIDTH) + else + love.graphics.rectangle("fill", rowX + 18, rowY + SWORDWIDTH, + KNIFELENGTH, SWORDWIDTH) + end + + love.graphics.draw(love.graphics.newText(self.ttf, lobbiest.name), + rowX + SWORDLENGTH + 30, rowY, 0, self.scale) + love.graphics.draw(love.graphics.newText(self.ttf, lobbiest.class.name), + rowX + 500, rowY, 0, self.scale) + + if (lobbiest.class.name == "LocalLobbiest") then + local keymap = lobbiest.keymap + local text = keymap["accel"] .. " " .. keymap["left"] .. " " + .. keymap["flip"] .. " " .. keymap["right"] + + love.graphics.draw(love.graphics.newText(self.ttf, text), + rowX + 300, rowY + 5, 0, self.scale * (2/3)) + end + end + + love.graphics.draw(love.graphics.newText(self.ttf, "SPACE: Add player"), + 10, 460, 0, self.scale) + love.graphics.draw(love.graphics.newText(self.ttf, "LEFT: Edit name"), + 10, 500, 0, self.scale) + love.graphics.draw(love.graphics.newText(self.ttf, "RIGHT: Change sprite"), + 10, 520, 0, self.scale) + love.graphics.draw(love.graphics.newText(self.ttf, "ACCEL: Change sword"), + 10, 540, 0, self.scale) +end + + +function Lobby:install(update, draw, press, release) + hookInstall(function (dt) self:update(dt) end, + function () self:draw() end, + function (key) self:keypressed(key) end, + function (key) self:keyreleased(key) end, + update, draw, press, release) +end + + +function Lobby:update(dt) +end + + +function Lobby:keypressed(key) + if (key == "space" and self.localLobbiestsN < table.maxn(KEYMAPS)) then + self:newLocalLobbiest() + else + for i,lobbiest in pairs(self.localLobbiests) do + lobbiest:keypressed(key) + end + end +end + + +function Lobby:keyreleased(key) +end + + +function Lobby:newLocalLobbiest() + local i = self.localLobbiestsN + 1 + self.localLobbiestsN = i + + self.localLobbiests[i] = LocalLobbiest:new(self, nil, KEYMAPS[i]) +end + + +function Lobby:lobbiests() + local lobbiests = {} + table.foreach(self.localLobbiests, + function(k, v) table.insert(lobbiests, v) end) + table.foreach(self.remoteLobbiests, + function(k, v) table.insert(lobbiests, v) end) + return lobbiests +end + + +function Lobby:lobbiestsN() + return self.remoteLobbiestsN + self.localLobbiestsN +end + + +-- LOCAL LOBBY +---------------------------------------- +LocalLobby = class("LocalLobby", Lobby) + +function LocalLobby:initialize() + Lobby.initialize(self) +end + + +function LocalLobby:keypressed(key) + if (key == "return" and self:lobbiestsN() > 1) then + game_load(self:lobbiests()) + else + Lobby.keypressed(self, key) + end +end + -- LOBBIEST proposed fighter ---------------------------------------- Lobbiest = class("Lobbiest") -function Lobbiest:initialize(name) +function Lobbiest:initialize(lobby, name) + self.lobby = lobby self.name = name or NAMES[math.random(1, table.maxn(NAMES))] - self.character = CHARACTERS[math.random(1, table.maxn(CHARACTERS))] + self.character = math.random(1, table.maxn(CHARACTERS)) + self.sprite = love.graphics.newImage("art/sprites/" + .. CHARACTERS[self.character]["file"]) + self.swordType = "normal" end --- LOCALLOBBIEST +-- LOCAL LOBBIEST ---------------------------------------- LocalLobbiest = class("LocalLobbiest", Lobbiest) -function LocalLobbiest:initialize(name, keymap) - Lobbiest.initialize(self, name) +function LocalLobbiest:initialize(lobby, name, keymap) + Lobbiest.initialize(self, lobby, name) self.keymap = keymap or KEYMAPS[math.random(1, table.maxn(KEYMAPS))] end +function LocalLobbiest:keypressed(key, playerNo) + if (key == self.keymap["accel"]) then + if (self.swordType == "normal") then self.swordType = "knife" + elseif (self.swordType == "knife") then self.swordType = "normal" + end + + elseif (key == self.keymap["left"]) then + local textBox = TextBox:new(20, 400, 3, 10, self.name, "Name: ", + function (text) + self.name = text + self.lobby:install() + end) + + textBox:install(false, drawFunction, nil, false) + + elseif (key == self.keymap["right"]) then + if (self.character == table.maxn(CHARACTERS)) then + self.character = 1 + else + self.character = self.character + 1 + end + self.sprite = love.graphics.newImage("art/sprites/" + .. CHARACTERS[self.character]["file"]) + end +end + + -- MENU used for creating menus (lol) ---------------------------------------- Menu = class("Menu") @@ -418,10 +581,20 @@ function Menu:initialize(x, y, offset_x, offset_y, scale, menuItems) end -function Menu:update () +function Menu:install(update, draw, press, release) + hookInstall(function (dt) self:update(dt) end, + function () self:draw() end, + function (key) self:keypressed(key) end, + function (key) self:keyreleased(key) end, + update, draw, press, release) end -function Menu:draw () + +function Menu:update() +end + + +function Menu:draw() for i=1,table.maxn(self.options) do local this_y = self.y + (self.offset_y * i) @@ -474,6 +647,63 @@ function Menu:keyreleased(key) end +-- TEXT ENTRY +---------------------------------------- +TextBox = class("TextBox") + +function TextBox:initialize(x, y, scale, max, initialText, label, onEnter) + self.x,self.y = x,y + self.scale = scale + self.onEnter = onEnter + self.text = initialText + self.label = label + self.max = max or 999 + + self.ttf = r_ttf +end + + +function TextBox:install(update, draw, press, release) + hookInstall(function (dt) self:update(dt) end, + function () self:draw() end, + function (key) self:keypressed(key) end, + function (key) self:keyreleased(key) end, + update, draw, press, release) +end + + +function TextBox:update() +end + + +function TextBox:draw() + love.graphics.draw(love.graphics.newText(self.ttf, + self.label .. self.text .. "_"), + self.x, self.y, 0, self.scale, self.scale) +end + + +function TextBox:keypressed(key) + print(key) + if (key == "return") then + self.onEnter(self.text) + + elseif (key == "backspace") then + self.text = self.text:sub(1, string.len(self.text) - 1) + elseif (string.len(self.text) > self.max) then + return + elseif (key == "space") then + self.text = self.text .. " " + elseif (string.len(key) == 1) then + self.text = self.text .. key + end +end + + +function TextBox:keyreleased(key) +end + + -- UTIL -------------------------------------------------------------------------------- function split(inputString, seperator) @@ -485,13 +715,51 @@ function split(inputString, seperator) end +-- Install the important 'hook' functions (draw, update, keypressed/released) +-- If any of the 'old' functions passed are not nil, then both the new and +-- old will be added into the new corresponding hook function +function hookInstall(newUpdate, newDraw, newPress, newRelease, + oldUpdate, oldDraw, oldPress, oldRelease) + local ignored = 1 + + if (oldUpdate == false) then + elseif (oldUpdate == nil and not (newUpdate == nil)) then + updateFunction = function (dt) newUpdate(dt) end + elseif not (newUpdate == nil) then + updateFunction = function (dt) oldUpdate(dt) newUpdate(dt) end + end + + if (oldDraw == false) then + elseif (oldDraw == nil and not (newDraw == nil)) then + drawFunction = function () newDraw() end + elseif not (newDraw == nil) then + drawFunction = function () oldDraw() newDraw() end + end + + if (oldPress == false) then + elseif (oldPress == nil and not (newPress == nil)) then + keypressedFunction = function (key) newPress(key) end + elseif not (newPress == nil) then + keypressedFunction = function (key) oldPress(key) newPress(key) end + end + + if (oldRelease == false) then + elseif (oldRelease == nil and not (newRelease == nil)) then + keyreleasedFunction = function (key) newRelease(key) end + elseif not (newPress == nil) then + keyreleasedFunction = function (key) oldRelease(key) newRelease(key) end + end +end + + -- MISC DATA -------------------------------------------------------------------------------- -- CHARACTERS ------------------------------------------ CHARACTERS = {} -CHARACTERS["jellyfish-lion.png"] = {"Lion Jellyfish", "hey, hey. you know whats shocking?", "rapidpunches", "CC-BY-SA 4.0"} -CHARACTERS["jellyfish-n.png"] = {"Jellyfish N", "(electricity)", "rapidpunches", "CC-BY-SA 4.0"} +CHARACTERS[1] = {["file"] = "jellyfish-lion.png", ["name"] = "Lion Jellyfish", ["desc"] = "hey, hey. you know whats shocking?", ["author"] = "rapidpunches", ["license"] = "CC-BY-SA 4.0"} +CHARACTERS[2] = {["file"] = "jellyfish-n.png", "Jellyfish N", "(electricity)", "rapidpunches", "CC-BY-SA 4.0"} +CHARACTERS[3] = {["file"] = "shark-unicorn.png", "Shark-Unicorn", "A masterpiece", "My little bro", "CC-BY-SA 4.0"} -- DEFAULT NAMES ------------------------------------------ @@ -500,5 +768,7 @@ NAMES = {"Ignucius", "Penguin", "Tux", "Puffy", "Doktoro", "Espero", "<3", "