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)