|
|
Line 166: |
Line 166: |
| end | | end |
| end) | | end) |
− | </syntaxhighlight>
| |
− |
| |
− | == KEY REMAPPING WITH SAVE DATA ==
| |
− | [[File:keyremapping.png||256px]]
| |
− |
| |
− | In this ''Settings'' scene we can remap any predefined keys. You can navigate using the arrows on your keyboard and press '''ENTER''' to remap a key.
| |
− |
| |
− | Once you have remapped the keys, the new settings are saved to a file which will be read everytime you restart the game.
| |
− |
| |
− | '''Code using [[ButtonMonster class|ButtonMonster]]'''
| |
− | <syntaxhighlight lang="lua">
| |
− | -- *** SAVING AND LOADING DATA IN JSON FORMAT ***
| |
− | require "json" -- don't forget to add the JSON plugin in your project
| |
− |
| |
− | function saveData(filepath, value)
| |
− | local contents = json.encode(value)
| |
− | local file = io.open(filepath, "w") -- create file
| |
− | file:write(contents) -- save json string in file
| |
− | io.close(file)
| |
− | end
| |
− |
| |
− | function getData(filepath)
| |
− | local value
| |
− | local file = io.open(filepath, "r")
| |
− | if file then
| |
− | local contents = file:read("*a") -- read contents
| |
− | value = json.decode(contents) -- decode json
| |
− | io.close(file)
| |
− | end
| |
− | return value
| |
− | end
| |
− |
| |
− | -- *** LOADING AND SAVING USER PREFS DATA ***
| |
− | -- global prefs functions
| |
− | function myLoadPrefs(xconfigfilepath)
| |
− | local mydata = getData(xconfigfilepath) -- try to read information from file
| |
− | if not mydata then -- if no prefs file, create it
| |
− | mydata = {}
| |
− | -- set prefs
| |
− | mydata.g_language = g_language
| |
− | -- controls
| |
− | mydata.g_keyleft = g_keyleft
| |
− | mydata.g_keyright = g_keyright
| |
− | mydata.g_keyup = g_keyup
| |
− | mydata.g_keydown = g_keydown
| |
− | mydata.g_keyaction1 = g_keyaction1
| |
− | mydata.g_keyaction2 = g_keyaction2
| |
− | mydata.g_keyaction3 = g_keyaction3
| |
− | -- save prefs
| |
− | saveData(xconfigfilepath, mydata) -- create file and save data
| |
− | else -- prefs file exists, use it!
| |
− | -- set prefs
| |
− | g_language = mydata.g_language
| |
− | -- controls
| |
− | g_keyleft = mydata.g_keyleft
| |
− | g_keyright = mydata.g_keyright
| |
− | g_keyup = mydata.g_keyup
| |
− | g_keydown = mydata.g_keydown
| |
− | g_keyaction1 = mydata.g_keyaction1
| |
− | g_keyaction2 = mydata.g_keyaction2
| |
− | g_keyaction3 = mydata.g_keyaction3
| |
− | end
| |
− | end
| |
− |
| |
− | function mySavePrefs(xconfigfilepath)
| |
− | local mydata = {} -- clear the table
| |
− | -- set prefs
| |
− | mydata.g_language = g_language
| |
− | -- controls
| |
− | mydata.g_keyleft = g_keyleft
| |
− | mydata.g_keyright = g_keyright
| |
− | mydata.g_keyup = g_keyup
| |
− | mydata.g_keydown = g_keydown
| |
− | mydata.g_keyaction1 = g_keyaction1
| |
− | mydata.g_keyaction2 = g_keyaction2
| |
− | mydata.g_keyaction3 = g_keyaction3
| |
− | -- save prefs
| |
− | saveData(xconfigfilepath, mydata) -- save new data
| |
− | end
| |
− |
| |
− | -- initial default global prefs values
| |
− | g_configfilepath = "|D|configfile.txt" -- data are saved in this file (in the Document app folder)
| |
− | g_language = application:getLanguage()
| |
− | g_keyleft = KeyCode.LEFT
| |
− | g_keyright = KeyCode.RIGHT
| |
− | g_keyup = KeyCode.UP
| |
− | g_keydown = KeyCode.DOWN
| |
− | g_keyaction1 = KeyCode.D -- punch1
| |
− | g_keyaction2 = KeyCode.S -- punch1
| |
− | g_keyaction3 = KeyCode.Q -- jump/jump punch1
| |
− |
| |
− | -- load saved prefs from file (|D|configfile.txt)
| |
− | myLoadPrefs(g_configfilepath) -- override default values by saved values if any
| |
− |
| |
− | -- *** GLOBAL FONT AND UI THEME FOR BUTTONS ***
| |
− | myttf = TTFont.new("fonts/Cabin-Regular-TTF.ttf", 2.8*8) -- UI
| |
− | g_ui_theme = {}
| |
− | g_ui_theme.pixelcolorup = 0x8d595d
| |
− | g_ui_theme.pixelcolordown = 0xc09c98
| |
− | g_ui_theme.textcolorup = 0xd9d2cb
| |
− | g_ui_theme.textcolordown = 0xd9d2cb
| |
− | g_ui_theme._textcolordisabled = 0xd9d2cb
| |
− | g_ui_theme.tooltiptextcolor = 0x3a1d20
| |
− | g_ui_theme.tooltipoffsetx = -7*8
| |
− | g_ui_theme.tooltipoffsety = 1*4
| |
− |
| |
− | -- *** THE OPTIONS SCENE (Class) ***
| |
− | Options = Core.class(Sprite)
| |
− |
| |
− | local keyNames = { -- display a friendly key name
| |
− | [KeyCode.LEFT] = "LEFT",
| |
− | [KeyCode.RIGHT] = "RIGHT",
| |
− | [KeyCode.UP] = "UP",
| |
− | [KeyCode.DOWN] = "DOWN",
| |
− | [KeyCode.NUM0] = "NUMPAD 0",
| |
− | [KeyCode.NUM1] = "NUMPAD 1",
| |
− | [KeyCode.NUM2] = "NUMPAD 2",
| |
− | [KeyCode.NUM3] = "NUMPAD 3",
| |
− | [KeyCode.NUM4] = "NUMPAD 4",
| |
− | [KeyCode.NUM5] = "NUMPAD 5",
| |
− | [KeyCode.NUM6] = "NUMPAD 6",
| |
− | [KeyCode.NUM7] = "NUMPAD 7",
| |
− | [KeyCode.NUM8] = "NUMPAD 8",
| |
− | [KeyCode.NUM9] = "NUMPAD 9",
| |
− | [KeyCode.SPACE] = "SPACE",
| |
− | [KeyCode.SHIFT] = "SHIFT",
| |
− | [KeyCode.CTRL] = "CONTROL",
| |
− | [KeyCode.ALT] = "ALT",
| |
− | [KeyCode.TAB] = "TAB",
| |
− | }
| |
− |
| |
− | function Options:init()
| |
− | -- bg
| |
− | application:setBackgroundColor(0x232a35)
| |
− | -- tooltip layer
| |
− | local tooltiplayer = Sprite.new()
| |
− | -- buttons
| |
− | local key
| |
− | -- movement
| |
− | if (keyNames[g_keyleft] or 0) == 0 then key = utf8.char(g_keyleft)
| |
− | else key = keyNames[g_keyleft]
| |
− | end -- display a friendly key name
| |
− | self.btnLEFT = ButtonMonster.new({
| |
− | autoscale=false, pixelwidth=17*8, pixelheight=6*8,
| |
− | pixelscalexup=0.8, pixelscalexdown=0.9,
| |
− | pixelcolorup=g_ui_theme.pixelcolorup, pixelcolordown=g_ui_theme.pixelcolordown,
| |
− | text=key, ttf=myttf, textcolorup=g_ui_theme.textcolorup, textcolordown=g_ui_theme.textcolordown,
| |
− | tooltiptext="left", tooltipttf=myttf, tooltiptextcolor=g_ui_theme.tooltiptextcolor,
| |
− | tooltipoffsetx=g_ui_theme.tooltipoffsetx, tooltipoffsety=g_ui_theme.tooltipoffsety,
| |
− | }, 2, tooltiplayer)
| |
− | if (keyNames[g_keyright] or 0) == 0 then key = utf8.char(g_keyright)
| |
− | else key = keyNames[g_keyright]
| |
− | end -- display a friendly key name
| |
− | self.btnRIGHT = ButtonMonster.new({
| |
− | autoscale=false, pixelwidth=17*8, pixelheight=6*8,
| |
− | pixelscalexup=0.8, pixelscalexdown=0.9,
| |
− | pixelcolorup=g_ui_theme.pixelcolorup, pixelcolordown=g_ui_theme.pixelcolordown,
| |
− | text=key, ttf=myttf, textcolorup=g_ui_theme.textcolorup, textcolordown=g_ui_theme.textcolordown,
| |
− | tooltiptext="right", tooltipttf=myttf, tooltiptextcolor=g_ui_theme.tooltiptextcolor,
| |
− | tooltipoffsetx=g_ui_theme.tooltipoffsetx, tooltipoffsety=g_ui_theme.tooltipoffsety,
| |
− | }, 3, tooltiplayer)
| |
− | if (keyNames[g_keyup] or 0) == 0 then key = utf8.char(g_keyup)
| |
− | else key = keyNames[g_keyup]
| |
− | end -- display a friendly key name
| |
− | self.btnUP = ButtonMonster.new({
| |
− | autoscale=false, pixelwidth=17*8, pixelheight=6*8,
| |
− | pixelscalexup=0.8, pixelscalexdown=0.9,
| |
− | pixelcolorup=g_ui_theme.pixelcolorup, pixelcolordown=g_ui_theme.pixelcolordown,
| |
− | text=key, ttf=myttf, textcolorup=g_ui_theme.textcolorup, textcolordown=g_ui_theme.textcolordown,
| |
− | tooltiptext="up", tooltipttf=myttf, tooltiptextcolor=g_ui_theme.tooltiptextcolor,
| |
− | tooltipoffsetx=g_ui_theme.tooltipoffsetx, tooltipoffsety=g_ui_theme.tooltipoffsety,
| |
− | }, 1, tooltiplayer)
| |
− | if (keyNames[g_keydown] or 0) == 0 then key = utf8.char(g_keydown)
| |
− | else key = keyNames[g_keydown]
| |
− | end -- display a friendly key name
| |
− | self.btnDOWN = ButtonMonster.new({
| |
− | autoscale=false, pixelwidth=17*8, pixelheight=6*8,
| |
− | pixelscalexup=0.8, pixelscalexdown=0.9,
| |
− | pixelcolorup=g_ui_theme.pixelcolorup, pixelcolordown=g_ui_theme.pixelcolordown,
| |
− | text=key, ttf=myttf, textcolorup=g_ui_theme.textcolorup, textcolordown=g_ui_theme.textcolordown,
| |
− | tooltiptext="down", tooltipttf=myttf, tooltiptextcolor=g_ui_theme.tooltiptextcolor,
| |
− | tooltipoffsetx=g_ui_theme.tooltipoffsetx, tooltipoffsety=g_ui_theme.tooltipoffsety,
| |
− | }, 4, tooltiplayer)
| |
− | -- actions
| |
− | if (keyNames[g_keyaction1] or 0) == 0 then key = utf8.char(g_keyaction1)
| |
− | else key = keyNames[g_keyaction1]
| |
− | end -- display a friendly key name
| |
− | self.btnACTION1 = ButtonMonster.new({
| |
− | autoscale=false, pixelwidth=17*8, pixelheight=6*8,
| |
− | pixelscalexup=0.8, pixelscalexdown=0.9,
| |
− | pixelcolorup=g_ui_theme.pixelcolorup, pixelcolordown=g_ui_theme.pixelcolordown,
| |
− | text=key, ttf=myttf, textcolorup=g_ui_theme.textcolorup, textcolordown=g_ui_theme.textcolordown,
| |
− | tooltiptext="punch1", tooltipttf=myttf, tooltiptextcolor=g_ui_theme.tooltiptextcolor,
| |
− | tooltipoffsetx=g_ui_theme.tooltipoffsetx, tooltipoffsety=g_ui_theme.tooltipoffsety,
| |
− | }, 5, tooltiplayer)
| |
− | if (keyNames[g_keyaction2] or 0) == 0 then key = utf8.char(g_keyaction2)
| |
− | else key = keyNames[g_keyaction2]
| |
− | end -- display a friendly key name
| |
− | self.btnACTION2 = ButtonMonster.new({
| |
− | autoscale=false, pixelwidth=17*8, pixelheight=6*8,
| |
− | pixelscalexup=0.8, pixelscalexdown=0.9,
| |
− | pixelcolorup=g_ui_theme.pixelcolorup, pixelcolordown=g_ui_theme.pixelcolordown,
| |
− | text=key, ttf=myttf, textcolorup=g_ui_theme.textcolorup, textcolordown=g_ui_theme.textcolordown,
| |
− | tooltiptext="punch2", tooltipttf=myttf, tooltiptextcolor=g_ui_theme.tooltiptextcolor,
| |
− | tooltipoffsetx=g_ui_theme.tooltipoffsetx, tooltipoffsety=g_ui_theme.tooltipoffsety,
| |
− | }, 6, tooltiplayer)
| |
− | if (keyNames[g_keyaction3] or 0) == 0 then key = utf8.char(g_keyaction3)
| |
− | else key = keyNames[g_keyaction3]
| |
− | end -- display a friendly key name
| |
− | self.btnACTION3 = ButtonMonster.new({
| |
− | autoscale=false, pixelwidth=17*8, pixelheight=6*8,
| |
− | pixelscalexup=0.8, pixelscalexdown=0.9,
| |
− | pixelcolorup=g_ui_theme.pixelcolorup, pixelcolordown=g_ui_theme.pixelcolordown,
| |
− | text=key, ttf=myttf, textcolorup=g_ui_theme.textcolorup, textcolordown=g_ui_theme.textcolordown,
| |
− | tooltiptext="jump punch", tooltipttf=myttf, tooltiptextcolor=g_ui_theme.tooltiptextcolor,
| |
− | tooltipoffsetx=g_ui_theme.tooltipoffsetx, tooltipoffsety=g_ui_theme.tooltipoffsety,
| |
− | }, 7, tooltiplayer)
| |
− | -- btn menu
| |
− | self.btnMENU = ButtonMonster.new({
| |
− | autoscale=false, pixelwidth=12*8, pixelheight=6*8,
| |
− | pixelscalexup=0.8, pixelscalexdown=0.9,
| |
− | pixelcolorup=g_ui_theme.pixelcolorup, pixelcolordown=g_ui_theme.pixelcolordown,
| |
− | text="MENU", ttf=myttf, textcolorup=0x0009B3, textcolordown=0x45d1ff,
| |
− | tooltiptext="Enter", tooltipttf=myttf, tooltiptextcolor=g_ui_theme.tooltiptextcolor,
| |
− | tooltipoffsetx=g_ui_theme.tooltipoffsetx, tooltipoffsety=g_ui_theme.tooltipoffsety,
| |
− | }, 8, tooltiplayer)
| |
− | -- btns table
| |
− | self.btns = {}
| |
− | self.btns[#self.btns + 1] = self.btnUP -- 1
| |
− | self.btns[#self.btns + 1] = self.btnLEFT -- 2
| |
− | self.btns[#self.btns + 1] = self.btnRIGHT -- 3
| |
− | self.btns[#self.btns + 1] = self.btnDOWN -- 4
| |
− | self.btns[#self.btns + 1] = self.btnACTION1 -- 5
| |
− | self.btns[#self.btns + 1] = self.btnACTION2 -- 6
| |
− | self.btns[#self.btns + 1] = self.btnACTION3 -- 7
| |
− | self.btns[#self.btns + 1] = self.btnMENU -- 8
| |
− | self.selector = 1 -- starting button
| |
− | -- position
| |
− | self.btnLEFT:setPosition(1.5*myappwidth/10, 6*8+6*myappheight/10) -- 2
| |
− | self.btnRIGHT:setPosition(3.5*myappwidth/10, 6*8+6*myappheight/10) -- 3
| |
− | self.btnUP:setPosition(2.5*myappwidth/10, 6*8+4.6*myappheight/10) -- 1
| |
− | self.btnDOWN:setPosition(2.5*myappwidth/10, 6*8+7.4*myappheight/10) -- 4
| |
− | for i = 5, 7 do -- action buttons
| |
− | self.btns[i]:setPosition(5.6*myappwidth/10, (i-5)*6*8+6*myappheight/10)
| |
− | end
| |
− | self.btnMENU:setPosition(myappwidth - self.btnMENU:getWidth()/2, myappheight - self.btnMENU:getHeight()/2)
| |
− | -- order
| |
− | for k, v in ipairs(self.btns) do self:addChild(v) end
| |
− | self:addChild(tooltiplayer)
| |
− | -- buttons listeners
| |
− | for k, v in ipairs(self.btns) do
| |
− | -- v:addEventListener("pressed", function() self.selector = k self:goto() end)
| |
− | v:addEventListener("clicked", function() self.selector = k self:goto() end)
| |
− | v:addEventListener("hovered", function(e) self.selector = e.currselector end)
| |
− | v.btns = self.btns -- FOR KEYBOARD NAVIGATION!
| |
− | end
| |
− | -- let's go!
| |
− | self.isremapping = false
| |
− | self:myKeysPressed()
| |
− | self:updateButton()
| |
− | end
| |
− |
| |
− | -- key remapping
| |
− | function Options:remapKey(xbool)
| |
− | local btn = self.btns[self.selector]
| |
− | if xbool then
| |
− | self.isremapping = true
| |
− | btn:setColorTransform(255/255, 255/255, 0/255, 255/255)
| |
− | else
| |
− | btn:setColorTransform(255/255, 255/255, 255/255, 255/255)
| |
− | end
| |
− | end
| |
− |
| |
− | -- update button state
| |
− | function Options:updateButton()
| |
− | for k, v in ipairs(self.btns) do
| |
− | v.currselector = self.selector
| |
− | v:updateVisualState()
| |
− | end
| |
− | end
| |
− |
| |
− | -- KEYS HANDLER
| |
− | function Options:myKeysPressed()
| |
− | self:addEventListener(Event.KEY_DOWN, function(e)
| |
− | if self.isremapping then -- KEY REMAPPING
| |
− | if e.keyCode == KeyCode.ESC then
| |
− | self.isremapping = false
| |
− | self:remapKey(self.isremapping)
| |
− | self:updateButton()
| |
− | return
| |
− | end
| |
− | local keycode = e.keyCode
| |
− | local key = keyNames[keycode]
| |
− | if (keyNames[keycode] or 0) == 0 then key = utf8.char(keycode) end
| |
− | self.btns[self.selector]:changeText(key)
| |
− | if self.selector == 1 then g_keyup = keycode -- follows self.btns order
| |
− | elseif self.selector == 2 then g_keyleft = keycode -- follows self.btns order
| |
− | elseif self.selector == 3 then g_keyright = keycode -- follows self.btns order
| |
− | elseif self.selector == 4 then g_keydown = keycode -- follows self.btns order
| |
− | elseif self.selector == 5 then g_keyaction1 = keycode -- follows self.btns order
| |
− | elseif self.selector == 6 then g_keyaction2 = keycode -- follows self.btns order
| |
− | elseif self.selector == 7 then g_keyaction3 = keycode -- follows self.btns order
| |
− | end
| |
− | self.isremapping = false
| |
− | self:remapKey(self.isremapping)
| |
− | self:updateButton()
| |
− | mySavePrefs(g_configfilepath)
| |
− | else -- NOT KEY REMAPPING
| |
− | if e.keyCode == KeyCode.ESC then self:back() end
| |
− | -- keyboard
| |
− | if e.keyCode == KeyCode.UP or e.keyCode == g_keyup or e.keyCode == KeyCode.LEFT or e.keyCode == g_keyleft then
| |
− | self.selector -= 1 if self.selector < 1 then self.selector = #self.btns end
| |
− | self:updateButton()
| |
− | elseif e.keyCode == KeyCode.DOWN or e.keyCode == g_keydown or e.keyCode == KeyCode.RIGHT or e.keyCode == g_keyright then
| |
− | self.selector += 1 if self.selector > #self.btns then self.selector = 1 end
| |
− | self:updateButton()
| |
− | end
| |
− | -- modifier
| |
− | local modifier = application:getKeyboardModifiers()
| |
− | local alt = (modifier & KeyCode.MODIFIER_ALT) > 0
| |
− | if not alt and (e.keyCode == KeyCode.ENTER or e.keyCode == KeyCode.SPACE or e.keyCode == g_keyaction1) then -- validate
| |
− | self:goto()
| |
− | end
| |
− | end
| |
− | end)
| |
− | end
| |
− |
| |
− | -- scenes navigation
| |
− | function Options:goto()
| |
− | for k, v in ipairs(self.btns) do
| |
− | if k == self.selector then
| |
− | if v.isdisabled then print("btn disabled!", k)
| |
− | elseif k >= 1 and k <= #self.btns-1 then self:remapKey(true) -- player1 controls/actions
| |
− | elseif k == #self.btns then self:back() -- last button is go back to menu scene
| |
− | else print("nothing here!", k)
| |
− | end
| |
− | end
| |
− | end
| |
− | end
| |
− | function Options:back()
| |
− | print("SWITCH TO MENU SCENE")
| |
− | -- scenemanager:changeScene("menu", 1, transitions[1], easings[3])
| |
− | end
| |
− |
| |
− | -- *** START THE SCENE ***
| |
− | stage:addChild(Options.new())
| |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |