Menu.gd WIP! (= base class for menus

This commit is contained in:
Harmony Honey 2024-01-28 03:08:50 -05:00
parent f7e173385f
commit c6574613bb
10 changed files with 194 additions and 182 deletions

View file

@ -49,6 +49,11 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://src/menu/options/Key.gd"
}, {
"base": "Node",
"class": "Menu",
"language": "GDScript",
"path": "res://src/menu/Menu.gd"
}, {
"base": "Actor",
"class": "Passthrough",
"language": "GDScript",
@ -78,6 +83,7 @@ _global_script_class_icons={
"EditorTheme": "",
"Exit": "",
"Key": "",
"Menu": "",
"Passthrough": "",
"Player": "",
"Switch": "",
@ -180,6 +186,30 @@ ui_focus_prev={
"deadzone": 0.5,
"events": [ ]
}
ui_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
ui_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
ui_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
ui_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
ui_page_up={
"deadzone": 0.5,
"events": [ ]
@ -196,30 +226,6 @@ ui_end={
"deadzone": 0.5,
"events": [ ]
}
ui_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
ui_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
ui_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
ui_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
ui_pause={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"physical_scancode":0,"unicode":0,"echo":false,"script":null)

View file

@ -1,35 +1,13 @@
extends CanvasLayer
extends Menu
var is_paused := false
export var path_parent : NodePath = ""
onready var node_parent : CanvasItem = get_node(path_parent)
export var path_cursor : NodePath = ""
onready var node_cursor : Control = get_node(path_cursor)
export var path_list : NodePath = ""
onready var node_list := get_node(path_list)
onready var menu_list : Array = node_list.get_children()
export var color_on := Color.white
export var color_off := Color(0.8,0.8,0.8,1.0)
export var cursor_offset := Vector2.ZERO
export var cursor_expand := Vector2.ZERO
var cursor := 0
var timer := 0.1 # prevent input overlap
var clock := 0.0
signal pause
signal unpause
func _ready():
node_parent.visible = false
set_cursor()
func _physics_process(delta):
if clock != 0:
clock = max(0, clock - delta)
@ -43,22 +21,11 @@ func _input(event):
if clock == 0 and Shared.is_in_game and !Wipe.is_wipe:
if event.is_action_pressed("ui_pause"):
toggle_pause()
if is_paused:
if event.is_action_pressed("ui_no"):
toggle_pause()
elif event.is_action_pressed("ui_yes"):
select()
else:
var up = event.is_action_pressed("ui_up")# or event.is_action_pressed("left")
var down = event.is_action_pressed("ui_down")# or event.is_action_pressed("right")
if up or down:
set_cursor(cursor + (-1 if up else 1))
Audio.play("menu_scroll", 0.8, 1.2)
func toggle_pause():
is_paused = !is_paused
node_parent.visible = is_paused
open(is_paused)
UI.keys(true, is_paused, is_paused, is_paused, is_paused)
UI.stats.visible = is_paused
TouchScreen.turn_arrows(is_paused)
@ -73,16 +40,10 @@ func toggle_pause():
emit_signal("unpause")
Audio.play("menu_pick", 0.9, 1.1)
func btn_no():
toggle_pause()
func set_cursor(arg = 0):
cursor = clamp(arg, 0, menu_list.size() - 1)
node_cursor.rect_global_position = cursor_offset + menu_list[cursor].rect_global_position - (cursor_expand * 0.5)
node_cursor.rect_size = menu_list[cursor].rect_size + cursor_expand
for i in menu_list.size():
menu_list[i].modulate = color_on if cursor == i else color_off
func select():
func btn_yes():
match cursor:
0:
toggle_pause()

View file

@ -24,12 +24,13 @@ script = ExtResource( 3 )
__meta__ = {
"_edit_horizontal_guides_": [ -19.0 ]
}
path_parent = NodePath("Control")
path_cursor = NodePath("Control/Cursor")
path_list = NodePath("Control/Center/VBox/List")
color_off = Color( 0.639216, 0.65098, 0.8, 1 )
cursor_offset = Vector2( -1, 0 )
parent_path = NodePath(".")
list_path = NodePath("Control/Center/VBox/List")
cursor_path = NodePath("Control/Cursor")
cursor_expand = Vector2( 9, 8 )
is_audio_scroll = true
is_color = true
color_off = Color( 0.639216, 0.65098, 0.8, 1 )
[node name="Control" type="Control" parent="."]
rect_min_size = Vector2( 228, 128 )

View file

@ -36,13 +36,13 @@ func _ready():
stats.visible = false
func keys(is_expand := true, _top := false, _arrows := true, _x := true, _c := true, _stack := false, _v := false):
spacer.size_flags_horizontal = spacer.SIZE_EXPAND_FILL if is_expand else spacer.SIZE_FILL
top.visible = _top
arrows.visible = _arrows
x.visible = _x
c.visible = _c
bottom.columns = 2 if _stack or !_arrows else 3
v.visible = _v
if spacer: spacer.size_flags_horizontal = spacer.SIZE_EXPAND_FILL if is_expand else spacer.SIZE_FILL
if top: top.visible = _top
if arrows: arrows.visible = _arrows
if x: x.visible = _x
if c: c.visible = _c
if bottom: bottom.columns = 2 if _stack or !_arrows else 3
if v: v.visible = _v
func labels(_x := "pick", _c := "back", _pause := "pause", _v := "clear"):
x_label.text = _x

127
src/menu/Menu.gd Normal file
View file

@ -0,0 +1,127 @@
extends Node
class_name Menu
export var is_open = false
export var parent_path : NodePath = ""
onready var parent_node = get_node_or_null(parent_path)
export var list_path : NodePath = ""
onready var list_node : Control = get_node_or_null(list_path)
onready var list := []
export var cursor_path : NodePath = ""
onready var cursor_node : Control = get_node_or_null(cursor_path)
export var cursor := 0 setget set_cursor
export var cursor_expand := Vector2.ZERO
export var cursor_lerp := 0.2
export var is_audio_scroll = false
export var scroll_path : NodePath = ""
onready var scroll_node : Control = get_node_or_null(scroll_path)
var last_menu = null
var open_clock := 0.0
export var open_time := 0.1
export var is_close_btn_no := false
export var is_color := false
export var color_on := Color.white
export var color_off := Color(0.8,0.8,0.8,1.0)
export var ui_expand := true
export var ui_top := false
export var ui_arrows := true
export var ui_x := true
export var ui_c := true
export var ui_stack := false
export var ui_v := false
func _ready():
if list_node: list = list_node.get_children()
open(false)
func _input(event):
menu_input(event)
func menu_input(event):
if !is_open or open_clock > 0 or Wipe.is_wipe: return
var b_del : bool = event.is_action_pressed("ui_del")
var b_pause : bool = event.is_action_pressed("ui_pause")
var b_no : bool = event.is_action_pressed("ui_no")
var b_yes : bool = event.is_action_pressed("ui_yes")
var b_x = btn.p("ui_right") - btn.p("ui_left")
var b_y = btn.p("ui_down") - btn.p("ui_up")
if b_del: btn_del()
elif b_no: btn_no()
elif b_yes: btn_yes()
elif b_y != 0: btn_y(b_y)
elif b_x != 0: btn_x(b_x)
func btn_del():
pass
func btn_no():
if is_close_btn_no:
open(false)
func btn_yes():
if list.size() > cursor and list[cursor].has_method("act"):
list[cursor].act()
func btn_y(arg := 0):
if arg != 0:
self.cursor += arg
if is_audio_scroll:
Audio.play("menu_scroll", 0.8, 1.2)
func btn_x(arg):
if list[cursor].has_method("scroll"):
list[cursor].scroll(arg)
func _physics_process(delta):
menu_process(delta)
func menu_process(delta):
open_clock = max(0, open_clock - delta)
if is_instance_valid(cursor_node) and list.size() > cursor:
cursor_node.rect_size = cursor_node.rect_size.linear_interpolate(list[cursor].rect_size + cursor_expand, cursor_lerp)
cursor_node.rect_global_position = cursor_node.rect_global_position.linear_interpolate(list[cursor].rect_global_position - (cursor_expand * 0.5), cursor_lerp)
if is_instance_valid(scroll_node):
scroll_node.rect_position.y = 64 - cursor_node.rect_position.y - (cursor_node.rect_size.y * 0.5)
func set_cursor(arg := cursor):
if list.size() > cursor and list[cursor].has_method("deselect"): list[cursor].deselect()
cursor = clamp(arg, 0, list.size() - 1)
if list.size() > cursor and list[cursor].has_method("select"): list[cursor].select()
if is_color:
for i in list.size():
list[i].modulate = color_on if i == cursor else color_off
func open(arg := false, _last = null):
is_open = arg
if is_instance_valid(_last):
last_menu = _last
if parent_node and parent_node.get("visible") != null:
parent_node.visible = is_open
if is_open:
set_cursor(0)
UI.keys(ui_expand, ui_top, ui_arrows, ui_x, ui_c, ui_stack, ui_v)
elif is_instance_valid(last_menu) and last_menu.has_method("resume"):
last_menu.resume()
open_clock = open_time
on_open()
func on_open():
pass

View file

@ -210,7 +210,7 @@ font_data = ExtResource( 23 )
1/shapes = [ ]
1/z_index = 0
[sub_resource type="TileSet" id=17]
[sub_resource type="TileSet" id=19]
4/name = "bricks.png 4"
4/texture = ExtResource( 18 )
4/tex_offset = Vector2( 0, 0 )
@ -873,7 +873,7 @@ tile_data = PoolIntArray( 393222, 0, 0, 393223, 0, 1, 393224, 0, 0, 393225, 0, 1
[node name="DetailTileMap" parent="Stage" instance=ExtResource( 8 )]
z_index = -11
tile_set = SubResource( 17 )
tile_set = SubResource( 19 )
tile_data = PoolIntArray( 131093, 536870916, 3, 131094, 4, 1, 131095, 4, 0, 131096, 4, 3, 196624, 5, 2, 196625, 5, 0, 196626, -1610612731, 2, 196630, 536870916, 0, 196631, 4, 1, 196632, 4, 0, 262154, 536870916, 3, 262155, 536870916, 0, 262156, 4, 3, 262159, 5, 2, 262160, 5, 0, 262161, 5, 0, 262162, 5, 0, 262163, -1610612731, 2, 262166, 4, 1, 262167, 4, 0, 262168, 4, 1, 327685, 5, 2, 327686, 5, 0, 327687, 5, 0, 327688, 5, 0, 327689, 536870917, 2, 327690, 536870916, 0, 327691, 4, 1, 327692, 4, 0, 327695, -1610612731, 0, 327696, 5, 0, 327697, 5, 0, 327698, 5, 0, 327699, -1073741819, 0, 327701, 536870916, 3, 327702, 4, 0, 327703, 4, 1, 327704, 536870916, 2, 393221, -1073741819, 0, 393227, 4, 1, 393228, 4, 0, 393229, 4, 3, 393231, -1073741819, 2, 393232, 5, 0, 393233, 5, 0, 393234, 5, 0, 393235, -536870907, 2, 393237, 536870916, 0, 393238, 4, 1, 393239, 536870916, 0, 458757, -1073741819, 2, 458759, -1610612731, 2, 458762, 4, 1, 458763, 536870916, 0, 458764, 4, 1, 458765, 4, 0, 458768, -1073741819, 2, 458769, 5, 0, 458770, 1610612741, 2, 458773, 4, 2, 458774, 4, 0, 458775, 4, 1, 458776, 4, 3, 524295, -1610612731, 0, 524298, 4, 2, 524299, 4, 1, 524300, 536870916, 0, 524301, 4, 1, 524302, 4, 3, 524305, 6, 0, 524310, 4, 2, 524311, 536870916, 0, 524312, 536870916, 2, 589831, -1610612730, 0, 589832, -1610612731, 0, 589836, 4, 2, 589837, 4, 1, 589838, 4, 0, 589839, 4, 3, 589841, 6, 0, 589842, -536870907, 2, 655367, -1610612731, 0, 655373, 536870916, 3, 655374, 4, 1, 655375, 536870916, 0, 655377, 6, 0, 720901, -2147483643, 2, 720903, -536870907, 2, 720905, 5, 2, 720906, 5, 0, 720907, 5, 0, 720908, 536870917, 2, 720909, 536870916, 3, 720910, 536870916, 0, 720911, 536870916, 2, 720912, 5, 2, 720913, 6, 0, 720914, 5, 0, 720915, 536870917, 2, 720917, 5, 2, 720918, 5, 0, 720919, 536870917, 2, 786437, -2147483643, 0, 786441, -1073741819, 0, 786455, -1610612731, 0, 851973, -1073741819, 2, 851974, 1610612741, 2, 851977, 1073741829, 2, 851978, 5, 0, 851979, 1610612741, 2, 851982, 4, 1, 851983, 4, 0, 851987, 1073741829, 2, 851988, 5, 0, 851989, 6, 0, 851990, 5, 0, 851991, -536870907, 2, 917517, 536870916, 0, 917518, 4, 1, 917519, 536870916, 2, 917525, 1610612741, 2, 983053, 4, 2, 983054, 4, 0, 983055, 536870916, 2 )
[node name="GameCamera" parent="Stage" instance=ExtResource( 13 )]

View file

@ -1,27 +1,17 @@
extends CanvasLayer
extends Menu
var is_open = false
onready var default_keys := {}
export var is_gamepad := false
export var scroll_path : NodePath = ""
onready var scroll_node := get_node_or_null(scroll_path)
onready var popup := $PopUp
var is_rebind := false
onready var list_node := $Control/VBox
export var row_path : NodePath = ""
onready var row_dupe := get_node_or_null(row_path).duplicate()
export var label_path : NodePath = ""
onready var label_dupe := get_node_or_null(label_path).duplicate()
var cursor := 0 setget set_cursor
onready var cursor_node := $Control/Cursor
export var cursor_expand := Vector2.ZERO
export var cursor_lerp := 0.2
var list := []
var actions := []
export var keys_action := {
@ -52,7 +42,6 @@ func _ready():
for i in [row_path, label_path]:
get_node(i).queue_free()
open(false)
popup.visible = false
# get default key binds
@ -60,6 +49,7 @@ func _ready():
default_keys[i] = InputMap.get_action_list(i)
# setup list
list = []
for i in keys_action.keys():
var h = i.begins_with("h_")
var b = i.begins_with("b_")
@ -80,7 +70,7 @@ func _ready():
set_cursor()
func _input(event):
func menu_input(event):
if !is_open or Wipe.is_wipe: return
var is_del : bool = event.is_action_pressed("ui_del")
@ -121,29 +111,15 @@ func _input(event):
self.cursor += btny
Audio.play("menu_scroll", 0.8, 1.2)
func _physics_process(delta):
if is_instance_valid(cursor_node):
cursor_node.rect_size = cursor_node.rect_size.linear_interpolate(list[cursor].rect_size + cursor_expand, cursor_lerp)
cursor_node.rect_global_position = cursor_node.rect_global_position.linear_interpolate(list[cursor].rect_global_position - (cursor_expand * 0.5), cursor_lerp)
if is_instance_valid(scroll_node):
scroll_node.rect_position.y = 64 - cursor_node.rect_position.y - (cursor_node.rect_size.y * 0.5)
func ui_keys():
UI.keys(true, false, !is_rebind, !is_rebind, !is_rebind, false, true)
func open(arg := false):
is_open = arg
visible = is_open
func on_open():
if is_open:
set_cursor(0)
ui_keys()
UI.labels()
func set_cursor(arg := cursor):
cursor = clamp(arg, 0, list.size() - 1)
func fill_row(row, action):
var a = get_action_list_is_type(action)
var k := []

View file

@ -14,10 +14,14 @@ font_data = ExtResource( 1 )
[node name="KeyMenu" type="CanvasLayer"]
script = ExtResource( 3 )
parent_path = NodePath(".")
list_path = NodePath("Control/VBox")
cursor_path = NodePath("Control/Cursor")
cursor_expand = Vector2( 4, 4 )
is_audio_scroll = true
scroll_path = NodePath("Control")
row_path = NodePath("Control/VBox/Row")
label_path = NodePath("Control/VBox/Label")
cursor_expand = Vector2( 4, 4 )
[node name="Back" type="ColorRect" parent="."]
modulate = Color( 0, 0, 0, 0.5 )

View file

@ -1,69 +0,0 @@
extends CanvasLayer
onready var node_cursor : ColorRect = $Center/Control/Cursor
onready var menu_items : Array = $Center/Control/MenuItems.get_children()
var cursor := 0
export var is_open := false
var input_clock := 0.0
export var input_cooldown := 0.1
var last_menu = null
func _ready():
visible = false
select_item(0)
func _input(event):
if !is_open or Wipe.is_wipe or input_clock > 0: return
var up = event.is_action_pressed("ui_up")
var down = event.is_action_pressed("ui_down")
var left = event.is_action_pressed("ui_left")
var right = event.is_action_pressed("ui_right")
var yes = event.is_action_pressed("ui_yes")
var no = event.is_action_pressed("ui_no")
if up or down:
select_item(cursor + (-1 if up else 1))
Audio.play("menu_scroll", 0.8, 1.2)
elif yes:
if menu_items[cursor].has_method("act"):
menu_items[cursor].act()
elif left or right:
var btnx = -1 if left else 1
if menu_items[cursor].has_method("scroll"):
menu_items[cursor].scroll(btnx)
elif no:
open(false)
func _physics_process(delta):
input_clock = max(0, input_clock - delta)
func select_item(arg := 0):
if menu_items[cursor].has_method("deselect"):
menu_items[cursor].deselect()
cursor = clamp(arg, 0, menu_items.size() - 1)
node_cursor.rect_global_position = menu_items[cursor].rect_global_position - Vector2(2, 2)
node_cursor.rect_size = menu_items[cursor].rect_size + Vector2(4, 4)
if menu_items[cursor].has_method("select"):
menu_items[cursor].select()
func open(arg := is_open, _last = null):
is_open = arg
if is_instance_valid(_last):
last_menu = _last
visible = is_open
input_clock = input_cooldown
select_item()
if is_open:
UI.keys(true)
if !is_open and is_instance_valid(last_menu) and last_menu.has_method("resume"):
last_menu.resume()

View file

@ -1,6 +1,6 @@
[gd_scene load_steps=12 format=2]
[ext_resource path="res://src/menu/options/OptionsMenu.gd" type="Script" id=1]
[ext_resource path="res://src/menu/Menu.gd" type="Script" id=1]
[ext_resource path="res://src/menu/options/Volume.tscn" type="PackedScene" id=2]
[ext_resource path="res://src/menu/options/OpenKeyMenu.gd" type="Script" id=3]
[ext_resource path="res://src/menu/Blink.gd" type="Script" id=4]
@ -18,6 +18,12 @@ font_data = ExtResource( 8 )
[node name="OptionsMenu" type="CanvasLayer"]
pause_mode = 2
script = ExtResource( 1 )
parent_path = NodePath(".")
list_path = NodePath("Center/Control/MenuItems")
cursor_path = NodePath("Center/Control/Cursor")
cursor_expand = Vector2( 4, 4 )
is_audio_scroll = true
is_close_btn_no = true
[node name="Back" type="ColorRect" parent="."]
modulate = Color( 0, 0, 0, 0.5 )