From 59b851d08727d14c973eb255413b4b48834cf1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erkki=20Sepp=C3=A4l=C3=A4?= Date: Thu, 23 Oct 2014 21:42:30 +0300 Subject: [PATCH] Added reconfigurable keybindings --- entities/entity.lua | 13 ---- entities/label.lua | 38 +++++++++++ entities/valuecontroller.lua | 27 ++++++++ level.lua | 1 + level_state.lua | 8 ++- menu_state.lua | 126 ++++++++++++++++++++++++++--------- player.lua | 6 ++ settings.lua | 10 ++- 8 files changed, 176 insertions(+), 53 deletions(-) create mode 100644 entities/label.lua create mode 100644 entities/valuecontroller.lua diff --git a/entities/entity.lua b/entities/entity.lua index 95c7412..e386710 100644 --- a/entities/entity.lua +++ b/entities/entity.lua @@ -36,16 +36,3 @@ Entity = Class{ self.level.entity_list[self.id] = nil end; } - -function drawEntities() - -- Do we need ordering? If so, use ipairs instead of pairs - for key, entity in pairs(entity_list) do - entity:draw() - end -end - -function updateEntities(dt) - for key, entity in pairs(entity_list) do - entity:update(dt) - end -end diff --git a/entities/label.lua b/entities/label.lua new file mode 100644 index 0000000..d7a4488 --- /dev/null +++ b/entities/label.lua @@ -0,0 +1,38 @@ +Class = require 'hump.class' +require 'entities/entity' + +Label = Class { + __include = Entity, + + init = function(self, label, font, color, align, xsize, ysize, ...) + Entity.init(self, ...) + self.label = label + self.color = color + self.font = font + self.align = align + self.xsize = xsize + self.ysize = ysize + self.onClickFunction = function() end + end; + + onClick = function(self, fn) + self.onClickFunction = fn + return self + end; + + draw = function(self) + love.graphics.push() + love.graphics.setColor(self.color) + love.graphics.translate(self.x, self.y) + love.graphics.setFont(self.font) + love.graphics.printf(self.label, 0, 0, self.xsize, self.align) + --love.graphics.rectangle("fill", 0, 0, self.xsize, self.ysize) + love.graphics.pop() + end; + + mousePressed = function(self, x, y, button) + if x >= self.x and y >= self.y and x <= self.x + self.xsize and y <= self.y + self.ysize then + self.onClickFunction(button) + end + end; +} diff --git a/entities/valuecontroller.lua b/entities/valuecontroller.lua new file mode 100644 index 0000000..1eff4b9 --- /dev/null +++ b/entities/valuecontroller.lua @@ -0,0 +1,27 @@ +Class = require 'hump.class' +require 'entities/entity' + +ValueController = Class { + __include = Entity, + + init = function(self, fn, level) + Entity.init(self, 0, 0, level) + self.fn = fn + self.onDelete = function() end + self.t = 0 + end; + + update = function(self, dt) + self.t = self.t + dt + self.fn(self.t) + end; + + draw = function(...) + Entity.draw(...) + end; + + delete = function(self, ...) + self.onDelete() + Entity.delete(self, ...) + end; +} diff --git a/level.lua b/level.lua index 3f17e8b..3956063 100644 --- a/level.lua +++ b/level.lua @@ -22,6 +22,7 @@ Level = Class{ self.background = love.graphics.newImage('resources/graphics/sky.png') self.bgCanvas = love.graphics.newCanvas() love.graphics.setCanvas(self.bgCanvas) + love.graphics.setColor(255, 255, 255, 255) love.graphics.draw(self.background) love.graphics.setCanvas() diff --git a/level_state.lua b/level_state.lua index 4961045..de8ae81 100644 --- a/level_state.lua +++ b/level_state.lua @@ -178,12 +178,14 @@ function level_state:keypressed(key, unicode) or love.keyboard.isDown("rctrl")) then debugEnabled = not debugEnabled - elseif key == " " then - paused = not paused else + local found = false for id, player in pairs(players) do - player:press(key) + found = player:press(key) or found end + if not found and (key == " " or key == "p") then + paused = not paused + end end end diff --git a/menu_state.lua b/menu_state.lua index 472b7d6..64c4671 100644 --- a/menu_state.lua +++ b/menu_state.lua @@ -1,54 +1,104 @@ Gamestate = require 'hump.gamestate' require 'level_state' require 'settings' +require 'entities/label' +require 'entities/valuecontroller' menu_state = {} local font = love.graphics.newFont(18) +local midfont = love.graphics.newFont(40) local titlefont = love.graphics.newFont(72) local background = love.graphics.newImage('resources/graphics/sky.png') +local menuTime = 0 + +local currentlyChosen = nil + +local bindingName = { + ccw = "Turn CW", + cw = "Turn CCW", + shoot = "Shoot", + accelerate = "Engine power up", + decelerate = "Engine power down", + flip = "Flip" +} + +local bindingOrder = { "ccw", "cw", "shoot", "accelerate", "decelerate", "flip" } + function menu_state:enter() + menu_state.entity_list = {} love.graphics.setBackgroundColor(0, 0, 0, 0) + + local x = 40 + for player = 1, 2, 1 do + local y = 300 + Label(string.format("Player %d", player), midfont, { 255, 255, 255, 255 }, "left", 500, 0, x, y, menu_state) + y = y + 60 + for idx, key in ipairs(bindingOrder) do + local binding = KEYMAP[player][key] + local l1 = Label(bindingName[key], font, { 255, 255, 255, 255 }, "left", 190, 25, x, y, menu_state) + local l2 = Label(binding, font, { 255, 255, 255, 255 }, "left", 50, 25, x + 200, y, menu_state) + local adjust = function() + menu_state:adjustBindings(l1, l2, player, key) + end + l1:onClick(adjust) + l2:onClick(adjust) + y = y + 30 + end + x = x + 400 + end end +local blinkColor = function(t) + local seconds, subseconds = math.modf(menuTime) + return 255 * ((math.sin(math.pow((math.log(subseconds + 1) / math.log(2)), 2) * math.pi * 2) * 0.5 + 0.5)); +end + +function menu_state:adjustBindings(name, binding, player, key) + if currentlyChosen ~= nil then + currentlyChosen:delete() + end + + currentlyChosen = ValueController(function () + name.color[4] = blinkColor(); + binding.color[4] = blinkColor(); + end, menu_state) + currentlyChosen.data = { name = name, binding = binding, player = player, key = key, label = binding } + currentlyChosen.onDelete = function() + name.color[4] = 255; + binding.color[4] = 255; + end +end function menu_state:draw() love.graphics.setColor(128, 128, 128, 255) love.graphics.draw(background) + local seconds, subseconds = math.modf(menuTime) + love.graphics.setColor(255,255,255,255) love.graphics.setFont(titlefont) love.graphics.printf("FYSPLANE", 0, 100, love.window.getWidth(), "center") - love.graphics.setFont(font) - love.graphics.printf("PLAYER 1\ -\ -Turn CW: " .. KEYMAP[1]['cw'] .. "\ -Turn CCW: " .. KEYMAP[1]['ccw'] .. "\ -Shoot: " .. KEYMAP[1]['shoot'] .. "\ -Engine power up: " .. KEYMAP[1]['accelerate'] .. "\ -Engine power down: " .. KEYMAP[1]['decelerate'] .. "\ -Flip: " .. KEYMAP[1]['flip'] .. "\ -", 40, 400, 400, "left") - - love.graphics.printf("PLAYER 2\ -\ -Turn CW: " .. KEYMAP[2]['cw'] .. "\ -Turn CCW: " .. KEYMAP[2]['ccw'] .. "\ -Shoot: " .. KEYMAP[2]['shoot'] .. "\ -Engine power up: " .. KEYMAP[2]['accelerate'] .. "\ -Engine power down: " .. KEYMAP[2]['decelerate'] .. "\ -Flip: " .. KEYMAP[2]['flip'] .. "\ -", love.window.getWidth() - 40 - 400, 400, 400, "left") - love.graphics.printf("PRESS ANY KEY TO BEGIN…", 0, 700, love.window.getWidth(), "center") + + for key, entity in pairs(menu_state.entity_list) do + entity:draw() + end + end function menu_state:update(dt) + menuTime = menuTime + dt + for key, entity in pairs(menu_state.entity_list) do + if entity.update then + entity:update(dt) + end + end end @@ -58,17 +108,27 @@ end function menu_state:keypressed(key, unicode) - if key == "1" then - level_state.mode = "solo" - Gamestate.switch(level_state) - elseif key == "c" then - level_state.mode = "computer" - Gamestate.switch(level_state) + if currentlyChosen == nil then + if key == "1" then + level_state.mode = "solo" + Gamestate.switch(level_state) + elseif key == "c" then + level_state.mode = "computer" + Gamestate.switch(level_state) + elseif key == "escape" then + love.event.quit() + else + level_state.computer = "2player" + Gamestate.switch(level_state) + end elseif key == "escape" then - love.event.quit() + currentlyChosen:delete() + currentlyChosen = nil else - level_state.computer = "2player" - Gamestate.switch(level_state) + KEYMAP[currentlyChosen.data.player][currentlyChosen.data.key] = key + currentlyChosen.data.label.label = key + currentlyChosen:delete() + currentlyChosen = nil end end @@ -79,7 +139,11 @@ end function menu_state:mousepressed(x, y, button) - + for key, entity in pairs(menu_state.entity_list) do + if entity.mousePressed then + entity:mousePressed(x, y, button) + end + end end function menu_state:mousereleased(x, y, button) diff --git a/player.lua b/player.lua index 172493a..9f1a0af 100644 --- a/player.lua +++ b/player.lua @@ -52,23 +52,29 @@ Player = Class{ end; press = function(self, key) + local found = false for action, keycode in pairs(self.keys) do if key == keycode then + found = true if self.actions[action] and self.plane then self.actions[action](true) end end end + return found end; release = function(self, key) + local found = false for action, keycode in pairs(self.keys) do if key == keycode then + found = true if self.actions[action] and self.plane then self.actions[action](false) end end end + return found end; joystick = function(self, ...) diff --git a/settings.lua b/settings.lua index 94d82ce..c829575 100644 --- a/settings.lua +++ b/settings.lua @@ -13,21 +13,19 @@ KEYMAP = { [1] = { ccw = 'k', cw = 'l', - flip = 'i', + flip = ',', shoot = 'o', accelerate = 'j', - decelerate = 'm', - flip = ',' + decelerate = 'm' }, [2] = { ccw = 'a', cw = 's', - flip = 'q', + flip = 'a', shoot = 'w', accelerate = 'x', - decelerate = 'z', - flip = 'a' + decelerate = 'z' } }