Compare commits
10 Commits
main
...
feature/le
| Author | SHA1 | Date |
|---|---|---|
|
|
98583d1284 | |
|
|
1e64e54158 | |
|
|
adbb39b623 | |
|
|
2d08a43d4c | |
|
|
2c1ea309ef | |
|
|
d83053d2d7 | |
|
|
52fa2c1f0c | |
|
|
1a533d8e62 | |
|
|
e3bbf1b5b8 | |
|
|
9c8a2675e5 |
|
|
@ -1,9 +0,0 @@
|
|||
<component name="libraryTable">
|
||||
<library name="GdSdk" type="GdScript">
|
||||
<CLASSES />
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$APPLICATION_HOME_DIR$/plugins/rider-gdscript/sdk/extracted/Master" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<component name="libraryTable">
|
||||
<library name="GdSdk Master" type="GdScript">
|
||||
<properties path="C:\Users\和玲央央\AppData\Local\JetBrains\Rider2024.3\projects\godot-plateformer.a8f64e99\sdk\GdSdk Master" version="Master" date="2024-06-01T15:14:16.000+02:00" />
|
||||
<CLASSES />
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$USER_HOME$/AppData/Local/JetBrains/Rider2024.3/projects/godot-plateformer.a8f64e99/sdk/GdSdk Master" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=15 format=3 uid="uid://3vc8ojbiyy5w"]
|
||||
[gd_scene format=3 uid="uid://3vc8ojbiyy5w"]
|
||||
|
||||
[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"]
|
||||
|
|
@ -12,34 +12,69 @@
|
|||
[ext_resource type="PackedScene" uid="uid://7424nctotch0" path="res://_scene/level1/l1_s6.tscn" id="9_m1t3p"]
|
||||
[ext_resource type="PackedScene" uid="uid://dr8a26hfqkh12" path="res://_scene/level1/l1_s7.tscn" id="10_5s0xe"]
|
||||
[ext_resource type="PackedScene" uid="uid://2d457ndb7toe" path="res://_scene/level1/l1_s8.tscn" id="11_ktxjv"]
|
||||
[ext_resource type="PackedScene" uid="uid://dcoq4q3brnkw6" path="res://_scene/level1/l1_s9.tscn" id="12_enubi"]
|
||||
[ext_resource type="PackedScene" uid="uid://dsw3o2bhc8bve" path="res://_scene/level1/l1_s10.tscn" id="13_53pmm"]
|
||||
[ext_resource type="PackedScene" uid="uid://dcoq4q3brnkw6" path="res://_scene/level1/l1_s10.tscn" id="12_enubi"]
|
||||
[ext_resource type="PackedScene" uid="uid://bw4jkkpctk1b8" path="res://_scene/level1/l1_s9.tscn" id="13_53pmm"]
|
||||
[ext_resource type="PackedScene" uid="uid://dsw3o2bhc8bve" path="res://_scene/level1/l1_s11.tscn" id="15_n0kgp"]
|
||||
[ext_resource type="PackedScene" uid="uid://5435tmcn1h0x" path="res://_scene/level1/l1_s11_derivative/l1_s11_R1.tscn" id="15_twc26"]
|
||||
[ext_resource type="PackedScene" uid="uid://dalreo21de7vf" path="res://_scene/level1/l1_s11_derivative/l1_s11_R2.tscn" id="16_jibn5"]
|
||||
[ext_resource type="PackedScene" uid="uid://d04rrja6xhmp4" path="res://_scene/level1/l1_s11_derivative/l1_s11_R3.tscn" id="17_ef7py"]
|
||||
[ext_resource type="PackedScene" uid="uid://c681o3efaii8a" path="res://_scene/level1/l1_s11_derivative/l1_s11_R4.tscn" id="18_5vsgs"]
|
||||
[ext_resource type="PackedScene" uid="uid://rkoopuv5ndr2" path="res://_scene/level1/l1_s11_derivative/l1_s11_L1.tscn" id="19_5ctuh"]
|
||||
[ext_resource type="PackedScene" uid="uid://bst6if5k6muxy" path="res://_scene/level1/l1_s11_derivative/l1_s11_L2.tscn" id="20_ns8iw"]
|
||||
[ext_resource type="PackedScene" uid="uid://cmqu6k42rd64d" path="res://_scene/level1/l1_s11_derivative/l1_s11_L3.tscn" id="21_n0kgp"]
|
||||
|
||||
[node name="Game" type="Node2D" groups=["PLAYER_RESPAWN"]]
|
||||
[node name="Game" type="Node2D" unique_id=1155642617 groups=["PLAYER_RESPAWN"]]
|
||||
script = ExtResource("1_yksyv")
|
||||
metadata/_edit_vertical_guides_ = [1074.0]
|
||||
|
||||
[node name="PlayerController" parent="." instance=ExtResource("2_x2i0j")]
|
||||
[node name="PlayerController" parent="." unique_id=1762035755 instance=ExtResource("2_x2i0j")]
|
||||
|
||||
[node name="PlateformerCamera" parent="." instance=ExtResource("3_enubi")]
|
||||
[node name="PlateformerCamera" parent="." unique_id=236758593 instance=ExtResource("3_enubi")]
|
||||
|
||||
[node name="L0_S0" parent="." instance=ExtResource("3_4ifj7")]
|
||||
[node name="L0_S0" parent="." unique_id=468557684 instance=ExtResource("3_4ifj7")]
|
||||
|
||||
[node name="L1_S1" parent="." instance=ExtResource("4_m1t3p")]
|
||||
[node name="L1_S1" parent="." unique_id=153388085 instance=ExtResource("4_m1t3p")]
|
||||
|
||||
[node name="L1_S2" parent="." instance=ExtResource("5_5s0xe")]
|
||||
[node name="L1_S2" parent="." unique_id=365454739 instance=ExtResource("5_5s0xe")]
|
||||
|
||||
[node name="L1_S3" parent="." instance=ExtResource("6_ktxjv")]
|
||||
[node name="L1_S3" parent="." unique_id=1491102572 instance=ExtResource("6_ktxjv")]
|
||||
|
||||
[node name="L1_S4" parent="." instance=ExtResource("7_x2i0j")]
|
||||
[node name="L1_S4" parent="." unique_id=779321283 instance=ExtResource("7_x2i0j")]
|
||||
|
||||
[node name="L1_S5" parent="." instance=ExtResource("7_4ifj7")]
|
||||
[node name="L1_S5" parent="." unique_id=1462709098 instance=ExtResource("7_4ifj7")]
|
||||
|
||||
[node name="L1_S6" parent="." instance=ExtResource("9_m1t3p")]
|
||||
[node name="L1_S6" parent="." unique_id=37322839 instance=ExtResource("9_m1t3p")]
|
||||
|
||||
[node name="L1_S7" parent="." instance=ExtResource("10_5s0xe")]
|
||||
[node name="L1_S7" parent="." unique_id=384593411 instance=ExtResource("10_5s0xe")]
|
||||
|
||||
[node name="L1_S8" parent="." groups=["GRAPABLE"] instance=ExtResource("11_ktxjv")]
|
||||
[node name="L1_S8" parent="." unique_id=784953402 instance=ExtResource("11_ktxjv")]
|
||||
|
||||
[node name="L1_S9" parent="." instance=ExtResource("12_enubi")]
|
||||
[node name="L1_S9" parent="." unique_id=1409865054 instance=ExtResource("13_53pmm")]
|
||||
position = Vector2(-608, -16)
|
||||
|
||||
[node name="L1_S10" parent="." instance=ExtResource("13_53pmm")]
|
||||
[node name="L1_S10" parent="." unique_id=997505711 instance=ExtResource("12_enubi")]
|
||||
position = Vector2(848, -336)
|
||||
|
||||
[node name="L1_S11" parent="." unique_id=99397381 instance=ExtResource("15_n0kgp")]
|
||||
position = Vector2(848, -336)
|
||||
|
||||
[node name="L1_S11_R1" parent="." unique_id=845126004 instance=ExtResource("15_twc26")]
|
||||
position = Vector2(848, -336)
|
||||
|
||||
[node name="L1_S11_R2" parent="." unique_id=692644329 instance=ExtResource("16_jibn5")]
|
||||
position = Vector2(848, -336)
|
||||
|
||||
[node name="L1_S11_R3" parent="." unique_id=2065908461 instance=ExtResource("17_ef7py")]
|
||||
position = Vector2(848, -336)
|
||||
|
||||
[node name="L1_S11_R4" parent="." unique_id=1329785958 instance=ExtResource("18_5vsgs")]
|
||||
position = Vector2(848, -336)
|
||||
|
||||
[node name="L1_S11_L1" parent="." unique_id=1598546581 instance=ExtResource("19_5ctuh")]
|
||||
position = Vector2(848, -336)
|
||||
|
||||
[node name="L1_S11_L2" parent="." unique_id=1168627092 instance=ExtResource("20_ns8iw")]
|
||||
position = Vector2(848, -336)
|
||||
|
||||
[node name="L1_S11_L3" parent="." unique_id=1755237319 instance=ExtResource("21_n0kgp")]
|
||||
position = Vector2(848, -336)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
extends Node2D
|
||||
|
||||
func _ready() -> void:
|
||||
$L0_S0.switch_act_by_id(1)
|
||||
#$L1_S1.switch_act_by_id(1)
|
||||
#$L0_S0.switch_act_by_id(1)
|
||||
$L1_S1.switch_act_by_id(1)
|
||||
#$L1_S2.switch_act_by_id(1)
|
||||
#$L1_S3.switch_act_by_id(1)
|
||||
#$L1_S4.switch_act_by_id(1)
|
||||
|
|
@ -11,5 +11,15 @@ func _ready() -> void:
|
|||
#$L1_S7.switch_act_by_id(1)
|
||||
#$L1_S8.switch_act_by_id(1)
|
||||
#$L1_S9.switch_act_by_id(1)
|
||||
#$L1_S10.switch_act_by_id(1)
|
||||
#$L1_S10_R1.switch_act_by_id(1)
|
||||
#$L1_S10_R2.switch_act_by_id(1)
|
||||
#$L1_S10_R3.switch_act_by_id(1)
|
||||
#$L1_S10_R4.switch_act_by_id(1)
|
||||
#$L1_S10_L1.switch_act_by_id(1)
|
||||
#$L1_S10_L2.switch_act_by_id(1)
|
||||
#$L1_S10_L3.switch_act_by_id(1)
|
||||
|
||||
GlobalEvent.player_follow_camera()
|
||||
await get_tree().process_frame
|
||||
get_tree().call_group(&"PLAYER_RESPAWN",&"respawn_avatar")
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
extends CanvasLayer
|
||||
|
||||
@export var target: Node2D
|
||||
@onready var rect = $ColorRect
|
||||
|
||||
var mat: ShaderMaterial
|
||||
var last_pos: Vector2
|
||||
|
||||
func _ready():
|
||||
mat = rect.material as ShaderMaterial
|
||||
if target != null:
|
||||
last_pos = target.global_position
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if target == null:
|
||||
return
|
||||
|
||||
if mat == null:
|
||||
return
|
||||
|
||||
var vp_size: Vector2 = get_viewport().get_visible_rect().size
|
||||
|
||||
# 玩家世界坐标
|
||||
var world_pos: Vector2 = target.global_position
|
||||
|
||||
# ✅ 世界 -> 屏幕像素坐标(包含相机影响)
|
||||
var screen_pos: Vector2 = get_viewport().get_canvas_transform() * world_pos
|
||||
|
||||
# 速度方向(世界空间)
|
||||
var vel: Vector2 = (world_pos - last_pos) / max(delta, 0.0001)
|
||||
last_pos = world_pos
|
||||
|
||||
var speed: float = vel.length()
|
||||
var dir: Vector2 = Vector2.RIGHT
|
||||
if speed > 0.001:
|
||||
dir = vel / speed
|
||||
|
||||
# ✅ 船头前移(拨水发生在玩家前面)
|
||||
var front_offset_px: Vector2 = dir * 30.0
|
||||
var uv_front: Vector2 = (screen_pos + front_offset_px) / vp_size
|
||||
uv_front = uv_front.clamp(Vector2(0, 0), Vector2(1, 1))
|
||||
|
||||
|
||||
mat.set_shader_parameter("obj_uv", uv_front)
|
||||
mat.set_shader_parameter("obj_dir", dir)
|
||||
mat.set_shader_parameter("obj_speed", clamp(speed / 600.0, 0.0, 2.0))
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c5in610cunjn2
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="ReedPropEffect" load_steps=6 format=3 uid="uid://bjjxh7g7iosla"]
|
||||
[gd_resource type="Resource" script_class="ReedPropEffect" format=3 uid="uid://bjjxh7g7iosla"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cdvgq0xqdbagk" path="res://addons/reedscene/prop/Effect/ReedPropEffect.gd" id="1_4meba"]
|
||||
[ext_resource type="Script" uid="uid://bf1qlvdbf8qdp" path="res://addons/reedscene/prop/Effect/EAT_CallFunc.gd" id="1_qrdf4"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="ReedPropEffect" load_steps=6 format=3 uid="uid://458r8rf7x02p"]
|
||||
[gd_resource type="Resource" script_class="ReedPropEffect" format=3 uid="uid://458r8rf7x02p"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bf1qlvdbf8qdp" path="res://addons/reedscene/prop/Effect/EAT_CallFunc.gd" id="1_lgnrf"]
|
||||
[ext_resource type="Script" uid="uid://cdvgq0xqdbagk" path="res://addons/reedscene/prop/Effect/ReedPropEffect.gd" id="2_lgnrf"]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://d20u8tfktepxg"]
|
||||
[gd_scene format=3 uid="uid://d20u8tfktepxg"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b7o5456qrwgbf" path="res://_props/_prefabs/collection/collection_prefab.gd" id="1_8ns1b"]
|
||||
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="2_qf7ju"]
|
||||
|
||||
[node name="CollectionPrefab" type="Area2D"]
|
||||
[node name="CollectionPrefab" type="Area2D" unique_id=647938263]
|
||||
collision_layer = 16
|
||||
collision_mask = 2
|
||||
script = ExtResource("1_8ns1b")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=486383318]
|
||||
scale = Vector2(0.2, 0.2)
|
||||
texture = ExtResource("2_qf7ju")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
extends AnimatableBody2D
|
||||
|
||||
@export var shaking_target: Node2D
|
||||
@export var shake_strength: float = 8.0
|
||||
@export var shake_duration: float = 0.25
|
||||
@export var shake_hz: float = 12.0 # 每秒抖几次(关键参数)
|
||||
|
||||
signal shaking_finished()
|
||||
|
||||
var _origin_pos: Vector2
|
||||
var _shaking := false
|
||||
var _rng := RandomNumberGenerator.new()
|
||||
|
||||
func _ready() -> void:
|
||||
if not shaking_target:
|
||||
shaking_target = self
|
||||
_rng.randomize()
|
||||
|
||||
func shaking() -> void:
|
||||
if _shaking:
|
||||
return
|
||||
|
||||
if not shaking_target:
|
||||
shaking_target = self
|
||||
|
||||
_origin_pos = shaking_target.position
|
||||
_shaking = true
|
||||
|
||||
var end_timer := get_tree().create_timer(shake_duration)
|
||||
var interval : float = 1.0 / max(shake_hz, 1.0)
|
||||
var next_update := 0.0
|
||||
var current_offset := Vector2.ZERO
|
||||
|
||||
while end_timer.time_left > 0.0:
|
||||
next_update -= get_process_delta_time()
|
||||
|
||||
if next_update <= 0.0:
|
||||
current_offset = Vector2(
|
||||
randf_range(-shake_strength, shake_strength),
|
||||
randf_range(-shake_strength, shake_strength)
|
||||
)
|
||||
next_update = interval
|
||||
|
||||
shaking_target.position = _origin_pos + current_offset
|
||||
await get_tree().process_frame
|
||||
|
||||
shaking_target.position = _origin_pos
|
||||
_shaking = false
|
||||
shaking_finished.emit()
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dmamoiy8sl0bn
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[gd_scene format=3 uid="uid://goua2e1q7qq6"]
|
||||
|
||||
[node name="FragileShakingPlatform" type="Node2D"]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="ReedPropEffect" load_steps=6 format=3 uid="uid://dd4df6yjkeifa"]
|
||||
[gd_resource type="Resource" script_class="ReedPropEffect" format=3 uid="uid://dd4df6yjkeifa"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cdvgq0xqdbagk" path="res://addons/reedscene/prop/Effect/ReedPropEffect.gd" id="1_bxu3h"]
|
||||
[ext_resource type="Script" uid="uid://bf1qlvdbf8qdp" path="res://addons/reedscene/prop/Effect/EAT_CallFunc.gd" id="1_y2h7j"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="ReedPropEffect" load_steps=6 format=3 uid="uid://b6iglvt36pm55"]
|
||||
[gd_resource type="Resource" script_class="ReedPropEffect" format=3 uid="uid://b6iglvt36pm55"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cdvgq0xqdbagk" path="res://addons/reedscene/prop/Effect/ReedPropEffect.gd" id="1_3md03"]
|
||||
[ext_resource type="Script" uid="uid://bf1qlvdbf8qdp" path="res://addons/reedscene/prop/Effect/EAT_CallFunc.gd" id="1_uj0dv"]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
class_name VinePlatform
|
||||
extends StaticBody2D
|
||||
|
||||
|
||||
## ===== 节点引用 =====
|
||||
@onready var player_trigger: Area2D = %PlayerTriggerVolumn
|
||||
@onready var hook_trigger: Area2D = %HookAttractVolumn
|
||||
@onready var sprite: Sprite2D = $Sprite2D
|
||||
@onready var collision: CollisionShape2D = $CollisionShape2D
|
||||
|
||||
|
||||
## ===== 配置 =====
|
||||
|
||||
## 触发到消失的总时间(固定)
|
||||
@export var destroy_total_time: float = 2.0
|
||||
|
||||
## 触发后多久开始抖动(可调)
|
||||
@export var shake_start_time: float = 1.0
|
||||
|
||||
## 消失后多久恢复(再生时间)
|
||||
@export var respawn_time: float = 3.0
|
||||
|
||||
|
||||
## 抖动参数
|
||||
@export var shake_x: float = 1.0
|
||||
@export var shake_y: float = 1.0
|
||||
@export var step_time: float = 0.034
|
||||
|
||||
|
||||
## ===== 状态机 =====
|
||||
enum State {
|
||||
IDLE,
|
||||
TRIGGERED,
|
||||
DISAPPEARED
|
||||
}
|
||||
|
||||
var _current_state: State = State.IDLE
|
||||
|
||||
|
||||
## ===== 抖动控制 =====
|
||||
var _shake_tween: Tween
|
||||
var _shake_origin_pos: Vector2
|
||||
|
||||
## 防止重复触发
|
||||
var _sequence_started := false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
player_trigger.body_entered.connect(_on_player_entered)
|
||||
hook_trigger.body_entered.connect(_on_hook_hit)
|
||||
|
||||
|
||||
## ==============================
|
||||
## 状态切换
|
||||
## ==============================
|
||||
func change_state(new_state: State) -> void:
|
||||
if new_state == _current_state:
|
||||
return
|
||||
|
||||
_current_state = new_state
|
||||
|
||||
match new_state:
|
||||
State.IDLE:
|
||||
_enable_platform(true)
|
||||
|
||||
State.TRIGGERED:
|
||||
_start_destroy_sequence()
|
||||
|
||||
State.DISAPPEARED:
|
||||
_disappear_and_respawn()
|
||||
|
||||
|
||||
## ==============================
|
||||
## 触发入口
|
||||
## ==============================
|
||||
|
||||
func _on_player_entered(body: Node) -> void:
|
||||
if body is Player:
|
||||
_trigger_platform()
|
||||
|
||||
|
||||
func _on_hook_hit(hit_pos: Vector2, hook: Hook) -> void:
|
||||
_trigger_platform()
|
||||
|
||||
|
||||
|
||||
func _trigger_platform() -> void:
|
||||
if _sequence_started:
|
||||
return
|
||||
_sequence_started = true
|
||||
|
||||
print("藤蔓平台触发:2秒后消失,再生时间:", respawn_time)
|
||||
|
||||
change_state(State.TRIGGERED)
|
||||
|
||||
|
||||
## ==============================
|
||||
## 销毁流程:抖动 + 消失(非销毁)
|
||||
## ==============================
|
||||
func _start_destroy_sequence() -> void:
|
||||
var shake_time: float = clampf(shake_start_time, 0.0, destroy_total_time)
|
||||
var remaining_time: float = destroy_total_time - shake_time
|
||||
|
||||
# 前半段静止
|
||||
if shake_time > 0.0:
|
||||
await get_tree().create_timer(shake_time).timeout
|
||||
|
||||
# 后半段抖动
|
||||
if remaining_time > 0.0:
|
||||
start_shaking()
|
||||
await get_tree().create_timer(remaining_time).timeout
|
||||
|
||||
stop_shaking()
|
||||
|
||||
# 进入消失状态
|
||||
change_state(State.DISAPPEARED)
|
||||
|
||||
|
||||
## ==============================
|
||||
## 消失 + 再生
|
||||
## ==============================
|
||||
func _disappear_and_respawn() -> void:
|
||||
print("平台消失,等待再生...")
|
||||
|
||||
# 关闭平台
|
||||
_enable_platform(false)
|
||||
|
||||
# 等待再生时间
|
||||
await get_tree().create_timer(respawn_time).timeout
|
||||
|
||||
print("平台恢复!")
|
||||
|
||||
# 重置触发锁
|
||||
_sequence_started = false
|
||||
|
||||
# 回到初始状态
|
||||
change_state(State.IDLE)
|
||||
|
||||
|
||||
## ==============================
|
||||
## 启用/禁用平台(关键)
|
||||
## ==============================
|
||||
func _enable_platform(enable: bool) -> void:
|
||||
sprite.visible = enable
|
||||
collision.disabled = not enable
|
||||
|
||||
player_trigger.monitoring = enable
|
||||
hook_trigger.monitoring = enable
|
||||
|
||||
|
||||
## ==============================
|
||||
## 抖动效果
|
||||
## ==============================
|
||||
func start_shaking() -> void:
|
||||
if _shake_tween and _shake_tween.is_running():
|
||||
return
|
||||
|
||||
_shake_origin_pos = sprite.position
|
||||
|
||||
_shake_tween = create_tween()
|
||||
_shake_tween.set_loops()
|
||||
_shake_tween.set_trans(Tween.TRANS_SINE)
|
||||
_shake_tween.set_ease(Tween.EASE_IN_OUT)
|
||||
|
||||
_shake_tween.tween_property(sprite, "position", _shake_origin_pos + Vector2(-shake_x, -shake_y), step_time)
|
||||
_shake_tween.tween_property(sprite, "position", _shake_origin_pos + Vector2(shake_x, shake_y), step_time)
|
||||
_shake_tween.tween_property(sprite, "position", _shake_origin_pos + Vector2(-shake_x, shake_y), step_time)
|
||||
_shake_tween.tween_property(sprite, "position", _shake_origin_pos + Vector2(shake_x, -shake_y), step_time)
|
||||
|
||||
|
||||
func stop_shaking() -> void:
|
||||
if _shake_tween:
|
||||
_shake_tween.kill()
|
||||
_shake_tween = null
|
||||
|
||||
sprite.position = _shake_origin_pos
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bog8pjjhrcd3g
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
[gd_scene format=3 uid="uid://dfwups0m7a5m4"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="1_a6xdh"]
|
||||
[ext_resource type="Script" uid="uid://bog8pjjhrcd3g" path="res://_props/_prefabs/vine_platform/vine_platform.gd" id="1_jux4m"]
|
||||
[ext_resource type="PackedScene" uid="uid://bonrls3iuhdqb" path="res://_props/_prefabs/player/player_trigger_volumn.tscn" id="2_1eb6k"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_1eb6k"]
|
||||
size = Vector2(32, 16)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_1ul4y"]
|
||||
size = Vector2(32, 24)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_jux4m"]
|
||||
size = Vector2(38, 22)
|
||||
|
||||
[node name="VinePlatform" type="StaticBody2D" unique_id=1779509136 groups=["GRAPABLE"]]
|
||||
collision_layer = 4
|
||||
collision_mask = 2
|
||||
script = ExtResource("1_jux4m")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1586582263]
|
||||
scale = Vector2(0.24999999, 0.125)
|
||||
texture = ExtResource("1_a6xdh")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=314807201]
|
||||
shape = SubResource("RectangleShape2D_1eb6k")
|
||||
debug_color = Color(1, 0.24705882, 0.40784314, 0.41960785)
|
||||
|
||||
[node name="PlayerTriggerVolumn" parent="." unique_id=869831136 instance=ExtResource("2_1eb6k")]
|
||||
unique_name_in_owner = true
|
||||
debug_print = false
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerTriggerVolumn" unique_id=209979624]
|
||||
position = Vector2(0, -4)
|
||||
shape = SubResource("RectangleShape2D_1ul4y")
|
||||
debug_color = Color(0.19215687, 0.6431373, 0, 0)
|
||||
|
||||
[node name="HookAttractVolumn" type="Area2D" parent="." unique_id=71519728]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 32
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="HookAttractVolumn" unique_id=1847255495]
|
||||
shape = SubResource("RectangleShape2D_jux4m")
|
||||
debug_color = Color(1, 0, 0.14509805, 0)
|
||||
|
|
@ -2,6 +2,7 @@ extends CharacterBody2D
|
|||
|
||||
@onready var player_collectable_volumn: PlayerTriggerVolumn = %PlayerCollectableVolumn
|
||||
@onready var hook_attract_volumn: Area2D = %HookAttractVolumn
|
||||
@export var respawn_time: float = 2.0
|
||||
|
||||
enum State {
|
||||
IDLE,
|
||||
|
|
@ -10,6 +11,7 @@ enum State {
|
|||
}
|
||||
|
||||
var _current_state: State = State.IDLE
|
||||
var _spawn_position: Vector2
|
||||
|
||||
## 拉回速度
|
||||
@export var pull_speed: float = 800.0
|
||||
|
|
@ -17,6 +19,7 @@ var _current_state: State = State.IDLE
|
|||
var _pull_target: Node2D
|
||||
|
||||
func _ready() -> void:
|
||||
_spawn_position = global_position
|
||||
player_collectable_volumn.player_entered.connect(_on_player_collected)
|
||||
|
||||
##状态管理函数
|
||||
|
|
@ -42,7 +45,7 @@ func change_state(in_state: State) -> void:
|
|||
State.PULLED_BY_HOOK:
|
||||
pass
|
||||
State.COLLECTED:
|
||||
queue_free()
|
||||
_on_collected_enter()
|
||||
|
||||
## 钩爪击中时调用(hit_pos 是击中点,hook 是钩爪实例)
|
||||
func on_hook_hit(hit_pos: Vector2, hook: Hook) -> void:
|
||||
|
|
@ -68,3 +71,41 @@ func _on_player_collected(body:CharacterBody2D) -> void:
|
|||
if body is Player:
|
||||
body.hsm.dispatch(&"trigger_external_dash")
|
||||
change_state(State.COLLECTED)
|
||||
|
||||
func _on_collected_enter() -> void:
|
||||
velocity = Vector2.ZERO
|
||||
|
||||
# 隐藏
|
||||
visible = false
|
||||
set_physics_process(false)
|
||||
|
||||
# 关闭碰撞
|
||||
if has_node("CollisionShape2D"):
|
||||
$CollisionShape2D.disabled = true
|
||||
|
||||
player_collectable_volumn.monitoring = false
|
||||
player_collectable_volumn.monitorable = false
|
||||
hook_attract_volumn.monitoring = false
|
||||
hook_attract_volumn.monitorable = false
|
||||
|
||||
# 启动重生流程
|
||||
_respawn_after_delay()
|
||||
|
||||
func _respawn_after_delay() -> void:
|
||||
await get_tree().create_timer(respawn_time).timeout
|
||||
|
||||
global_position = _spawn_position
|
||||
|
||||
visible = true
|
||||
set_physics_process(true)
|
||||
|
||||
if has_node("CollisionShape2D"):
|
||||
$CollisionShape2D.disabled = false
|
||||
|
||||
player_collectable_volumn.monitoring = true
|
||||
player_collectable_volumn.monitorable = true
|
||||
hook_attract_volumn.monitoring = true
|
||||
hook_attract_volumn.monitorable = true
|
||||
|
||||
change_state(State.IDLE)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://bju8jr1w4d60m"]
|
||||
[gd_scene format=3 uid="uid://bju8jr1w4d60m"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="1_dd62g"]
|
||||
[ext_resource type="Script" uid="uid://cvrty667x12i6" path="res://_props/spring/spring.gd" id="1_mfmm2"]
|
||||
|
|
@ -6,16 +6,16 @@
|
|||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_wsen7"]
|
||||
size = Vector2(16, 16)
|
||||
|
||||
[node name="spring" type="Area2D" groups=["GRAPABLE"]]
|
||||
[node name="spring" type="Area2D" unique_id=470552845 groups=["GRAPABLE"]]
|
||||
collision_layer = 4
|
||||
collision_mask = 2
|
||||
script = ExtResource("1_mfmm2")
|
||||
jump_speed = 1000.0
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=506922243]
|
||||
position = Vector2(-2.3841858e-07, 0)
|
||||
scale = Vector2(0.12499999, 0.125)
|
||||
texture = ExtResource("1_dd62g")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=97358040]
|
||||
shape = SubResource("RectangleShape2D_wsen7")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://badmoya3nd161"]
|
||||
[gd_scene format=3 uid="uid://badmoya3nd161"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dajlxaybacxxc" path="res://_props/trigger_fall_rock_climb/trigger_fall_rock_climb.gd" id="1_n6tyk"]
|
||||
[ext_resource type="PackedScene" uid="uid://cmjwk4gr1nfns" path="res://_props/_prefabs/rock.tscn" id="2_ibofv"]
|
||||
|
|
@ -11,31 +11,31 @@ size = Vector2(52, 52)
|
|||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_mvp6g"]
|
||||
size = Vector2(54, 52.5)
|
||||
|
||||
[node name="TriggerFallRock_Climb" type="Node2D"]
|
||||
[node name="TriggerFallRock_Climb" type="Node2D" unique_id=788823859]
|
||||
scale = Vector2(0.9, 0.9)
|
||||
script = ExtResource("1_n6tyk")
|
||||
|
||||
[node name="rock" parent="." instance=ExtResource("2_ibofv")]
|
||||
[node name="rock" parent="." unique_id=1121422701 instance=ExtResource("2_ibofv")]
|
||||
position = Vector2(0, -74)
|
||||
falling_gravity = 600.0
|
||||
max_fall_speed = 1500.0
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="rock"]
|
||||
[node name="Sprite2D" type="Sprite2D" parent="rock" unique_id=2092021495]
|
||||
position = Vector2(0, 73.99999)
|
||||
scale = Vector2(0.405, 0.405)
|
||||
texture = ExtResource("3_mb81t")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="rock"]
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="rock" unique_id=2039714799]
|
||||
position = Vector2(0, 74)
|
||||
shape = SubResource("RectangleShape2D_vv0hj")
|
||||
debug_color = Color(0.99629647, 0, 0.19810504, 0.41960785)
|
||||
|
||||
[node name="PlayerTriggerVolumn" parent="." instance=ExtResource("4_txegh")]
|
||||
debug_print = true
|
||||
[node name="PlayerTriggerVolumn" parent="." unique_id=296183028 instance=ExtResource("4_txegh")]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerTriggerVolumn"]
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerTriggerVolumn" unique_id=1068719796]
|
||||
position = Vector2(0, -0.75)
|
||||
shape = SubResource("RectangleShape2D_mvp6g")
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
[node name="Timer" type="Timer" parent="." unique_id=1698795583]
|
||||
wait_time = 0.8
|
||||
one_shot = true
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://knrcnoedxvm6"]
|
||||
[gd_scene format=3 uid="uid://knrcnoedxvm6"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b8yl6l3tlam86" path="res://_props/trigger_fall_rock_hazard/trigger_fall_rock_hazard.gd" id="1_2ms0f"]
|
||||
[ext_resource type="PackedScene" uid="uid://cmjwk4gr1nfns" path="res://_props/_prefabs/rock.tscn" id="2_ww3ib"]
|
||||
|
|
@ -11,29 +11,30 @@ size = Vector2(52, 52)
|
|||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_mvp6g"]
|
||||
size = Vector2(52, 108.5)
|
||||
|
||||
[node name="TriggerFallRock_Hazard" type="Node2D"]
|
||||
[node name="TriggerFallRock_Hazard" type="Node2D" unique_id=248471 groups=["ROCK_BREAK"]]
|
||||
scale = Vector2(0.9, 0.9)
|
||||
script = ExtResource("1_2ms0f")
|
||||
|
||||
[node name="rock" parent="." instance=ExtResource("2_ww3ib")]
|
||||
[node name="rock" parent="." unique_id=1315018512 groups=["ROCK_BREAK"] instance=ExtResource("2_ww3ib")]
|
||||
position = Vector2(0, -82)
|
||||
falling_gravity = 600.0
|
||||
max_fall_speed = 1000.0
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="rock"]
|
||||
[node name="Sprite2D" type="Sprite2D" parent="rock" unique_id=947610890]
|
||||
scale = Vector2(0.405, 0.405)
|
||||
texture = ExtResource("3_f8vfu")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="rock"]
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="rock" unique_id=93634710]
|
||||
shape = SubResource("RectangleShape2D_vv0hj")
|
||||
debug_color = Color(0.99629647, 0, 0.19810504, 0.41960785)
|
||||
|
||||
[node name="PlayerTriggerVolumn" parent="." instance=ExtResource("4_s77mb")]
|
||||
debug_print = true
|
||||
[node name="PlayerTriggerVolumn" parent="." unique_id=182002080 instance=ExtResource("4_s77mb")]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerTriggerVolumn"]
|
||||
position = Vector2(0, -54)
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerTriggerVolumn" unique_id=821875896]
|
||||
position = Vector2(0, -4)
|
||||
scale = Vector2(1, 1.92)
|
||||
shape = SubResource("RectangleShape2D_mvp6g")
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
[node name="Timer" type="Timer" parent="." unique_id=130846245]
|
||||
wait_time = 0.8
|
||||
one_shot = true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
extends VinePlatform
|
||||
|
||||
@export var jump_speed: float = 600.0 # 向上的初速度
|
||||
|
||||
##跳跃声音特效
|
||||
signal s_jump_sound
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
|
||||
|
||||
func _on_player_entered(body: Node) -> void:
|
||||
# 只处理 CharacterBody2D
|
||||
if body is Player:
|
||||
_trigger_platform()
|
||||
# 给予垂直向上的速度
|
||||
var dir := -global_transform.y.normalized()
|
||||
body.velocity = dir * jump_speed
|
||||
# 播放弹簧音效
|
||||
on_ejection()
|
||||
# 触发破碎机制
|
||||
_trigger_platform()
|
||||
|
||||
|
||||
func on_ejection() -> void:
|
||||
# 播放弹簧音效
|
||||
s_jump_sound.emit()
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bike0n5pc38qk
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
[gd_scene format=3 uid="uid://b188rk1rmyb2h"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bike0n5pc38qk" path="res://_props/vine_spring/vine_spring.gd" id="1_p0in6"]
|
||||
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="2_c0rfy"]
|
||||
[ext_resource type="PackedScene" uid="uid://bonrls3iuhdqb" path="res://_props/_prefabs/player/player_trigger_volumn.tscn" id="3_ejnsy"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_1eb6k"]
|
||||
size = Vector2(32, 16)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_1ul4y"]
|
||||
size = Vector2(32, 24)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_jux4m"]
|
||||
size = Vector2(38, 22)
|
||||
|
||||
[node name="VineSpring" type="StaticBody2D" unique_id=1779509136 groups=["GRAPABLE"]]
|
||||
collision_layer = 4
|
||||
collision_mask = 2
|
||||
script = ExtResource("1_p0in6")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1586582263]
|
||||
scale = Vector2(0.24999999, 0.125)
|
||||
texture = ExtResource("2_c0rfy")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=314807201]
|
||||
shape = SubResource("RectangleShape2D_1eb6k")
|
||||
debug_color = Color(1, 0.24705882, 0.40784314, 0.41960785)
|
||||
|
||||
[node name="PlayerTriggerVolumn" parent="." unique_id=869831136 instance=ExtResource("3_ejnsy")]
|
||||
unique_name_in_owner = true
|
||||
debug_print = false
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerTriggerVolumn" unique_id=209979624]
|
||||
position = Vector2(0, -4)
|
||||
shape = SubResource("RectangleShape2D_1ul4y")
|
||||
debug_color = Color(0.19215687, 0.6431373, 0, 0)
|
||||
|
||||
[node name="HookAttractVolumn" type="Area2D" parent="." unique_id=71519728]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 32
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="HookAttractVolumn" unique_id=1847255495]
|
||||
shape = SubResource("RectangleShape2D_jux4m")
|
||||
debug_color = Color(1, 0, 0.14509805, 0)
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="SceneTrigger" load_steps=19 format=3 uid="uid://bym4pb0ellj7b"]
|
||||
[gd_resource type="Resource" script_class="SceneTrigger" format=3 uid="uid://bym4pb0ellj7b"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/scene_trigger/base/SceneTrigger.gd" id="2_cq8o1"]
|
||||
[ext_resource type="Script" uid="uid://dxj5vimigc651" path="res://addons/reedscene/scene/scene_trigger/base/SceneTriggerEffectPair.gd" id="3_m0qh3"]
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://rrlq7ucvgbsv"]
|
||||
|
||||
[ext_resource type="Shader" uid="uid://b14j7g5tolgq" path="res://_shader/new_shader.gdshader" id="1_kkjpc"]
|
||||
[ext_resource type="Texture2D" uid="uid://cfjprjiin3dnk" path="res://_asset/ksw/normal.png" id="2_kkjpc"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_iixbh"]
|
||||
shader = ExtResource("1_kkjpc")
|
||||
shader_parameter/amount = 20.0
|
||||
shader_parameter/move = 1.0
|
||||
shader_parameter/bandsize = 0.1
|
||||
shader_parameter/speed = 1.0
|
||||
|
||||
[node name="Ripple" type="Node2D"]
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
material = SubResource("ShaderMaterial_iixbh")
|
||||
texture = ExtResource("2_kkjpc")
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="TileSet" load_steps=4 format=3 uid="uid://doepkfp83k0lb"]
|
||||
[gd_resource type="TileSet" format=3 uid="uid://doepkfp83k0lb"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://doxhsab56pe50" path="res://_asset/all.png" id="1_26tvm"]
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const _DEBUG_TOOL := preload("res://addons/reedcamera/scripts/camera_tools/DeadZ
|
|||
|
||||
@export_group("Follow")
|
||||
@export var enabled_follow: bool = true
|
||||
@export var follow_speed: float = 600.0 # 世界单位 / 秒
|
||||
@export var follow_speed: float = 10000.0 # 世界单位 / 秒
|
||||
@export var follow_lerp := 0.12 # 0~1,越大越“跟手”,越小越“蔚蓝感”的滞后
|
||||
@export_subgroup("Follow Dynamic Speed")
|
||||
@export var min_speed_scale := 0.4 # 贴近死区时
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
<Project Sdk="Godot.NET.Sdk/4.6.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net9.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<RootNamespace>godotplateformer</RootNamespace>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -8,11 +8,15 @@
|
|||
|
||||
config_version=5
|
||||
|
||||
[animation]
|
||||
|
||||
compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
||||
|
||||
[application]
|
||||
|
||||
config/name="godot-plateformer"
|
||||
run/main_scene="uid://3vc8ojbiyy5w"
|
||||
config/features=PackedStringArray("4.5", "Forward Plus")
|
||||
config/features=PackedStringArray("4.6", "C#", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[autoload]
|
||||
|
|
@ -30,6 +34,10 @@ window/size/window_width_override=1920
|
|||
window/size/window_height_override=1080
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
[dotnet]
|
||||
|
||||
project/assembly_name="godot-plateformer"
|
||||
|
||||
[editor_plugins]
|
||||
|
||||
enabled=PackedStringArray("res://addons/reedcamera/plugin.cfg", "res://addons/reedcomponent/plugin.cfg", "res://addons/reedfx/plugin.cfg", "res://addons/reedinput/plugin.cfg", "res://addons/reedscene/plugin.cfg")
|
||||
|
|
|
|||
Loading…
Reference in New Issue