这一节,我主要学习了场景切换的管理,跟以前的场景代码切换截然不同,实现的效果是进入场景之前屏幕变黑,进入后恢复正常。本节最后我将整理好的三种方法附到后面了。
一、新建场景和节点
新建CanvasLayer场景,命名为ScenceManage.tscn,保存到Scenes目录下。然后给根节点添加AnimationPlayer、ColorRect2个节点。AnimationPlayer用于播发屏幕透明到黑色,黑色到透明的动画。ColorRect用于使屏幕变黑。
二、设置节点
1.ColorRect设置
将ColorRect大小调整到跟屏幕大小相等,颜色设置为黑色。
2.AnimationPlayer设置
选择AnimationPlayer,在其动画面板中新建fadin,设置动画为0.3秒,第0秒的时候将ColorRect的Moulate属性a设置为0,表示透明,添加关键帧到动画;第0.3秒,将ColorRect的Moulate属性a设置为1,表示不透明,添加关键帧到动画。
3.添加代码
选择根目录,新建脚本命名为Scence_Manage.gd存在Scripts目录下。
编写如下代码:
extends CanvasLayer
@onready var animation_player = $AnimationPlayer
var current_scene = null #当前场景
func _ready() -> void:
$ColorRect.modulate.a=0
var root = get_tree().root #获取根节点
current_scene = root.get_child(root.get_child_count() - 1) #设置当前场景
#场景切换函数,第一个参数表示切换到对应场景的路径,参数二表示人公出现的位置
func switch_scene(res_path,chargePoint:Vector2):
call_deferred("_deferred_switch_scene", res_path,chargePoint)
#在空闲时调用该对象的_deferred_switch_scene方法。始终返回 null,不返回该方法的结果。
#真正切换场景函数,第一个参数表示切换到对应场景的路径,参数二表示人公出现的位置
func _deferred_switch_scene(res_path,chargePoint:Vector2):
animation_player.play("fadin")
await animation_player.animation_finished
current_scene.free()#释放当前场景
var scene = load(res_path)#载入新场景
current_scene = scene.instantiate()
get_tree().root.add_child(current_scene)#将场景添加到根目录
get_tree().current_scene = current_scene#当前场景设置为新的场景
if current_scene.has_node("Player"):#判断当前场景是否含有Player节点
current_scene.get_node("Player").position= chargePoint #果含有Player节点,设置主人公位置
animation_player.play_backwards("fadin")
三、自动加载
单击菜单栏选择项目->项目设置,在项目设置对话框切换到自动加载,然后选择scence_manage.tscn场景,添加到自动记载。
切换到door_room场景的根节点代码,在_on_room_info_body_entered函数添加如下代码:
ScenceManage.switch_scene("res://Scenes/underground.tscn",Vector2(191.0,288.0))
这样就完成了场景切换的代码,对我们以前的代码进行了一个优化。最后效果如下:
四、总结
其实,我整理了三种方面进行场景切换,我把他记录如下,以备后用。
第一种方法:
extends Node2D
@export var level_2_scene:PackedScene
func _on_level_2_button_pressed() -> void:
get_tree().change_scene_to_packed(level_2_scene)
第二种方法:
extends Node2D
func _on_level_1_button_pressed() -> void:
get_tree().change_scene_to_file("res://level_1.tscn")
第三种方法:
extends Node
var current_scene = null
func _ready() -> void:
var root = get_tree().root
current_scene = root.get_child(root.get_child_count() - 1)
func switch_scene(res_path):
call_deferred("_deferred_switch_scene", res_path)
func _deferred_switch_scene(res_path):
current_scene.free()
var s = load(res_path)
current_scene = s.instantiate()
get_tree().root.add_child(current_scene)
get_tree().current_scene = current_scene