extends Node2D @export var SectorScenePath: String = "res://scenes/sector.tscn" @onready var container = $VBoxContainer @onready var camera: Camera2D = $Camera2D # Pamiętaj o poprawnej nazwie węzła kamery # KONFIGURACJA KAMERY (ZOOM) const ZOOM_SPEED = 0.1 const MIN_ZOOM = 0.25 const MAX_ZOOM = 4.0 # ZMIENNE DO PRZECIĄGANIA (PAN) - MUSZĄ BYĆ ZADEKLAROWANE TUTAJ var is_dragging: bool = false var drag_start_position: Vector2 = Vector2.ZERO func _ready(): #_init_background() _create_sector_buttons() # Upewnienie się, że kamera jest aktywna camera.make_current() # Ograniczenie ruchu kamery do granic świata $Camera2D.limit_left = 0 $Camera2D.limit_top = 0 $Camera2D.limit_right = Settings.MAP_WIDTH $Camera2D.limit_bottom = Settings.MAP_HEIGHT func _process(delta): # Tworzenie wektora ruchu na podstawie akcji (Input Map) var movement_vector = Vector2.ZERO # Ruch pionowy if Input.is_action_pressed("map_move_down"): movement_vector.y += 1.0 if Input.is_action_pressed("map_move_up"): movement_vector.y -= 1.0 # Ruch poziomy if Input.is_action_pressed("map_move_right"): movement_vector.x += 1.0 if Input.is_action_pressed("map_move_left"): movement_vector.x -= 1.0 # Normalizacja wektora, aby ruch po przekątnej nie był szybszy if movement_vector.length() > 0: movement_vector = movement_vector.normalized() # Aktualizacja pozycji kamery # Ruch jest skalowany przez czas (delta), prędkość i aktualny poziom zoomu camera.position += movement_vector * Settings.MOVE_SPEED * camera.zoom * delta # OPCJONALNIE: Ograniczenie ruchu do granic mapy (jeśli je ustaliłeś) # camera.position.x = clampf(camera.position.x, camera.limit_left, camera.limit_right) # camera.position.y = clampf(camera.position.y, camera.limit_top, camera.limit_bottom) # --- TWORZENIE GWIAZD SEKTORÓW --- const GLOBAL_STAR_REDUCTION = 0.45 # Zmniejsza gwiazdy do 65% oryginalnego rozmiaru const FONT_PATH := "res://assets/fonts/Chopsic.otf" func _create_sector_buttons(): for child in container.get_children(): child.queue_free() var font = load(FONT_PATH) for i in range(Manager.SECTOR_COUNT): var sector_info = Manager.get_sector(i) var button = TextureButton.new() button.texture_normal = load(sector_info["star"]["texture_path"]) button.stretch_mode = TextureButton.STRETCH_KEEP_ASPECT_CENTERED # Skala gwiazdy var star_scale = sector_info["star"]["scale"] * GLOBAL_STAR_REDUCTION button.scale = Vector2(star_scale, star_scale) button.position = sector_info["position"] print(button.scale) # --- Podpis sektora --- var label = Label.new() label.text = sector_info["name"] label.add_theme_font_override("font", font) label.scale = Vector2(1 / star_scale, 1 / star_scale) # Ustawienie grubości konturu label.add_theme_constant_override("outline_size", 2) # Grubość konturu 2px # Ustawienie koloru konturu label.add_theme_color_override("font_outline_color", Color.BLACK) label.add_theme_font_size_override("font_size", 7) label.modulate = Color(0.887, 0.867, 0.836, 1.0) label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER # umieszczamy labelkę POD gwiazdą (np. 60 px niżej) var button_width = button.size.x var button_height = button.size.y # ... reszta kodu do centrowania i pozycjonowania label.position = Vector2(-1000, 1500) button.add_child(label) var index = i button.pressed.connect(func(): _on_sector_selected(index)) container.add_child(button) # --- WYBRANIE SEKTORA --- func _on_sector_selected(index: int): Manager.current_sector = index var sector_scene = load(SectorScenePath) get_tree().change_scene_to_packed(sector_scene) # --- TŁO --- func _init_background(): var background = Sprite2D.new() background.texture = load(Settings.GALAXY_BACKGROUND) background.centered = true background.position = get_viewport_rect().size / 2 var screen_size = get_viewport_rect().size var tex_size = background.texture.get_size() var scale_factor = max(screen_size.x / tex_size.x, screen_size.y / tex_size.y) background.scale = Vector2(scale_factor, scale_factor) add_child(background) background.z_index = -10 func _unhandled_input(event): # --- PRZESUWANIE (PAN) --- if event is InputEventMouseButton: # Rozpoczęcie przeciągania (domyślnie Prawy Przycisk Mysz) if event.button_index == MOUSE_BUTTON_RIGHT and event.pressed: is_dragging = true # Zapis pozycji myszy w koordynatach ekranu drag_start_position = event.position get_viewport().set_input_as_handled() # Zakończenie przeciągania elif event.button_index == MOUSE_BUTTON_RIGHT and not event.pressed: is_dragging = false get_viewport().set_input_as_handled() # --- SKALOWANIE (ZOOM) --- elif event.button_index == MOUSE_BUTTON_WHEEL_UP: # Kółko w górę (przybliżanie) _apply_zoom(1.0 / (1.0 + ZOOM_SPEED)) get_viewport().set_input_as_handled() elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN: # Kółko w dół (oddalanie) _apply_zoom(1.0 + ZOOM_SPEED) get_viewport().set_input_as_handled() if event is InputEventMouseMotion and is_dragging: # Przesunięcie myszy od ostatniej klatki var delta_drag = event.position - drag_start_position # Zmiana pozycji kamery # Dzielimy przez zoom, aby ruch był stały niezależnie od skali camera.position -= delta_drag * camera.zoom # Aktualizujemy punkt startowy, aby śledzić ciągły ruch drag_start_position = event.position get_viewport().set_input_as_handled() func _apply_zoom(factor: float): var new_zoom = camera.zoom * factor # Ograniczenie zoomu do zdefiniowanych minimalnych i maksymalnych wartości new_zoom.x = clampf(new_zoom.x, MIN_ZOOM, MAX_ZOOM) new_zoom.y = clampf(new_zoom.y, MIN_ZOOM, MAX_ZOOM) camera.zoom = new_zoom