How to make a sprite show and be closable with the same key?

Godot Version

4.6

Question

Hello :smiley:

im trying to have it so that my player can open a letter, and close it with the same key once theyre done reading it. My problem is, though, that its calling the open and close function at the same time and i dont know how to stop it, so the letter never opens (Visually, i mean). How do I make it wait for another press of E rather than taking the same one?

@onready var label = $"../../CanvasLayer/may_entrance"
@onready var sprite = $"../../May_letter"
@onready var visibleletter = false
@onready var room_entrance_entered = false


func _on_area_entered(area: Area2D) -> void:
	room_entrance_entered = true
	
func _process(delta: float) -> void:
	if room_entrance_entered:
		letter_opened()
		close_letter()

func letter_opened():
	if Globals.friendship_may == 10:
		Globals.may_open = true
	if Globals.may_open:
		label.show()
		if Input.is_action_just_pressed("interact"):
	       get_tree().change_scene_to_file("res://scenes/rooms/may_room.tscn")
	label.show()

	if Input.is_action_just_pressed("interact"):
		if visibleletter == false:
			sprite.visible = true
			Globals.locked = true
			visibleletter = true

func close_letter():
	if visibleletter:
		if Input.is_action_just_pressed("interact"):
			sprite.visible = false
			Globals.locked = false
			visibleletter = false


(I did try doing something to this line of code:

func _process(delta: float) -> void:
	if room_entrance_entered:
		letter_opened()
		close_letter()

to turn it into this:

func _process(delta: float) -> void:
	if room_entrance_entered:
		letter_opened()
		if letter_opened():
			close_letter()

but then, when I opened it, it wouldn’t close.)

You need to rewrite this code to make easier to follow.

Make an open_letter() method similar to the close_letter() and have the visible_letter tested in _process().

Here is a simplified example:

extends Node2D

# Called when the node enters the scene tree for the first time.
func _ready():
	room_entrance_entered = true
	pass # Replace with function body.


#@onready var label = $"../../CanvasLayer/may_entrance"
#@onready var sprite = $"../../May_letter"
@onready var visibleletter = false
@onready var room_entrance_entered = false


func _on_area_entered(area: Area2D) -> void:
	room_entrance_entered = true
	
func _process(delta: float) -> void:
	if room_entrance_entered:
		if Input.is_action_just_pressed("ui_right"):
			if not visibleletter:
				open_letter()
			else:
				close_letter()

func open_letter():
	#sprite.visible = true
	print("OPEN LETTER")
	visibleletter = true

func close_letter():
	#sprite.visible = false
	print("CLOSE LETTER")
	visibleletter = false