How can I set the door opening and closing in 2d space in my script?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Bran_coder

How can I set the door opening and closing in 2d space in my script? I need some condition that when the player comes to area2d only then can I open/close the door. And how can I use only one key, e.g. “E” for both opening and closing? Now I have “E” to open the door and “Q” to close the door. Can anyone help please?

:bust_in_silhouette: Reply From: Wakatta

Use a toggled bool var

# Area.gd
extends Area2D

var can_open_door = false
var door_opened = false

# connect area signal
func _on_body_entered(body):
    if body == $Player:
        can_open_door = true

# connect area signal
func _on_body_exited(body):
    if body == $Player:
        can_open_door = false

func _input(event):
    if event is InputEventKey:
        if event.scancode == KEY_E and can_open_door:
            if door_opened:
                close_door()
            else:
                open_door()

            # Toggle door_open bool
             door_opened = !door_opened
        

Thank you Wakatta, but it doesn´t work…in func _input(event): close_door() and open_door() is not declared.

Bran_coder | 2022-10-17 14:16

Those are place holder functions for what you actually want to happen during the close and open events of your door.

For example

  • Play an animation
  • Change scenes
  • Transport an object

As your project is now all the code you have when the E key is pressed replace open_door() with that and replace close_door() with the code you have when the Q is pressed

Wakatta | 2022-10-17 14:41

I have: KinematicBody2D - Player, StaticBody2D - Door, Area2D - Door.
When I come to the door, interact is playing and I can use key E to open door, CollisionShape2D is dissabled and player can go through th door. But I can open and close the door, when player is not near the door. I have signal already between player and area2D on interact. I have script on Player and StaticBody2D - Door. I think, that only need some code to (extends StaticBody2D) func _get_input() or func _physics_process(_delta).

Bran_coder | 2022-10-17 16:18

I just need something for the engine to recognize that when the player interacts with the door, only then can the E or Q keys be used.

Bran_coder | 2022-10-17 16:18

There are a lot of ways to achieve what you want to-do but that all depends on where in your project you want to make those checks.

If you share the code you currently have will be able to assist you further otherwise you can use the above code attached to all of your Door (Area2D) nodes.

Wakatta | 2022-10-17 22:47

Here is code:

extends StaticBody2D # This is Safety_gate.

func get_input():
if Input.is_action_just_pressed(“interact”):
$Safety_gate.play(“Safety_gate_open”)
$CollisionShape2D_Safety_Gate.disabled = true
$Safety_gate_sound.play()

elif Input.is_action_just_pressed(“close”):
$Safety_gate.play(“Safety_gate_close”)
$CollisionShape2D_Safety_Gate.disabled = false
$Safety_gate_sound.play()

func _physics_process(_delta):
if $“…/Player/Interact”.visible:
get_input()

Now, I need use only “E” key to open and close Safety_gate. If the player is at the door and the interact is visible after pressing the “E” key the Safety_gate will open, and then after pressing the “E” key the Safety_gate will close. Safety_gate is AnimatedSprite, 4 frames is playing - Safety_gate_open. Safety_gate_close is playing backwards.

Bran_coder | 2022-10-18 18:06

extends StaticBody2D # This is Safety_gate.

func get_input():
    if Input.is_action_just_pressed("interact"):
        if $CollisionShape2DSafetyGate.disabled:
            $Safetygate.play("Safetygateclose")
            $CollisionShape2DSafetyGate.disabled = false
        else:
            $Safetygate.play("Safetygateopen")
            $CollisionShape2DSafetyGate.disabled = true
        $Safetygate_sound.play()        

func _physics_process(delta):
    if $"../Player/Interact".visible:
        get_input()

Wakatta | 2022-10-21 06:39

Thank you Wakatta, but I did it my way and it’s functional. Now, I have problem with Safety_gates in game, because I have three Safety_gates and when I’m pressing key “E”, I’m opening all three Safety_gates, but I want to open only one Safety_gate when player is interacting with the current Safety_gate in Area2D. I need the Safety_gates to open individually and independently of each other. How should I proceed in the script? Do you have any solution?

Thank you.

Bran_coder | 2022-10-21 14:30

Which is why it is recommended to use Signals with your code

extends StaticBody2D # This is Safety_gate.

var can_open_door = false

func _ready():
    $Door.connect("body_entered", self, "_on_body_entered")
    $Door.connect("body_exited", self, "_on_body_exited")

func get_input():
    if Input.is_action_just_pressed("interact"):
        if $CollisionShape2DSafetyGate.disabled:
            $Safetygate.play("Safetygateclose")
            $CollisionShape2DSafetyGate.disabled = false
        else:
            $Safetygate.play("Safetygateopen")
            $CollisionShape2DSafetyGate.disabled = true
        $Safetygate_sound.play()        

func _physics_process(delta):
    if $"../Player/Interact".visible and can_open_door:
        get_input()

func _on_body_entered(body):
    if body == $"../Player":
        can_open_door = true

func _on_body_exited(body):
    if body == $"../Player":
        can_open_door = false

Assuming your node tree looks like this

 ┖╴Game
    ┠╴Player - KinematicBody2D
    ┃  ┖╴Interact - StaticBody2D
    ┃  
    ┠╴Door - StaticBody2D (Safety_gate.gd)
    ┃  ┖╴Door - Area2D
    ┠╴Door2 - StaticBody2D (Safety_gate.gd)
    ┃  ┖╴Door - Area2D
    ┖╴Door3 - StaticBody2D (Safety_gate.gd)

Wakatta | 2022-11-01 12:04