1. 创建节点,搭建房屋

需要将对应的Collision Layer设置为1

image-20260211211517240
image-20260211211517240

2. 绘制碰撞区域

在TileSet设置中选择指定节点,首先需要绘制区域,就是对应着Physics Layer0

image-20260211211628118
image-20260211211628118

然后选择物理层进行绘制

image-20260211211754802
image-20260211211754802

创建家具,可以采用同一个素材,shift可以多选

image-20260211213325208
image-20260211213325208

按照之前的步骤一样进行区域绘制

image-20260211213444557
image-20260211213444557

image-20260211214309091
image-20260211214309091

然后我们会发现人物太大了,进不去,可以考虑缩小人物框体

然后可以直接复用tileset,里面有导入场景功能,直接拖进来

image-20260211215405624
image-20260211215405624

可在调试中打开碰撞区域

image-20260211215527625
image-20260211215527625

接下来就是门的绘制,门有开、关等状态

3. 门开、关

创建一个StaticBody2D+Sprite2d 门的动画

image-20260212202227116
image-20260212202227116

可以直接按照开门动作进行帧的绘制,需要进行开门、关门、默认帧动画

image-20260212202431424
image-20260212202431424

再创建对应的碰撞体,但是我们需要这个碰撞体在地面层上面

image-20260212202603992
image-20260212202603992

将任务设置为固定的图层,这样就可以发生碰撞

image-20260212203009431
image-20260212203009431

在之前缺门的场景增加门,需要和墙的位置一致

image-20260212204516092
image-20260212204516092

可交互大门,创建新的Area2d,用于交互,需要实现对应的信号、body进入、body出去相关代码

image-20260212205016189
image-20260212205016189

class_name IteractableComponent
extends Area2D
signal interactable_actived
signal interactable_deactived
func _on_body_entered(body: Node2D) -> void:
interactable_actived.emit();
func _on_body_exited(body: Node2D) -> void:
interactable_deactived.emit();

image-20260212212232340
image-20260212212232340

需要创建新的图层和player进行交互,之前我们设置player为图层2,此时门的交互已经可以了,我们只需要将这个绑定到门即可,其中这个碰撞区域需要大一些,因为我们做的是检测门的开关位置是否有人,有人就自动进行开门。

image-20260212205558222
image-20260212205558222

接下来就是创建门的脚本,选中组件移动,然后按住ctrl即可自动引用

extends StaticBody2D
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
@onready var interactable_componet: IteractableComponent = $InteractableComponet
func _ready() -> void:
# 绑定信号
interactable_componet.interactable_actived.connect(on_interactable_actived);
interactable_componet.interactable_deactived.connect(on_interactable_deactived);
func on_interactable_actived() ->void:
animated_sprite_2d.play("open_door")
func on_interactable_deactived()->void:
animated_sprite_2d.play("close_door")

然后发现因为碰撞体,人物无法进出,最简单的方式是动态图层,和人物一层

extends StaticBody2D
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
@onready var interactable_componet: IteractableComponent = $InteractableComponet
func _ready() -> void:
# 绑定信号
interactable_componet.interactable_actived.connect(on_interactable_actived);
interactable_componet.interactable_deactived.connect(on_interactable_deactived);
collision_layer = 1
func on_interactable_actived() ->void:
animated_sprite_2d.play("open_door")
collision_layer = 2
func on_interactable_deactived()->void:
animated_sprite_2d.play("close_door")
collision_layer = 2