v0.2.2
This commit is contained in:
parent
4334f4a4b0
commit
b306abb739
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,44 @@
|
|||
'''
|
||||
此类为工具体积类,主要为检测玩家是否进入了检测体积。
|
||||
'''
|
||||
class_name PlayerTriggerVolumn
|
||||
extends Area2D
|
||||
|
||||
@export var debug_print: bool = false
|
||||
|
||||
signal player_entered(body:CharacterBody2D)
|
||||
signal player_exit(body:CharacterBody2D)
|
||||
|
||||
var _cached_player : Player
|
||||
|
||||
func _ready() -> void:
|
||||
self.body_entered.connect(_on_body_enter)
|
||||
self.body_exited.connect(_on_body_exit)
|
||||
|
||||
func _on_body_enter(body:Node2D) -> void:
|
||||
if not body.is_in_group("PLAYER"):
|
||||
return
|
||||
|
||||
var p = body as Player
|
||||
if not p: return
|
||||
|
||||
if debug_print:
|
||||
print("[TiggerVolumn]: Player Entered")
|
||||
|
||||
_cached_player = p
|
||||
player_entered.emit(p)
|
||||
|
||||
func _on_body_exit(body:Node2D) -> void:
|
||||
if not _cached_player: return
|
||||
|
||||
if not body.is_in_group("PLAYER"):
|
||||
return
|
||||
|
||||
var p = body as Player
|
||||
if not p: return
|
||||
|
||||
if debug_print:
|
||||
print("[TiggerVolumn]: Player Exited")
|
||||
|
||||
_cached_player = null
|
||||
player_exit.emit(p)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://c25ea2nypjah7
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://bonrls3iuhdqb"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c25ea2nypjah7" path="res://_props/tools/player_trigger_volumn.gd" id="1_qrafk"]
|
||||
|
||||
[node name="PlayerTriggerVolumn" type="Area2D"]
|
||||
editor_description = "此类在检测到玩家时会发出signal,可以与其他的需要检测玩家的scene组合使用。
|
||||
"
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
script = ExtResource("1_qrafk")
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
class_name Rock
|
||||
extends CharacterBody2D
|
||||
|
||||
## ===== 配置 =====
|
||||
@export var falling_gravity: float = 2000.0
|
||||
@export var max_fall_speed: float = 3000.0
|
||||
@export var kill_y: float = 10000000.0
|
||||
|
||||
@export var shake_x := 2.0
|
||||
@export var shake_y := 2.0
|
||||
@export var step_time := 0.034
|
||||
|
||||
@export var binded_rock_texture: Node2D
|
||||
|
||||
## ===== 常量 =====
|
||||
const NO_TARGET_Y: float = 1e20
|
||||
|
||||
## ===== 状态 =====
|
||||
var is_falling: bool = false
|
||||
var fall_target_y: float = NO_TARGET_Y
|
||||
|
||||
## ===== 抖动量 =====
|
||||
var _shake_tween: Tween
|
||||
var _shake_origin_pos: Vector2
|
||||
|
||||
##岩石开始抖动
|
||||
func start_shaking() -> void:
|
||||
var sprite := $Sprite2D
|
||||
|
||||
if binded_rock_texture: sprite = binded_rock_texture
|
||||
if not sprite:
|
||||
return
|
||||
|
||||
# 防止重复启动
|
||||
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:
|
||||
var sprite := $Sprite2D
|
||||
if not sprite:
|
||||
return
|
||||
|
||||
if _shake_tween:
|
||||
_shake_tween.kill()
|
||||
_shake_tween = null
|
||||
|
||||
# 强制回到原位,防止残留偏移
|
||||
sprite.position = _shake_origin_pos
|
||||
|
||||
## 开始下落(可指定目标)
|
||||
func start_falling(target_y: float = NO_TARGET_Y) -> void:
|
||||
is_falling = true
|
||||
fall_target_y = target_y
|
||||
velocity = Vector2.ZERO
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if not is_falling:
|
||||
return
|
||||
|
||||
_update_fall(delta)
|
||||
|
||||
|
||||
func _update_fall(delta: float) -> void:
|
||||
## 速度积分
|
||||
velocity.y += falling_gravity * delta
|
||||
velocity.y = min(velocity.y, max_fall_speed)
|
||||
|
||||
## 预测下一帧位置
|
||||
var next_y: float = global_position.y + velocity.y * delta
|
||||
|
||||
## 到达目标 / kill
|
||||
var limit_y: float = min(fall_target_y, kill_y)
|
||||
if next_y >= limit_y:
|
||||
global_position.y = limit_y
|
||||
_on_fall_finished()
|
||||
return
|
||||
|
||||
move_and_slide()
|
||||
|
||||
func _on_fall_finished() -> void:
|
||||
is_falling = false
|
||||
queue_free() # 或者变成平台 / 播动画
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://hme2aiy2gff7
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cmjwk4gr1nfns"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://hme2aiy2gff7" path="res://_props/tools/rock.gd" id="1_60pcp"]
|
||||
|
||||
[node name="rock" type="CharacterBody2D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
script = ExtResource("1_60pcp")
|
||||
falling_gravity = 400.0
|
||||
max_fall_speed = 600.0
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cmjwk4gr1nfns"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://hme2aiy2gff7" path="res://_props/tools/rock.gd" id="1_60pcp"]
|
||||
|
||||
[node name="rock" type="AnimatableBody2D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
sync_to_physics = false
|
||||
script = ExtResource("1_60pcp")
|
||||
falling_gravity = 400.0
|
||||
kill = null
|
||||
max_fall_speed = 600.0
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cmjwk4gr1nfns"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://hme2aiy2gff7" path="res://_props/tools/rock.gd" id="1_60pcp"]
|
||||
|
||||
[node name="rock" type="AnimatableBody2D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
sync_to_physics = false
|
||||
script = ExtResource("1_60pcp")
|
||||
falling_gravity = 400.0
|
||||
kill = null
|
||||
max_fall_speed = 600.0
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cmjwk4gr1nfns"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://hme2aiy2gff7" path="res://_props/tools/rock.gd" id="1_60pcp"]
|
||||
|
||||
[node name="rock" type="AnimatableBody2D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
sync_to_physics = false
|
||||
script = ExtResource("1_60pcp")
|
||||
falling_gravity = 400.0
|
||||
kill = null
|
||||
max_fall_speed = 600.0
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cmjwk4gr1nfns"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://hme2aiy2gff7" path="res://_props/tools/rock.gd" id="1_60pcp"]
|
||||
|
||||
[node name="rock" type="AnimatableBody2D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
sync_to_physics = false
|
||||
script = ExtResource("1_60pcp")
|
||||
falling_gravity = 400.0
|
||||
kill = null
|
||||
max_fall_speed = 600.0
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cmjwk4gr1nfns"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://hme2aiy2gff7" path="res://_props/tools/rock.gd" id="1_60pcp"]
|
||||
|
||||
[node name="rock" type="AnimatableBody2D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
sync_to_physics = false
|
||||
script = ExtResource("1_60pcp")
|
||||
falling_gravity = 400.0
|
||||
kill = null
|
||||
max_fall_speed = 600.0
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cmjwk4gr1nfns"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://hme2aiy2gff7" path="res://_props/tools/rock.gd" id="1_60pcp"]
|
||||
|
||||
[node name="rock" type="AnimatableBody2D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
sync_to_physics = false
|
||||
script = ExtResource("1_60pcp")
|
||||
falling_gravity = 400.0
|
||||
kill = null
|
||||
max_fall_speed = 600.0
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
extends Node2D
|
||||
|
||||
@export var binded_rock: Rock
|
||||
@export var binded_volumn: PlayerTriggerVolumn
|
||||
|
||||
var _rock : Rock
|
||||
var _volumn : PlayerTriggerVolumn
|
||||
|
||||
func _ready() -> void:
|
||||
_rock = binded_rock if binded_rock != null else _find_first_rock(self)
|
||||
_volumn = binded_volumn if binded_volumn != null else _find_first_volumn(self)
|
||||
|
||||
if not _volumn or not _rock: return
|
||||
|
||||
_volumn.player_entered.connect(_on_rock_start_shake,CONNECT_ONE_SHOT)
|
||||
|
||||
func _on_rock_start_shake(player: Player) -> void:
|
||||
if not _rock: return
|
||||
|
||||
_rock.start_shaking()
|
||||
$Timer.start()
|
||||
$Timer.timeout.connect(_on_rock_falling)
|
||||
|
||||
func _on_rock_falling() -> void:
|
||||
_rock.stop_shaking()
|
||||
_rock.start_falling()
|
||||
|
||||
|
||||
## ================================
|
||||
## 查找工具函数(强类型)
|
||||
## ================================
|
||||
|
||||
func _find_first_rock(root: Node) -> Rock:
|
||||
var found: Node = _find_first_child_matching(root, func(n: Node) -> bool: return n is Rock)
|
||||
return found as Rock
|
||||
|
||||
|
||||
func _find_first_volumn(root: Node) -> PlayerTriggerVolumn:
|
||||
var found: Node = _find_first_child_matching(root, func(n: Node) -> bool: return n is PlayerTriggerVolumn)
|
||||
return found as PlayerTriggerVolumn
|
||||
|
||||
|
||||
func _find_first_child_matching(root: Node, predicate: Callable) -> Node:
|
||||
for child: Node in root.get_children():
|
||||
# predicate.call() 返回值在类型系统里可能是 Variant,所以别用 := 推断
|
||||
var ok: bool = bool(predicate.call(child))
|
||||
if ok:
|
||||
return child
|
||||
|
||||
var deeper: Node = _find_first_child_matching(child, predicate)
|
||||
if deeper != null:
|
||||
return deeper
|
||||
|
||||
return null
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://b8yl6l3tlam86
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://knrcnoedxvm6"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bonrls3iuhdqb" path="res://_props/tools/player_trigger_volumn.tscn" id="1_mvp6g"]
|
||||
[ext_resource type="PackedScene" uid="uid://cmjwk4gr1nfns" path="res://_props/tools/rock.tscn" id="1_nh18e"]
|
||||
[ext_resource type="Script" uid="uid://b8yl6l3tlam86" path="res://_props/trigger_fall_rock/trigger_fall_rock.gd" id="1_vv0hj"]
|
||||
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="2_xilvp"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vv0hj"]
|
||||
size = Vector2(52, 51)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_mvp6g"]
|
||||
size = Vector2(52, 108.5)
|
||||
|
||||
[node name="TriggerFallRock" type="Node2D"]
|
||||
script = ExtResource("1_vv0hj")
|
||||
|
||||
[node name="rock" parent="." instance=ExtResource("1_nh18e")]
|
||||
position = Vector2(0, -82)
|
||||
falling_gravity = 100.0
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="rock"]
|
||||
scale = Vector2(0.4, 0.4)
|
||||
texture = ExtResource("2_xilvp")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="rock"]
|
||||
position = Vector2(0, -0.5)
|
||||
shape = SubResource("RectangleShape2D_vv0hj")
|
||||
debug_color = Color(0.99629647, 0, 0.19810504, 0.41960785)
|
||||
|
||||
[node name="PlayerTriggerVolumn" parent="." instance=ExtResource("1_mvp6g")]
|
||||
debug_print = true
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerTriggerVolumn"]
|
||||
position = Vector2(0, -54)
|
||||
shape = SubResource("RectangleShape2D_mvp6g")
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
wait_time = 0.8
|
||||
one_shot = true
|
||||
Binary file not shown.
|
|
@ -81,7 +81,6 @@ func enable_movement() -> void:
|
|||
func _physics_process(delta: float) -> void:
|
||||
if !_can_move :
|
||||
return #不允许移动,直接停止退出
|
||||
print("Loco 更新中")
|
||||
|
||||
_update_movement(delta) #更新移动输入
|
||||
_update_gravity(delta) #更新重力
|
||||
|
|
|
|||
21
update.md
21
update.md
|
|
@ -18,7 +18,16 @@ v0.1.3
|
|||
|
||||
v0.2.1
|
||||
|
||||
-
|
||||
- 添加了全局的特效管理器,添加了全局的特效层,现在所有的特效在一个单独的Canvas Layer上播放。
|
||||
- 添加了全局的音效管理器
|
||||
|
||||
v0.2.2
|
||||
|
||||
- 添加了基础的TriggerVolumn,可以定向的检测Player的碰撞,然后绑定到对应的组件上触发对应的效果
|
||||
- 添加了落石的基础类,可以实现,开始抖动,结束抖动,移动,结束移动,移动到目标点等一系列操作
|
||||
- 添加了一个落石的基础案例,可以在此案例的基础上对落石功能进行拓展和修改
|
||||
|
||||
|
||||
|
||||
## 更新计划
|
||||
|
||||
|
|
@ -53,11 +62,11 @@ V0.2
|
|||
- [ ] 相机功能
|
||||
- [ ] 相机追随
|
||||
- [ ] 相机震动
|
||||
|
||||
- [ ] 地图功能
|
||||
- [ ] 地图美术功能
|
||||
- [ ] 地图物件功能
|
||||
|
||||
- [ ] 落石
|
||||
- [ ] 移动跟随平台
|
||||
- [ ] 玩家死亡和重生的逻辑
|
||||
- [ ] Room功能:一个Level由n个Room组成,Room存在一个Entrance,玩家进入Entrance会让Entrance向上传输消息给Room并让镜头切换到对应的Room
|
||||
- [ ] entrance的对应不同的复活点,从不同的entrance进入会让玩家死亡后在不同的复活点复活
|
||||
|
|
@ -71,11 +80,11 @@ V0.3
|
|||
|
||||
- [x] VFX Manager
|
||||
- [x] 可以實現在場景中根據預設播放VFX
|
||||
- [ ] 將所有的VFX放置在一個插件專屬的Layer
|
||||
- [x] 將所有的VFX放置在一個插件專屬的Layer
|
||||
|
||||
- [ ] SFX Manager
|
||||
- [x] SFX Manager
|
||||
- [ ] 可以實現在場景中根據預設播放SFX
|
||||
- [ ] 可以播放一個隨機的SFX Asset
|
||||
- [x] 可以播放一個隨機的SFX Asset
|
||||
- [ ] 不同的SFX預設
|
||||
|
||||
- [ ] CameraShake Manager
|
||||
|
|
|
|||
Loading…
Reference in New Issue