Skip to content

Commit

Permalink
Merge pull request #848 from uspgamedev/feature/user-preferences
Browse files Browse the repository at this point in the history
Settings Menu
  • Loading branch information
Kazuo256 authored Aug 16, 2018
2 parents 0d51586 + d9221d3 commit 77f22c3
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 12 deletions.
12 changes: 12 additions & 0 deletions game/database/settings/user-preferences.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"bgm-volume": {
"default": 100,
"range": [0, 100],
"step": 10
},
"sfx-volume": {
"default": 100,
"range": [0, 100],
"step": 10
}
}
2 changes: 1 addition & 1 deletion game/domain/definitions/colors.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ COLORS.EXIT = Color.fromInt {0x77, 0xba, 0x99, 0xff}
COLORS.FLOOR1 = Color.fromInt {25, 73, 95, 0xff}
COLORS.FLOOR2 = Color.fromInt {25, 73, 95 + 20, 0xff}

COLORS.EMPTY = Color:new {0.2, .15, 0.05}
COLORS.EMPTY = Color:new {0.2, .15, 0.05, 1}
COLORS.WARNING = Color:new {1, 0.8, 0.2, 1}
COLORS.VALID = Color:new {0, 0.7, 1, 1}
COLORS.NOTIFICATION = Color.fromInt {0xD9, 0x53, 0x4F, 0xff}
Expand Down
100 changes: 100 additions & 0 deletions game/gamestates/settings.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@

local DB = require 'database'
local INPUT = require 'input'
local DIRECTIONALS = require 'infra.dir'
local PROFILE = require 'infra.profile'
local PLAYSFX = require 'helpers.playsfx'
local SettingsView = require 'view.settings'

local state = {}

local insert = table.insert
local sort = table.sort
local max = math.max
local min = math.min
local unpack = unpack

local _selection
local _schema
local _fields
local _fieldcount
local _original
local _view
local _save

local function _changeField(field, offset)
local low, high = unpack(_schema[field]["range"])
local step = _schema[field]["step"]
local value = (_changes[field] or _original[field]) + offset * step
_changes[field] = min(high, max(low, value))
PROFILE.setPreference(field, _changes[field])
end

function state:init()
_schema = DB.loadSetting("user-preferences")
_fields = {}
for field in pairs(_schema) do
insert(_fields, field)
end
sort(_fields) -- show them in alphabetical order!
_fieldcount = #_fields
_selection = 1
end

function state:enter(from, ...)
_selection = 1
_original = {}
for _,field in ipairs(_fields) do
_original[field] = PROFILE.getPreference(field) or _schema[field].default
PROFILE.setPreference(field, _original[field])
end
_changes = setmetatable({}, { __index = original })
_view = SettingsView(_fields)
_view:addElement("GUI")
end

function state:update(dt)
if INPUT.wasActionPressed("CONFIRM") then
PLAYSFX 'ok-menu'
_save = true
SWITCHER.pop()
elseif INPUT.wasActionPressed("CANCEL") then
PLAYSFX 'back-menu'
_save = false
SWITCHER.pop()
elseif DIRECTIONALS.wasDirectionTriggered("UP") then
PLAYSFX 'select-menu'
_selection = (_selection - 2 + _fieldcount) % _fieldcount + 1
_view:setFocus(_selection)
elseif DIRECTIONALS.wasDirectionTriggered("DOWN") then
PLAYSFX 'select-menu'
_selection = (_selection % _fieldcount) + 1
_view:setFocus(_selection)
elseif DIRECTIONALS.wasDirectionTriggered("LEFT") then
PLAYSFX 'ok-menu'
_changeField(_fields[_selection], -1)
elseif DIRECTIONALS.wasDirectionTriggered("RIGHT") then
PLAYSFX 'ok-menu'
_changeField(_fields[_selection], 1)
end
end

function state:leave()
-- when you leave, it will either save or restore the changes
if _save then
PROFILE.save()
PROFILE.init()
else
for field, value in ipairs(_original) do
PROFILE.setPreference(field, value)
end
end
_view:destroy()
end

function state:draw()
return Draw.allTables()
end

return state

13 changes: 6 additions & 7 deletions game/gamestates/start_menu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function _activity:enterMenu()
fade_view:fadeInAndThen(self.resume)
self.yield()
_locked = false
fade_view:destroy()
return fade_view:destroy()
end

function _activity:changeState(mode, to, ...)
Expand All @@ -47,16 +47,11 @@ function _activity:changeState(mode, to, ...)
self.yield()
fade_view:destroy()
_menu_view.invisible = true
if mode == 'push' then
SWITCHER.push(to, ...)
elseif mode == 'switch' then
SWITCHER.switch(to, ...)
end
return SWITCHER[mode](to, ...)
end


--STATE FUNCTIONS--

function state:enter()
_menu_context = "START_MENU"

Expand Down Expand Up @@ -102,6 +97,7 @@ function state:update(dt)
if _menu_context == "START_MENU" then
_menu_view:setItem("New route")
_menu_view:setItem("Load route")
_menu_view:setItem("Settings")
if DEV then
_menu_view:setItem("Controls")
end
Expand All @@ -127,6 +123,9 @@ function state:update(dt)
if MENU.item("Load route") then
_menu_context = "LOAD_LIST"
end
if MENU.item("Settings") then
_activity:changeState('push', GS.SETTINGS)
end
if DEV and MENU.item("Controls") then
CONFIGURE_INPUT(INPUT, INPUT.getMap())
end
Expand Down
3 changes: 2 additions & 1 deletion game/helpers/playsfx.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

local PROFILE = require 'infra.profile'
local RES = require 'resources'

return function (sfxname)
local sfx = RES.loadSFX(sfxname)
sfx:setVolume(1)
sfx:setVolume(PROFILE.getPreference("sfx-volume") / 100)
sfx:stop()
return sfx:play()
end
Expand Down
20 changes: 18 additions & 2 deletions game/infra/profile.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ local PROFILE_FILENAME = "profile"
local CONTROL_FILENAME = "controls"
local PROFILE_PATH = SAVEDIR..PROFILE_FILENAME
local CONTROL_PATH = SAVEDIR..CONTROL_FILENAME
local METABASE = { next_id = 1, save_list = {} }
local METABASE = { next_id = 1, save_list = {}, preferences = {} }

-- HELPERS
local filesystem = love.filesystem
Expand Down Expand Up @@ -86,6 +86,10 @@ local function _loadProfile()
local filedata = assert(filesystem.newFileData(PROFILE_PATH))
_metadata = _decode(filedata:getString())
_id_generator = IDGenerator(_metadata.next_id)
for field, default in pairs(METABASE) do
-- protection against version update (SHALLOW COPY ONLY)
_metadata[field] = _metadata[field] or default
end
end

-- METHODS --
Expand Down Expand Up @@ -127,10 +131,22 @@ function PROFILE.newRoute(player_info)
return route_data
end

function PROFILE.getSaveList ()
function PROFILE.getSaveList()
return _metadata.save_list
end

function PROFILE.getPreference(field)
return _metadata.preferences[field]
end

function PROFILE.setPreference(field, value)
_metadata.preferences[field] = value
end

function PROFILE.save()
_saveProfile()
end

-- NOTE TO SELF:
-- Add a quit method that deletes saves that are not on the profile's save_list.
-- This means that when you load a file, and you don't save it, it is lost
Expand Down
75 changes: 75 additions & 0 deletions game/view/settings.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@

local COLORS = require 'domain.definitions.colors'
local PROFILE = require 'infra.profile'
local FONT = require 'view.helpers.font'

local fmod = math.fmod
local sin = math.sin

local _PI = math.pi

local _font

local SettingsView = Class{
__includes = { ELEMENT }
}

local _getPreference = PROFILE.getPreference

function SettingsView:init(fields)
ELEMENT.init(self)
self.fields = fields
self.focus = 1
_font = FONT.get("Text", 20)
end

function SettingsView:setFocus(idx)
self.focus = idx
end

function SettingsView:draw()
local g = love.graphics
local focus = self.focus
local width = 256
local height = 10
local mx, my = 8, 8
local font_height = 20
local lw = 4
local base_y = 256
local x = 320
-- draw one settings input type
FONT.set("Title", 32)
g.setColor(COLORS.NEUTRAL)
g.print("SETTINGS", x, base_y - 80)
_font:set()
for i, field in ipairs(self.fields) do
local y = base_y + (i - 1) * (height + 4*my + font_height)
local percentage = _getPreference(field) / 100
local is_focused = (i == focus)
g.push()
g.translate(x, y)

-- field name
g.setColor(is_focused and COLORS.NEUTRAL or COLORS.HALF_VISIBLE)
g.print(field:gsub("[-]", " "):upper(), 0, -font_height)
g.translate(0, font_height)

-- line width offset
g.translate(0, lw)

-- trail
g.setLineWidth(lw)
g.setColor(is_focused and COLORS.EMPTY or COLORS.DARKER)
g.line(0, 0, width, 0)

-- value progression
g.setColor(is_focused and COLORS.NEUTRAL or COLORS.HALF_VISIBLE)
g.line(0, 0, percentage * width, 0)
g.ellipse("fill", percentage * width, 0, height, height)

g.pop()
end
end

return SettingsView

10 changes: 9 additions & 1 deletion game/view/soundtrack/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

local RES = require 'resources'
local RES = require 'resources'
local PROFILE = require 'infra.profile'

local SoundTrack = require 'lux.class' :new{}

Expand All @@ -18,12 +19,19 @@ function SoundTrack:instance(obj)
bgm.stream = RES.loadBGM(theme.bgm)
bgm.stream:play()
bgm.id = theme.bgm
updateVolume()
elseif not theme and bgm.stream then
bgm.stream:stop()
bgm.stream = nil
end
end

function updateVolume()
if bgm.stream then
bgm.stream:setVolume(PROFILE.getPreference("bgm-volume") / 100)
end
end

end

return SoundTrack
Expand Down

0 comments on commit 77f22c3

Please sign in to comment.