extends Control @export var min_zoom: float = 0.3 @export var max_zoom: float = 3.0 @onready var content: Node2D = $MapContent @onready var open_button: IconButton = get_node("../MapButton") @onready var recenter_button: IconButton = $RecenterButton @onready var close_button: IconButton = $CloseButton @onready var fleet: Node2D = get_node("../../Fleet") var touches: Dictionary = {} var pinch_active: bool = false var pinch_start_distance: float = 0.0 var pinch_start_zoom: float = 1.0 func _ready() -> void: open_button.pressed.connect(open_map) recenter_button.pressed.connect(recenter_view) close_button.pressed.connect(close_map) func open_map() -> void: visible = true open_button.visible = false recenter_view() func close_map() -> void: visible = false open_button.visible = true touches.clear() pinch_active = false func recenter_view() -> void: var fleet_local: Vector2 = fleet.get_centroid() * content.WORLD_TO_LOCAL var viewport_center: Vector2 = get_viewport_rect().size / 2.0 content.position = viewport_center - fleet_local * content.scale.x func _input(event: InputEvent) -> void: if not visible: return if event is InputEventScreenTouch: _handle_touch(event) get_viewport().set_input_as_handled() elif event is InputEventScreenDrag: _handle_drag(event) get_viewport().set_input_as_handled() elif event is InputEventMagnifyGesture: _handle_magnify(event) get_viewport().set_input_as_handled() func _handle_touch(event: InputEventScreenTouch) -> void: if event.pressed: touches[event.index] = event.position if touches.size() == 2: pinch_active = true var positions: Array = touches.values() pinch_start_distance = positions[0].distance_to(positions[1]) pinch_start_zoom = content.scale.x else: touches.erase(event.index) if touches.size() < 2: pinch_active = false func _handle_drag(event: InputEventScreenDrag) -> void: if not touches.has(event.index): return var previous_pos: Vector2 = touches[event.index] touches[event.index] = event.position if pinch_active and touches.size() == 2 and pinch_start_distance > 0.0: var positions: Array = touches.values() var current_distance: float = positions[0].distance_to(positions[1]) var new_zoom: float = pinch_start_zoom * (current_distance / max(pinch_start_distance, 1.0)) _set_zoom(new_zoom) elif touches.size() == 1: content.position += event.position - previous_pos func _handle_magnify(event: InputEventMagnifyGesture) -> void: _set_zoom(content.scale.x * event.factor) func _set_zoom(z: float) -> void: var clamped: float = clamp(z, min_zoom, max_zoom) content.scale = Vector2(clamped, clamped)