godot-plateformer/_camera/CameraSystem.gd

266 lines
6.6 KiB
GDScript3
Raw Normal View History

#'''全局的相机管理器
#
#======= 外部调用函数 =======
#
#'''
#@tool
#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
#var _dirty := false
#var _screen_size : Vector2i
#
### 玩家关卡内静态相机
#const CAMERA_FOLLOWER:= preload("res://camera/camera_follower.tscn")
#
#func _ready() -> void:
## Setting default screensize
#_screen_size = Vector2i(
#ProjectSettings.get_setting("display/window/size/viewport_width"),
#ProjectSettings.get_setting("display/window/size/viewport_height")
#)
#
## For editor
#if Engine.is_editor_hint():
#ProjectSettings.settings_changed.connect(func():
#_screen_size = Vector2i(
#ProjectSettings.get_setting("display/window/size/viewport_width"),
#ProjectSettings.get_setting("display/window/size/viewport_height")
#)
#)
## For runtime
#else:
#get_tree().get_root().size_changed.connect(func():
#_screen_size = get_viewport().get_visible_rect().size
#)
#
#func _editor_ready() -> void:
#ProjectSettings.settings_changed.connect(func():
#_screen_size = Vector2i(
#ProjectSettings.get_setting("display/window/size/viewport_width"),
#ProjectSettings.get_setting("display/window/size/viewport_height")
#)
#)
#
#func _runtime_ready() -> void:
#get_tree().get_root().size_changed.connect(func():
#_screen_size = get_viewport().get_visible_rect().size
#)
#
##func _process(delta):
##if not Engine.is_editor_hint():
##_runtime_process(delta)
#
#
#func _runtime_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 _on_player_spawned(new_player: Player) -> void:
#if _current_anchor and _current_anchor.follow_player:
#_bind_camera_follow_to_player(new_player)
#
#func _on_player_dead() -> void:
#return
#
### 绑定camera 到 player
#func _bind_camera_follow_to_player(player: Player) -> void:
#if _player_remote and is_instance_valid(_player_remote):
#_player_remote.queue_free()
#_player_remote = null
#
#if not is_instance_valid(player):
#return
#
#var rt := RemoteTransform2D.new()
#rt.name = "__CameraAnchorFollow"
#rt.remote_path = camera_2d.get_path()
#rt.update_position = true
#rt.update_rotation = false
#rt.update_scale = false
#
#player.add_child(rt)
#_player_remote = rt
#
### 外部获取玩家全局相机
#func get_cached_camera() -> Camera2D:
#return camera_2d
#
### 注册一个相机锚点
#func register_anchor(anchor: CameraAnchor) -> void:
#if anchor in _cached_anchors:
#return
#_cached_anchors.append(anchor)
#anchor.on_priority_change.connect(on_anchor_priority_changed)
#_request_evaluate()
#
### 当相机锚点的权重改变时,向管理器触发事件
#func on_anchor_priority_changed(priority:int, anchor: CameraAnchor) -> void:
#_request_evaluate()
#
### 注销一个相机锚点
#func unregister_anchor(anchor: CameraAnchor) -> void:
#_cached_anchors.erase(anchor)
#if _current_anchor == anchor:
#_current_anchor = null
#_request_evaluate()
#
#func _request_evaluate() -> void:
#_dirty = true
#if _switch_scheduled:
#return
#_switch_scheduled = true
#call_deferred("_commit_camera_anchor")
#
#func _commit_camera_anchor() -> void:
#_switch_scheduled = false
#if not _dirty:
#return
#_dirty = false
#
## 清理无效
#_cached_anchors = _cached_anchors.filter(func(a): return is_instance_valid(a))
#
#var winner: CameraAnchor = _pick_best_anchor()
#
#if winner == null:
#return
#
#if winner == _current_anchor:
#return
#
#switch_anchor(winner)
#
#func _pick_best_anchor() -> CameraAnchor:
#var best: CameraAnchor = null
#var best_p := -INF
#
#for a in _cached_anchors:
#if not a.enabled:
#continue
#if a._priority > best_p:
#best_p = a._priority
#best = a
#
#return best
#
### 排序已有的锚点
#func _sort_anchors() -> void:
#_cached_anchors.sort_custom(func(a, b):
#return a._priority > b._priority
#)
#
### 尝试自切换
#func _try_auto_switch() -> void:
#for a in _cached_anchors:
#if a.enabled:
#switch_anchor(a)
#_current_anchor = a
#return
#
#
#
###应用Anchor的Limit
#func _apply_anchor_limits(anchor: CameraAnchor) -> void:
#if not camera_2d:
#return
#camera_2d.limit_left = anchor.global_position.x + anchor.limit_left
#camera_2d.limit_right = anchor.global_position.x + anchor.limit_right
#camera_2d.limit_top = anchor.global_position.y + anchor.limit_top
#camera_2d.limit_bottom = anchor.global_position.y + anchor.limit_bottom
#
#func _clear_camera_limits() -> void:
#if not camera_2d:
#return
#camera_2d.limit_left = -10000000
#camera_2d.limit_right = 10000000
#camera_2d.limit_top = -10000000
#camera_2d.limit_bottom = 10000000
#
### 切换相机
#func switch_anchor(target_anchor: CameraAnchor) -> void:
#if target_anchor == null:
#return
#if target_anchor == _current_anchor:
#return
#if not is_instance_valid(camera_2d):
#return
#
##优先清除已有的remote
#if _player_remote:
#_player_remote.queue_free()
#_player_remote = null
#
## 中断旧 Tween
#if _switch_tween and _switch_tween.is_running():
#_switch_tween.kill()
#_switch_tween = null
#
#var camera := camera_2d
#var blend_time : float = max(target_anchor.blend_time, 0.001)
#
#_clear_camera_limits()
#
#_switch_tween = get_tree().create_tween()
#_switch_tween.set_ignore_time_scale(true)
#_switch_tween.set_trans(Tween.TRANS_CUBIC)
#_switch_tween.set_ease(Tween.EASE_OUT)
#
## ===== 位置 =====
#_switch_tween.tween_property(
#self,
#"_base_camera_pos",
#target_anchor.global_position,
#blend_time
#)
#
## ===== Zoom =====
#_switch_tween.parallel().tween_property(
#camera,
#"zoom",
#target_anchor.zoom,
#blend_time * 1.5
#)
#
## 完成回调
#_switch_tween.finished.connect(func():
#_current_anchor = target_anchor
#_update_anchor_follow_state(target_anchor)
#_apply_anchor_limits(target_anchor)
#)
#
#_current_anchor = target_anchor
#
#func _update_anchor_follow_state(anchor: CameraAnchor) -> void:
#if not anchor.follow_player:
#return
#
#var player := GlobalEvent.get_player()
#if player:
#_bind_camera_follow_to_player(player)
#
## ==========================
## External API
## ==========================
### 重置所有的Camera的_priority
#func reset_all_camera_priority() -> void:
#for a in _cached_anchors:
#a._priority = 0
#
### 返回屏幕比例
#func get_screen_size() -> Vector2i:
#return _screen_size