Menu slide to the screen when the button is pressed

i tried to make a menu slide to the screen when the button is pressed with each button react to another button. it did work with the code i wrote. but it seems there is another efficient ways to that. or is it the only way to do that?

extends Control

var target : Vector2  = Vector2(0, 720)
var closed : Vector2 = Vector2(0, 720)
var slider_status = false
var target_node
var closed_node
var button_1_status = false
var button_2_status = false
var button_3_status = false
var button_4_status = false

@onready var parent_node = get_node(".")
@onready var upgrade_node = get_node("upgrade")
@onready var generator_node = get_node("generator")
@onready var upgrade_node2 = get_node("upgrade2")
@onready var generator_node2 = get_node("generator2")

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	if target_node != null :
		if closed_node != null :
			if (target_node.position - target).length() < 0.1 :
				target_node.position = target_node.position.lerp(target, delta * 30)
				closed_node = target_node
				target_node = null
				print(closed_node.position)
			else :
				target_node.position = target_node.position.lerp(target, delta * 30)
				closed_node.position = closed_node.position.lerp(closed, delta * 30)
		else :
			if (target_node.position - target).length() < 0.1 :
				closed_node = target_node
				target_node = null
				print(closed_node.position)
			else :
				target_node.position = target_node.position.lerp(target, delta * 30)


func _on_open_upgrade_pressed() -> void:
	target_node = upgrade_node
	if button_2_status or button_3_status or button_4_status :
		target = Vector2(0,270)
		closed = Vector2(0,720)
		button_1_status = true
		button_2_status = false
		button_3_status = false
		button_4_status = false
		parent_node.move_child(upgrade_node, 1)
	elif button_1_status :
		closed_node = null
		target = Vector2(0, 720)
		button_1_status = false
		parent_node.move_child(upgrade_node, 1)
	elif !button_1_status and closed_node != null :
		target = Vector2(0, 270)
		closed_node = null
		button_1_status = true
		parent_node.move_child(upgrade_node, 1)
	else :
		target = Vector2(0, 270)
		closed_node = null
		button_1_status = true
		parent_node.move_child(upgrade_node, 1)

func _on_open_generator_pressed() -> void:
	target_node = generator_node
	if button_1_status or button_3_status or button_4_status :
		target = Vector2(0,270)
		closed = Vector2(0,720)
		button_1_status = false
		button_2_status = true
		button_3_status = false
		button_4_status = false
		parent_node.move_child(generator_node, 1)
	elif button_2_status :
		closed_node = null
		target = Vector2(0, 720)
		button_2_status = false
		parent_node.move_child(generator_node, 1)
	elif !button_1_status and closed_node != null :
		target = Vector2(0, 270)
		closed_node = null
		button_2_status = true
		parent_node.move_child(generator_node, 1)
	else :
		target = Vector2(0, 270)
		closed_node = null
		button_2_status = true
		parent_node.move_child(generator_node, 1)

func _on_open_upgrade2_pressed() -> void:
	target_node = upgrade_node2
	if button_2_status or button_3_status or button_1_status :
		target = Vector2(0,270)
		closed = Vector2(0,720)
		button_1_status = false
		button_2_status = false
		button_3_status = false
		button_4_status = true
		parent_node.move_child(upgrade_node2, 1)
	elif button_4_status :
		closed_node = null
		target = Vector2(0, 720)
		button_4_status = false
		parent_node.move_child(upgrade_node2, 1)
	elif !button_4_status and closed_node != null :
		target = Vector2(0, 270)
		closed_node = null
		button_4_status = true
		parent_node.move_child(upgrade_node2, 1)
	else :
		target = Vector2(0, 270)
		closed_node = null
		button_4_status = true
		parent_node.move_child(upgrade_node2, 1)

func _on_open_generator2_pressed() -> void:
	target_node = generator_node2
	if button_1_status or button_2_status or button_4_status :
		target = Vector2(0,270)
		closed = Vector2(0,720)
		button_1_status = false
		button_2_status = false
		button_3_status = true
		button_4_status = false
		parent_node.move_child(generator_node2, 1)
	elif button_3_status :
		closed_node = null
		target = Vector2(0, 720)
		button_3_status = false
		parent_node.move_child(generator_node2, 1)
	elif !button_3_status and closed_node != null :
		target = Vector2(0, 270)
		closed_node = null
		button_3_status = true
		parent_node.move_child(generator_node2, 1)
	else :
		target = Vector2(0, 270)
		closed_node = null
		button_3_status = true
		parent_node.move_child(generator_node2, 1)

3 Likes

Create a function that takes in a Control or Panel node as its parameter, and then moves it either up or down. Then upon a button being pressed to open a panel, loop through every other panel (you could use an export array for this) and checks whether or not it is closed/open. If it is open, call the close function on it. If closed, skip it. Then after that for loop, open the panel associated with the given button pressed. The two key ideas is expand-ability and to minimize repetition. So using for loops for expand-ability, and separate repeated logic into functions to decrease repetition.

2 Likes

As @SpikeTrapBoomStudios said, using a function to avoid repetitions and scalability.
You could also have a variable open_panel which will take the index of opened panel from your array of panels, if -1 all are closed, otherwise one is opened and can be closed before opening thr new one.

2 Likes

heyy, @MIE1981
i see your point. what do you think about this new cleaned version

func _process(delta: float) -> void:
	if open_node != null :
		if (open_node.position - target).length() < 0.1 :
			open_node = null
		else :
			open_node.position = open_node.position.lerp(target, delta * 30)
	
	if closed_node != null :
		if (closed_node.position - closed).length() < 0.1 :
			closed_node = null
		else :
			closed_node.position = closed_node.position.lerp(closed, delta * 30)

func _open_panel(node) :
	open_node = node
	target = Vector2(0, 0)
	parent_node.move_child(node, 0)

func _check_panel_isOpen():
	for Control in get_children():
		if (Control.position - target).length() < 0.1 :
			closed_node = Control
			closed = Vector2(0,460)

func _on_button_1_pressed() -> void:
	_check_panel_isOpen()
	_open_panel(upgrade_node)

func _on_button_2_pressed() -> void:
	_check_panel_isOpen()
	_open_panel(generator_node)

func _on_button_3_pressed() -> void:
	_check_panel_isOpen()
	_open_panel(generator_node2)

func _on_button_4_pressed() -> void:
	_check_panel_isOpen()
	_open_panel(upgrade_node2)

Can’t you use a Tween node to open and close panels?

Also, you could do without the loop to check opened panel:

(I’m on my phone, not easy to write code)

var opened_panel: MyPanel

func _on_button_1_pressed() -> void:
	_open_panel(upgrade_node)

func _open_panel(new_panel: MyPanel) -> void:
	# check if a panel is opened, then closes it
	if opened_panel != null:
		opened_panel.close()
	# affect panel to open (new_panel) to open_panel
	opened_panel = new_panel
	# open new panel
	opened_panel.open()


And in you MyPanel class, you have a open and close function that calls a Tween on self, or an AnimationPlayer.

Or if you want simultaneously open and close, use the Tween in the _open_panel function, with parallel function.

1 Like