godot-plateformer/addons/reedcamera/scripts/ScreenRatioRect.gd

115 lines
2.4 KiB
GDScript3
Raw Permalink Normal View History

2026-01-13 16:52:45 +08:00
@tool
extends Node2D
class_name ScreenRatioRect
# ===============================
# Internal State
# ===============================
var _rect: Rect2 = Rect2()
var _line_color: Color = Color(0.2, 0.9, 0.4, 0.9)
var _line_width: float = 2.0
var _target_node: Node2D = null
var _target_screen_pos: Vector2 = Vector2.ZERO
var _target_radius: float = 6.0
var _target_color: Color = Color(1, 0.3, 0.3, 0.9)
func _process(_delta: float) -> void:
if Engine.is_editor_hint():
return
if _target_node:
_update_target_screen_pos()
queue_redraw()
# ===============================
# Public API
# ===============================
## 通过屏幕比例设置0~1
func set_ratio(ratio: Vector2) -> void:
var viewport_size := get_viewport_rect().size
var size := viewport_size * ratio
var pos := (viewport_size - size) * 0.5
set_rect(Rect2(pos, size))
## 直接设置屏幕空间 Rect
func set_rect(rect: Rect2) -> void:
_rect = rect
queue_redraw()
## 设置绘制风格
func set_style(color: Color, width: float = 2.0) -> void:
_line_color = color
_line_width = width
queue_redraw()
## 设置追踪点
func set_target_node(node: Node2D) -> void:
_target_node = node
_update_target_screen_pos()
queue_redraw()
## 更新targetnode在屏幕的位置
func _update_target_screen_pos() -> void:
if not _target_node:
return
_target_screen_pos = \
_target_node.get_global_transform_with_canvas().get_origin()
## 可选:快速隐藏 / 显示
func clear() -> void:
_target_node = null
_rect = Rect2()
queue_redraw()
# ===============================
# Draw
# ===============================
func _draw() -> void:
if _rect.size == Vector2.ZERO:
return
var left := _rect.position.x
var right := _rect.position.x + _rect.size.x
var top := _rect.position.y
var bottom := _rect.position.y + _rect.size.y
var vp_size := get_viewport_rect().size
# 上边线
draw_line(
Vector2(0, top),
Vector2(vp_size.x, top),
_line_color,
_line_width
)
# 下边线
draw_line(
Vector2(0, bottom),
Vector2(vp_size.x, bottom),
_line_color,
_line_width
)
# 左边线
draw_line(
Vector2(left, 0),
Vector2(left, vp_size.y),
_line_color,
_line_width
)
# 右边线
draw_line(
Vector2(right, 0),
Vector2(right, vp_size.y),
_line_color,
_line_width
)
##绘制角色位置锚点
if _target_node:
draw_circle(_target_screen_pos, _target_radius, _target_color)