更新单向平台;更新角色重生点prop

This commit is contained in:
Reed 2026-01-08 14:15:38 +08:00
parent 27dcd5b8e6
commit c5c7248c0f
24 changed files with 278 additions and 26 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 B

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 B

After

Width:  |  Height:  |  Size: 445 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1767846541187" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6507" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M544 85.312v119.04a309.44 309.44 0 0 1 275.712 275.584l118.976 0.064v64h-119.04A309.44 309.44 0 0 1 544 819.712v118.976h-64v-119.04A309.44 309.44 0 0 1 204.224 544H85.312v-64h119.04a309.44 309.44 0 0 1 275.584-275.712L480 85.312h64zM512 266.688a245.312 245.312 0 1 0 0 490.624 245.312 245.312 0 0 0 0-490.624zM512 384a128 128 0 1 1 0 256 128 128 0 0 1 0-256z" fill="#8da5f3" p-id="6508"></path></svg>

After

Width:  |  Height:  |  Size: 733 B

View File

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://2e0o5lq5u7qj"
path="res://.godot/imported/player_respawn_icon.svg-8dcd220294d780ad8ee9d929e5c13a68.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/icon/player_respawn_icon.svg"
dest_files=["res://.godot/imported/player_respawn_icon.svg-8dcd220294d780ad8ee9d929e5c13a68.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -1,22 +1,16 @@
[gd_scene load_steps=8 format=3 uid="uid://3vc8ojbiyy5w"] [gd_scene load_steps=7 format=3 uid="uid://3vc8ojbiyy5w"]
[ext_resource type="Script" uid="uid://crgac4manhoud" path="res://_game/game.gd" id="1_yksyv"] [ext_resource type="Script" uid="uid://crgac4manhoud" path="res://_game/game.gd" id="1_yksyv"]
[ext_resource type="PackedScene" uid="uid://cvqehvdjpoar4" path="res://_player/player_controller.tscn" id="2_x2i0j"] [ext_resource type="PackedScene" uid="uid://cvqehvdjpoar4" path="res://_player/player_controller.tscn" id="2_x2i0j"]
[ext_resource type="PackedScene" uid="uid://gwhff4qaouxy" path="res://_player/Avatar.tscn" id="3_4ifj7"]
[ext_resource type="PackedScene" uid="uid://cd88ydqhdo28" path="res://_scene/level1/l1_s1.tscn" id="4_m1t3p"] [ext_resource type="PackedScene" uid="uid://cd88ydqhdo28" path="res://_scene/level1/l1_s1.tscn" id="4_m1t3p"]
[ext_resource type="PackedScene" uid="uid://djs1eg5y008cs" path="res://_scene/level1/l1_s2.tscn" id="5_5s0xe"] [ext_resource type="PackedScene" uid="uid://djs1eg5y008cs" path="res://_scene/level1/l1_s2.tscn" id="5_5s0xe"]
[ext_resource type="PackedScene" uid="uid://dh43kt0l28qd5" path="res://_scene/level1/l1_s3.tscn" id="6_ktxjv"] [ext_resource type="PackedScene" uid="uid://dh43kt0l28qd5" path="res://_scene/level1/l1_s3.tscn" id="6_ktxjv"]
[ext_resource type="PackedScene" uid="uid://br46ftt4v3bwm" path="res://_scene/level1/l1_s4_Es.tscn" id="7_x2i0j"] [ext_resource type="PackedScene" uid="uid://br46ftt4v3bwm" path="res://_scene/level1/l1_s4_Es.tscn" id="7_x2i0j"]
[node name="Game" type="Node2D"] [node name="Game" type="Node2D" groups=["PLAYER_RESPAWN"]]
script = ExtResource("1_yksyv") script = ExtResource("1_yksyv")
[node name="PlayerController" parent="." node_paths=PackedStringArray("auto_controlled_avatar") instance=ExtResource("2_x2i0j")] [node name="PlayerController" parent="." instance=ExtResource("2_x2i0j")]
auto_controlled_avatar = NodePath("../Avatar")
[node name="Avatar" parent="." instance=ExtResource("3_4ifj7")]
position = Vector2(1642, -548)
collision_mask = 4
[node name="L1_S1" parent="." instance=ExtResource("4_m1t3p")] [node name="L1_S1" parent="." instance=ExtResource("4_m1t3p")]

View File

@ -2,3 +2,5 @@ extends Node2D
func _ready() -> void: func _ready() -> void:
CameraSystem.register_player_camera(self) CameraSystem.register_player_camera(self)
get_tree().call_group(&"PLAYER_RESPAWN",&"respawn_avatar")

View File

@ -54,8 +54,9 @@ size = Vector2(10, 25)
[node name="Avatar" type="CharacterBody2D" groups=["PLAYER"]] [node name="Avatar" type="CharacterBody2D" groups=["PLAYER"]]
collision_layer = 2 collision_layer = 2
collision_mask = 0 collision_mask = 36
floor_snap_length = 4.0 floor_snap_length = 4.0
platform_floor_layers = 4
platform_wall_layers = 4 platform_wall_layers = 4
script = ExtResource("1_rkqpu") script = ExtResource("1_rkqpu")

View File

@ -26,7 +26,7 @@ var is_dead: bool = false:
is_dead = value is_dead = value
if is_dead: if is_dead:
locomotion_comp.is_active = false locomotion_comp.is_active = false
GlobalEvent.boradcast_player_dead_event() GlobalEvent.boradcast_player_dead_event(self)
player_dead.emit() player_dead.emit()
signal player_direction_changed(direction: Direction) signal player_direction_changed(direction: Direction)
@ -42,6 +42,9 @@ signal v_jump_dust
##跳跃声音特效 ##跳跃声音特效
signal s_jump_sound signal s_jump_sound
func _enter_tree() -> void:
GlobalEvent.register_player(self)
func _ready() -> void: func _ready() -> void:
self.player_direction_changed.connect(_handle_direction_changed) self.player_direction_changed.connect(_handle_direction_changed)
self.hit_box.area_entered.connect(_handle_hit_box_entered) self.hit_box.area_entered.connect(_handle_hit_box_entered)

View File

@ -8,6 +8,9 @@ var _controlled_avatar: Player
## 当前输入状态 ## 当前输入状态
var move_input: Vector2 = Vector2.ZERO var move_input: Vector2 = Vector2.ZERO
func _enter_tree() -> void:
GlobalEvent.register_player_controller(self)
func _ready() -> void: func _ready() -> void:
if auto_controlled_avatar: if auto_controlled_avatar:
bind_avatar(auto_controlled_avatar) bind_avatar(auto_controlled_avatar)
@ -18,8 +21,6 @@ func bind_avatar(p_avatar: Player) -> void:
##解绑avatar ##解绑avatar
func unbind_avatar() -> void: func unbind_avatar() -> void:
if not _controlled_avatar: return
_controlled_avatar = null _controlled_avatar = null
##解绑avatar ##解绑avatar

View File

@ -0,0 +1,104 @@
@tool
@icon("uid://2e0o5lq5u7qj")
class_name PlayerRespawnPoint
extends Node2D
var _can_respawn: bool = false
const avatar_scene := preload("res://_player/Avatar.tscn")
func _ready() -> void:
if not Engine.is_editor_hint():
GlobalEvent.player_dead.connect(_on_player_dead)
func _on_player_dead(player: Player) -> void:
call_deferred(&"respawn_avatar")
func _process(delta: float) -> void:
queue_redraw()
func _draw() -> void:
# 只在编辑器绘制
if not Engine.is_editor_hint():
return
var color := Color(0.2, 0.9, 0.4, 0.8)
var line_width := 2.0
# 尺寸参数(都可以微调)
var outer_radius := 16.0
var inner_gap := 6.0
var line_length := 10.0
var center_radius := 3.0
var center := Vector2.ZERO
# —— 外圈圆环 ——
draw_arc(
center,
outer_radius,
0.0,
TAU,
48, # 分段数,越大越圆
color,
line_width
)
# —— 准星十字 ——
# 上
draw_line(
center + Vector2(0, -inner_gap),
center + Vector2(0, -inner_gap - line_length),
color,
line_width
)
# 下
draw_line(
center + Vector2(0, inner_gap),
center + Vector2(0, inner_gap + line_length),
color,
line_width
)
# 左
draw_line(
center + Vector2(-inner_gap, 0),
center + Vector2(-inner_gap - line_length, 0),
color,
line_width
)
# 右
draw_line(
center + Vector2(inner_gap, 0),
center + Vector2(inner_gap + line_length, 0),
color,
line_width
)
# —— 中心圆点 ——
draw_circle(center, center_radius, color)
func push_respawner() -> void:
_can_respawn = true
func pop_respawner() -> void:
_can_respawn = false
func respawn_avatar() -> CharacterBody2D:
if not _can_respawn: return null
if not avatar_scene:
return null
var new_avatar : Player = avatar_scene.instantiate()
var pc : PlayerController = GlobalEvent.get_player_controller()
if not pc or not new_avatar:
return null
pc.unbind_avatar()
pc.bind_avatar(new_avatar)
new_avatar.position = self.global_position
get_tree().current_scene.add_child(new_avatar)
return new_avatar

View File

@ -0,0 +1 @@
uid://dybx7a7eirfg8

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://cxgcmdxlbwwjh"]
[ext_resource type="Script" uid="uid://dybx7a7eirfg8" path="res://_props/_prefabs/player/player_respawn_point.gd" id="1_x4u84"]
[node name="PlayerRespawnPoint" type="Node2D" groups=["PLAYER_RESPAWN"]]
script = ExtResource("1_x4u84")

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@
[ext_resource type="Script" uid="uid://dsgl7lbyjsiif" path="res://addons/reedscene/act/ActManager.gd" id="4_10cyl"] [ext_resource type="Script" uid="uid://dsgl7lbyjsiif" path="res://addons/reedscene/act/ActManager.gd" id="4_10cyl"]
[ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/SceneTrigger.gd" id="4_qrebp"] [ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/SceneTrigger.gd" id="4_qrebp"]
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_0xms0"] [ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_0xms0"]
[ext_resource type="Resource" uid="uid://gmaitie4ys4h" path="res://_shared/QuickTriggerConfig/player_entered_act_1.tres" id="5_qrebp"] [ext_resource type="Resource" uid="uid://gmaitie4ys4h" path="res://_shared/quick_scene_config/player_entered_act_1.tres" id="5_qrebp"]
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_agny0"] [ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_agny0"]
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_8ou3l"] [ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_8ou3l"]
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="8_dq7pn"] [ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="8_dq7pn"]

View File

@ -5,7 +5,7 @@
[ext_resource type="Script" uid="uid://dn0ksjoswquf5" path="res://addons/reedscene/scene/SceneManager.gd" id="3_uuej8"] [ext_resource type="Script" uid="uid://dn0ksjoswquf5" path="res://addons/reedscene/scene/SceneManager.gd" id="3_uuej8"]
[ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/SceneTrigger.gd" id="4_2v5hg"] [ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/SceneTrigger.gd" id="4_2v5hg"]
[ext_resource type="Script" uid="uid://dsgl7lbyjsiif" path="res://addons/reedscene/act/ActManager.gd" id="4_jlqvj"] [ext_resource type="Script" uid="uid://dsgl7lbyjsiif" path="res://addons/reedscene/act/ActManager.gd" id="4_jlqvj"]
[ext_resource type="Resource" uid="uid://cstjpy2eh8mck" path="res://_shared/QuickTriggerConfig/prop1_player_entered_act_1.tres" id="5_jlqvj"] [ext_resource type="Resource" uid="uid://cstjpy2eh8mck" path="res://_shared/quick_scene_config/prop1_player_entered_act_1.tres" id="5_jlqvj"]
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_vajwc"] [ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_vajwc"]
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_td1yf"] [ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_td1yf"]
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_pawhc"] [ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_pawhc"]

View File

@ -7,7 +7,7 @@
[ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/SceneTrigger.gd" id="4_sv1n5"] [ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/SceneTrigger.gd" id="4_sv1n5"]
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_dnt6f"] [ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_dnt6f"]
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="5_qtvqv"] [ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="5_qtvqv"]
[ext_resource type="Resource" uid="uid://gmaitie4ys4h" path="res://_shared/QuickTriggerConfig/player_entered_act_1.tres" id="5_sv1n5"] [ext_resource type="Resource" uid="uid://gmaitie4ys4h" path="res://_shared/quick_scene_config/player_entered_act_1.tres" id="5_sv1n5"]
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_qtvqv"] [ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_qtvqv"]
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="8_6bhoi"] [ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="8_6bhoi"]
[ext_resource type="TileSet" uid="uid://doepkfp83k0lb" path="res://_tileset/test.tres" id="8_wofhb"] [ext_resource type="TileSet" uid="uid://doepkfp83k0lb" path="res://_tileset/test.tres" id="8_wofhb"]

13
_shared/RespawnManager.gd Normal file
View File

@ -0,0 +1,13 @@
extends Node
var _cached_respawn : Array[PlayerRespawnPoint]
## 外部向管理器注冊自己
func register_player_respawn(prp: PlayerRespawnPoint) -> void:
if not _cached_respawn.has(prp):
_cached_respawn.append(prp)
## 清除其他管理器的Respawn
func reset_all_respawn() -> void:
for i in _cached_respawn:
i._can_respawn = false

View File

@ -0,0 +1 @@
uid://dwee6n1jgif8b

View File

@ -1,6 +1,32 @@
extends Node extends Node
signal player_dead signal player_dead(player: Player)
func boradcast_player_dead_event() -> void: var _cached_player_controller: PlayerController
player_dead.emit() var _cached_player: Player
## player controller進入tree會注冊自己到Global
func register_player_controller(pc: PlayerController) -> PlayerController:
if not pc: return null
_cached_player_controller = pc
return _cached_player_controller
## player進入tree會注冊自己到Global
func register_player(player: Player) -> Player:
if not player: return null
_cached_player = player
return _cached_player
## 外部快速获取Player
func get_player() -> Player:
return _cached_player
## 外部快速获取Player Controller
func get_player_controller() -> PlayerController:
return _cached_player_controller
## 外部用于监听Player死亡
func boradcast_player_dead_event(player:Player) -> void:
player_dead.emit(player)

View File

@ -12,10 +12,17 @@ texture = ExtResource("1_26tvm")
1:1/0 = 0 1:1/0 = 0
0:2/0 = 0 0:2/0 = 0
1:2/0 = 0 1:2/0 = 0
2:0/0 = 0
2:0/0/physics_layer_2/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, -3.0719662, -8, -3.0719662)
2:0/0/physics_layer_2/polygon_0/one_way = true
2:1/0 = 0
2:2/0 = 0
[resource] [resource]
physics_layer_0/collision_layer = 4 physics_layer_0/collision_layer = 4
physics_layer_0/collision_mask = 0 physics_layer_0/collision_mask = 0
physics_layer_1/collision_layer = 8 physics_layer_1/collision_layer = 8
physics_layer_1/collision_mask = 0 physics_layer_1/collision_mask = 0
physics_layer_2/collision_layer = 32
physics_layer_2/collision_mask = 0
sources/0 = SubResource("TileSetAtlasSource_s5wqu") sources/0 = SubResource("TileSetAtlasSource_s5wqu")

View File

@ -13,5 +13,5 @@ width = 8.0
[node name="RayCast2D" type="RayCast2D" parent="."] [node name="RayCast2D" type="RayCast2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
target_position = Vector2(80, 0) target_position = Vector2(80, 0)
collision_mask = 4 collision_mask = 36
collide_with_areas = true collide_with_areas = true

View File

@ -22,6 +22,7 @@ CameraSystem="*res://_shared/camera/CameraSystem.tscn"
GlobalEvent="*res://_shared/global_event.gd" GlobalEvent="*res://_shared/global_event.gd"
ReedVFX="*res://addons/reedfx/vfx/ReedVFXSystem.tscn" ReedVFX="*res://addons/reedfx/vfx/ReedVFXSystem.tscn"
ReedSceneRegistry="*res://addons/reedscene/scene/SceneRegistry.gd" ReedSceneRegistry="*res://addons/reedscene/scene/SceneRegistry.gd"
RespawnManager="*res://_shared/RespawnManager.gd"
[display] [display]
@ -40,6 +41,7 @@ enabled=PackedStringArray("res://addons/phantom_camera/plugin.cfg", "res://addon
ROOM="房间分组其下存在所有的Room" ROOM="房间分组其下存在所有的Room"
PLAYER="玩家分组,其下只存在玩家控制器" PLAYER="玩家分组,其下只存在玩家控制器"
GRAPABLE="" GRAPABLE=""
PLAYER_RESPAWN="所有的PlayerRespawnPoint的绑定Group"
[input] [input]
@ -90,3 +92,4 @@ grap_hook={
2d_physics/layer_3="Environment" 2d_physics/layer_3="Environment"
2d_physics/layer_4="Damage" 2d_physics/layer_4="Damage"
2d_physics/layer_5="Collectable" 2d_physics/layer_5="Collectable"
2d_physics/layer_6="OneWayPlateform"