Menu - Selection

Hello everyone.
Currently I am trying to implement a cursor to select the button and would like to have the cursor to be controlled using keys. However I have no idea to do so because based on my understanding the button is implemented using click and touch. Please refer to the image shown below.
Would you guys be able to provide some guides?
Thank you.

You are free to implement buttons and selections in any way you want. We do not decide for you how that is supposed to be done. Are you perhaps using a library or something?

Either way, add key up/down triggers and move the cursor up and down among your list of menu options. And space/enter to select the choice that is currently selected. Run the same code as if the button would have been pressed using the mouse/touch.

2 Likes

I do not know about library sir. But the cursor can be done using an image? or it has to be the actual cursor?

Do you want to replicate the FF7 menu style? That can all be done with images and a few lines of code.

1 Like

yes sir Pkeod, would you be able to show me the code? Thank you

If you need it using keys as an input, it won’t be difficult.
Just do something like this

local b = {–all my nodes}
local offset = vmath.vector3(-50, 0, 0) --distance of cursor from the buttons
local cursor = gui.get_node(“cursor”)
– set self.index to 1 in init
local function index(increment)
if self.index > #b then
self.index = 1
else if self.index < 0 then
self.index = #b
end

if increment then
self.index = self.index + 1
Else
self.index = self.index - 1
end
return self.index
end

– in input
if action_id == hash(“up”) then
gui.set_position(cursor, gui.get_position(b[index(true)]) + offset)
elseif action_id == hash(“down”) then
gui.set_position(cursor, gui.get_position(b[index(false)]) + offset)
end

(typing from mobile, so may have errors)
BTW am I the only one not seeing the write code button while replying :thinking:

2 Likes

okay thank you very much, I will try

Here’s a rough, hard coded menu recreation. For educational use only. If you do this kind of style then you can move a cursor around different marker nodes at irregular positions or spaced however you want. There’s room to improve and make the idea more generic too, such as make it so you design menus based on JSON data and it builds the menu and its trees of options automatically by cloneing GUI nodes and setting them up.

retromenu_example.zip (142.0 KB)

5 Likes

thank you very much sir for your time. I am really appreciate it.

3 Likes

@TheKing0x9 @Pkeod I will study the code that you guys have provided. I will share what I have learned once I have understand it sir. Thank you. :+1:

4 Likes

game.zip (141.9 KB)

Here’s a slight fix, I realized I moved the input around without updating the game.project. :slight_smile:

1 Like

thank you so much sir for your time

I have studied the code. I will try my best to explain each line of code based on my understanding. It may not perfect because I myself is a newcomer to Lua language and using Defold Engine. Thank you very much @Pkeod @TheKing0x9 for providing the code for myself to learn. And last but not least @britzl, thank you. Hope someone will find these information useful. :+1:

  1. the cursor is set the position to 1.The self.node_cursor = gui.get_node(“cursor”), find the data named as “cursor” at the gui and set it on the self.node_cursor. Applies the same for the data named as “text_newgame” and “text_continue”.

    function init(self)
    msg.post(".", "acquire_input_focus")
    self.cursor_position = 1
    

self.node_cursor=gui.get_node(“cursor”)
self.node_text_newgame = gui.get_node(“text_newgame”)
self.node_text_continue = gui.get_node(“text_continue”)
end

  1. if statement. if self.up means going up, decreases the value of self.cursor_position hold. then play the sound of cursor move. If the value of self.cursor_position is less than 1, set its value to 2. if the value of self.cursor_position is greater than 2,set its value to 1.

    function update(self, dt)
    if self.up then 
    	self.cursor_position = self.cursor_position - 1
    	msg.post("/audio#cursor_move", "play_sound")
    end
     if self.down then
    	self.cursor_position = self.cursor_position + 1
    	msg.post("/audio#cursor_move", "play_sound")
    if self.cursor_position < 1 then self.cursor_position = 2 end
    if self.cursor_position > 2 then self.cursor_position = 1 end
    

3.This is where the cursor is automatically set to the node named as New Game. That is why it is always point at “New Game”, because at init, the self.cursor_position is set as 1. if the value of self.cursor_position hold is 1, the cursor will point at “New Game”. Then when the value of self.cursor_position hold is 2, the cursor will point at “Continue?”.

if self.cursor_position == 1 then
    local position = gui.get_position(self.node_text_newgame)
    gui.set_position(self.node_cursor, position)
    end
     if self.cursor_position == 2 then
		local position = gui.get_position(self.node_text_continue)
		gui.set_position(self.node_cursor, position)
	end	


    self.up = false
    self.down = false
     end

4.Skip to the enter code. If the certain key is set as enter, then check if the value of self.cursor_position holds is 1, play the sound cursor_accept. Change the screen to game. Means its time to play game. Elseif the value of self.cursor_position holds is 2, play the sound cursor_accept. Change the screen to continue. Means load the game data based on the last save point. For an example, in Final Fantasy 7, if you guys saves at Gold Saucer area, then it loads at Gold Saucer area and so on.

function on_input(self, action_id, action)
	if action.released and action_id == hash("up") then
		self.up = true
	end
	if action.released and action_id == hash("down") then
		self.down = true
	end
	if action.released and action_id == hash("enter") then
		if self.cursor_position == 1 then 
		print(self.cursor_position)
		msg.post("/audio#cursor_accept", "play_sound")
		msg.post("main:/loader#script", "goto_game")
	elseif self.cursor_position == 2 then 
			print(self.cursor_position)
			msg.post("/audio#cursor_accept", "play_sound")
			msg.post("main:/loader#script", "goto_continue")
		end
	end
end
3 Likes