Files
g-world/scripts/game/vault_camera.gd
T

66 lines
2.7 KiB
GDScript

class_name VaultCamera
extends Camera2D
## Камера убежища: перетаскивание, зум колесом и клавиатурная прокрутка.
##
## Границы задаются встроенными limit_* по размеру убежища, поэтому вручную
## позицию не зажимаем — движок делает это сам.
const ZOOM_STEP := 1.2
const MIN_ZOOM := 0.45
const MAX_ZOOM := 2.2
const KEY_PAN_SPEED := 900.0
const EDGE_MARGIN := 420.0
## Сверху запас больше: там небо со светилами, и на него хочется смотреть.
const SKY_MARGIN := 900.0
var _dragging := false
func _ready() -> void:
var bounds := VaultGrid.bounds()
limit_left = int(bounds.position.x - EDGE_MARGIN)
limit_right = int(bounds.end.x + EDGE_MARGIN)
# Сверху отмеряем от поверхности, а не от бункера: над землёй стоит будка
# входа, и до неё нужно доезжать.
limit_top = int(-SKY_MARGIN)
limit_bottom = int(bounds.end.y + EDGE_MARGIN)
# Открываемся на верхних этажах — оттуда видно и вход, и застройку.
position = Vector2(bounds.get_center().x, bounds.position.y + VaultGrid.CELL.y)
func _process(delta: float) -> void:
var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
if direction != Vector2.ZERO:
position += direction * KEY_PAN_SPEED * delta / zoom.x
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton:
_handle_mouse_button(event as InputEventMouseButton)
elif event is InputEventMouseMotion and _dragging:
position -= (event as InputEventMouseMotion).relative / zoom
get_viewport().set_input_as_handled()
func _handle_mouse_button(event: InputEventMouseButton) -> void:
match event.button_index:
# На один щелчок колеса Godot шлёт и нажатие, и отпускание. Без
# проверки pressed шаг зума применялся бы дважды.
MOUSE_BUTTON_WHEEL_UP:
if event.pressed:
_zoom_by(ZOOM_STEP)
get_viewport().set_input_as_handled()
MOUSE_BUTTON_WHEEL_DOWN:
if event.pressed:
_zoom_by(1.0 / ZOOM_STEP)
get_viewport().set_input_as_handled()
MOUSE_BUTTON_RIGHT, MOUSE_BUTTON_MIDDLE:
# Правая и средняя кнопки таскают вид; левая остаётся строительству.
_dragging = event.pressed
get_viewport().set_input_as_handled()
func _zoom_by(factor: float) -> void:
var target := clampf(zoom.x * factor, MIN_ZOOM, MAX_ZOOM)
zoom = Vector2(target, target)