相机碰撞功能添加

This commit is contained in:
RedisTKey 2026-01-11 23:31:06 +08:00
parent 027ea95584
commit c7b0729e34
17 changed files with 167 additions and 54 deletions

View File

@ -1,12 +1,16 @@
[gd_scene load_steps=37 format=3 uid="uid://gwhff4qaouxy"]
[gd_scene load_steps=41 format=3 uid="uid://gwhff4qaouxy"]
[ext_resource type="Script" uid="uid://dq1g1qp66chwy" path="res://_player/avatar.gd" id="1_rkqpu"]
[ext_resource type="Script" uid="uid://isu8onknb75o" path="res://_player/states/character_state_machine.gd" id="1_wvs5h"]
[ext_resource type="Script" uid="uid://15n8yfyr4eqj" path="res://_player/states/grounded.gd" id="2_5p50s"]
[ext_resource type="Texture2D" uid="uid://doxhsab56pe50" path="res://_asset/all.png" id="2_8nsdm"]
[ext_resource type="Script" uid="uid://dcfq4wnx2g6bs" path="res://_player/player_locomotion.gd" id="2_11vl8"]
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_shared/camera/camera_shake/CameraShakePreset.gd" id="2_u7cua"]
[ext_resource type="Resource" uid="uid://iv3hfxqm5503" path="res://_shared/camera/camera_shake/CSP_HorizontalOnly.tres" id="3_1a1t3"]
[ext_resource type="Resource" uid="uid://bs3cqsp23047i" path="res://_shared/camera/camera_shake/CSP_VerticalOnly.tres" id="4_01uoa"]
[ext_resource type="Script" uid="uid://b5hkfpjbye70" path="res://_player/states/idle.gd" id="4_30i7g"]
[ext_resource type="BlackboardPlan" uid="uid://nlw7rxugv5uh" path="res://_player/bbp_player.tres" id="4_mwufa"]
[ext_resource type="Resource" uid="uid://cs50mkt830f8r" path="res://_shared/camera/camera_shake/CSP_XY.tres" id="5_ciuu3"]
[ext_resource type="Script" uid="uid://bpd54nf8oxwsb" path="res://_player/states/player_hsm.gd" id="6_8q4ov"]
[ext_resource type="Script" uid="uid://po21boe8iqcc" path="res://_player/states/move.gd" id="7_rrwxs"]
[ext_resource type="Script" uid="uid://cjf7kds0cipkw" path="res://_tools/limbo_state_helper.gd" id="8_clxy3"]
@ -53,6 +57,11 @@ floor_snap_length = 4.0
platform_floor_layers = 4
platform_wall_layers = 4
script = ExtResource("1_rkqpu")
camera_shake_preset = Dictionary[StringName, ExtResource("2_u7cua")]({
&"x_only_light": ExtResource("3_1a1t3"),
&"xy_light": ExtResource("5_ciuu3"),
&"y_only_light": ExtResource("4_01uoa")
})
[node name="GroundCompanion" type="Area2D" parent="."]
unique_name_in_owner = true

View File

@ -11,6 +11,8 @@ class_name Player extends CharacterBody2D
@onready var collision_shape_2d: CollisionShape2D = %CollisionShape2D
##用来记录CameraShake的Preset
@export var camera_shake_preset : Dictionary[StringName,CameraShakePreset]
enum Direction{LEFT,RIGHT}
var direction: Direction = Direction.RIGHT: set = _player_direction_changed

View File

@ -33,15 +33,19 @@ func _enter() -> void:
if hook_inst:
var i = hook_inst.get_direction_id()
#if i >= 0:
#if i == 0 or i == 4:
#CameraSystem.get_cached_camera().emit_hook_touch_shock(0)
#elif i == 1 or i == 5:
#CameraSystem.get_cached_camera().emit_hook_touch_shock(1)
#elif i == 2 or i == 6:
#CameraSystem.get_cached_camera().emit_hook_touch_shock(2)
#elif i == 3 or i == 7:
#CameraSystem.get_cached_camera().emit_hook_touch_shock(3)
if i >= 0:
var csp : CameraShakePreset = null
if i == 0 or i == 4:
csp = agent.camera_shake_preset.get("y_only_light")
elif i == 1 or i == 5:
csp = agent.camera_shake_preset.get("xy_light")
elif i == 2 or i == 6:
csp = agent.camera_shake_preset.get("x_only_light")
elif i == 3 or i == 7:
csp = agent.camera_shake_preset.get("xy_light")
if csp:
CameraSystem.camera_shake_player.play(csp)
if root.grap_hook_state._jump_grace_timer > 0:
_hook_to_jump()

File diff suppressed because one or more lines are too long

View File

@ -6,11 +6,13 @@
extends Node
@onready var camera_2d: Camera2D = %Camera2D
@onready var camera_shake_player: CameraShakePlayer = %CameraShakePlayer
var _cached_anchors: Array[CameraAnchor] = []
var _current_anchor: CameraAnchor
var _switch_tween: Tween
var _player_remote: RemoteTransform2D
var _base_camera_pos := Vector2.ZERO
##标记位,用来检测当前帧是否存在相机切换
var _switch_scheduled := false
@ -20,6 +22,16 @@ var _dirty := false
const PLAYER_CAMERA_SCENE:= preload("res://_shared/camera/PlayerStaticCamera.tscn")
const CAMERA_FOLLOWER:= preload("res://_shared/camera/camera_follower.tscn")
func _ready() -> void:
_base_camera_pos = camera_2d.global_position
func _process(delta):
if not camera_2d:
return
var shake_offset := camera_shake_player.update(delta)
camera_2d.global_position = _base_camera_pos + shake_offset
## 外部获取玩家全局相机
func get_cached_camera() -> Camera2D:
return camera_2d
@ -149,8 +161,8 @@ func switch_anchor(target_anchor: CameraAnchor) -> void:
# ===== 位置 =====
_switch_tween.tween_property(
camera,
"global_position",
self,
"_base_camera_pos",
target_anchor.global_position,
blend_time
)

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://b8pv5wtbo0y20"]
[gd_scene load_steps=3 format=3 uid="uid://b8pv5wtbo0y20"]
[ext_resource type="Script" uid="uid://04mchxkp161a" path="res://_shared/camera/CameraSystem.gd" id="1_xxnab"]
[ext_resource type="Script" uid="uid://sfrjes1hq8b7" path="res://_shared/camera/camera_shake/CameraShakePlayer.gd" id="2_xxnab"]
[node name="CameraSystem" type="Node"]
script = ExtResource("1_xxnab")
@ -10,3 +11,7 @@ unique_name_in_owner = true
limit_smoothed = true
editor_draw_limits = true
editor_draw_drag_margin = true
[node name="CameraShakePlayer" type="Node" parent="Camera2D"]
unique_name_in_owner = true
script = ExtResource("2_xxnab")

View File

@ -1,24 +0,0 @@
class_name GlobalCamera extends Node2D
@onready var phantom_camera_2d: PhantomCamera2D = %PhantomCamera2D
@onready var _0_hook_touch_noise: PhantomCameraNoiseEmitter2D = %"0_Hook_Touch_Noise"
@onready var _45_hook_touch_noise: PhantomCameraNoiseEmitter2D = %"45_Hook_Touch_Noise"
@onready var _90_hook_touch_noise: PhantomCameraNoiseEmitter2D = %"90_Hook_Touch_Noise"
@onready var _135_hook_touch_noise: PhantomCameraNoiseEmitter2D = %"135_Hook_Touch_Noise"
func emit_camera_shock(noise: PhantomCameraNoise2D) -> void:
if not noise:
return
func emit_hook_touch_shock(dir : int) -> void:
match dir:
0:
_0_hook_touch_noise.emit()
1:
_45_hook_touch_noise.emit()
2:
_90_hook_touch_noise.emit()
3:
_135_hook_touch_noise.emit()

View File

@ -1 +0,0 @@
uid://52tgslofxoi2

View File

@ -1,11 +1,37 @@
[gd_scene load_steps=11 format=3 uid="uid://d1w8ftfhxycfy"]
[ext_resource type="Script" uid="uid://52tgslofxoi2" path="res://_shared/camera/GlobalCamera.gd" id="1_fixiw"]
[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="1_llsih"]
[ext_resource type="Script" uid="uid://bhd4nuiu23e7l" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd" id="3_0bl5s"]
[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_fixiw"]
[ext_resource type="Script" uid="uid://dimvdouy8g0sv" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd" id="6_ctkin"]
[sub_resource type="GDScript" id="GDScript_fixiw"]
script/source = "class_name GlobalCamera extends Node2D
@onready var phantom_camera_2d: PhantomCamera2D = %PhantomCamera2D
@onready var _0_hook_touch_noise: PhantomCameraNoiseEmitter2D = %\"0_Hook_Touch_Noise\"
@onready var _45_hook_touch_noise: PhantomCameraNoiseEmitter2D = %\"45_Hook_Touch_Noise\"
@onready var _90_hook_touch_noise: PhantomCameraNoiseEmitter2D = %\"90_Hook_Touch_Noise\"
@onready var _135_hook_touch_noise: PhantomCameraNoiseEmitter2D = %\"135_Hook_Touch_Noise\"
func emit_camera_shock(noise: PhantomCameraNoise2D) -> void:
if not noise:
return
func emit_hook_touch_shock(dir : int) -> void:
match dir:
0:
_0_hook_touch_noise.emit()
1:
_45_hook_touch_noise.emit()
2:
_90_hook_touch_noise.emit()
3:
_135_hook_touch_noise.emit()
"
[sub_resource type="Resource" id="Resource_pvk7k"]
script = ExtResource("3_fixiw")
@ -43,7 +69,7 @@ randomize_noise_seed = 1
metadata/_custom_type_script = "uid://dimvdouy8g0sv"
[node name="PlayerStaticCamera" type="Node2D"]
script = ExtResource("1_fixiw")
script = SubResource("GDScript_fixiw")
[node name="PhantomCamera2D" type="Node2D" parent="."]
unique_name_in_owner = true

View File

@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="CameraShakePreset" load_steps=2 format=3 uid="uid://iv3hfxqm5503"]
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_shared/camera/camera_shake/CameraShakePreset.gd" id="1_mwfjy"]
[resource]
script = ExtResource("1_mwfjy")
amplitude = Vector2(35, 0)
frequency = 55.0
fade_in = 0.04
fade_out = 0.06

View File

@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="CameraShakePreset" load_steps=2 format=3 uid="uid://bs3cqsp23047i"]
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_shared/camera/camera_shake/CameraShakePreset.gd" id="1_pnkiv"]
[resource]
script = ExtResource("1_pnkiv")
amplitude = Vector2(0, 35)
frequency = 55.0
fade_in = 0.04
fade_out = 0.06

View File

@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="CameraShakePreset" load_steps=2 format=3 uid="uid://cs50mkt830f8r"]
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_shared/camera/camera_shake/CameraShakePreset.gd" id="1_3oq5o"]
[resource]
script = ExtResource("1_3oq5o")
amplitude = Vector2(23, 23)
frequency = 55.0
fade_in = 0.04
fade_out = 0.06

View File

@ -0,0 +1,50 @@
# CameraShakePlayer.gd
extends Node
class_name CameraShakePlayer
var _preset: CameraShakePreset
var _time := 0.0
var _strength := 0.0
var _active := false
var _noise := FastNoiseLite.new()
var _noise_seed := randi()
func play(preset: CameraShakePreset) -> void:
_preset = preset
_time = 0.0
_strength = 0.0
_active = true
_noise.seed = _noise_seed
func stop() -> void:
_active = false
func update(delta: float) -> Vector2:
if not _active or not _preset:
return Vector2.ZERO
_time += delta
var total := _preset.fade_in + _preset.hold + _preset.fade_out
if _time >= total:
_active = false
return Vector2.ZERO
# ===== 强度曲线 =====
if _time < _preset.fade_in:
_strength = _time / _preset.fade_in
elif _time < _preset.fade_in + _preset.hold:
_strength = 1.0
else:
var t := (_time - _preset.fade_in - _preset.hold) / _preset.fade_out
_strength = 1.0 - t
# ===== Noise 偏移 =====
var shake_t := _time * _preset.frequency
var offset := Vector2(
_noise.get_noise_1d(shake_t),
_noise.get_noise_1d(shake_t + 1000)
)
return offset * _preset.amplitude * _strength

View File

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

View File

@ -0,0 +1,9 @@
# CameraShakePreset.gd
extends Resource
class_name CameraShakePreset
@export var amplitude := Vector2(6, 6) # 最大位移
@export var frequency := 25.0 # 抖动频率
@export var fade_in := 0.05
@export var hold := 0.1
@export var fade_out := 0.15

View File

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

View File

@ -1,12 +0,0 @@
[gd_resource type="Resource" script_class="PhantomCameraNoise2D" load_steps=2 format=3 uid="uid://dy1hsviasxfu0"]
[ext_resource type="Script" uid="uid://dimvdouy8g0sv" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd" id="1_oi7x7"]
[resource]
script = ExtResource("1_oi7x7")
amplitude = 8.0
frequency = 15.0
randomize_noise_seed = 1
noise_seed = 608
positional_multiplier_y = 2.0
metadata/_custom_type_script = "uid://dimvdouy8g0sv"