ArkSol/scripts/galaxy.gd

148 lines
4.7 KiB
GDScript

extends Node2D
@onready var StarScene = preload("res://scenes/star.tscn")
@onready var PlanetScene = preload("res://scenes/planet.tscn")
@onready var MenuScene = preload("res://scenes/menu.tscn")
@onready var camera = $Camera2D
@onready var TimeDispaly = $CanvasLayer2
var existing_star_positions: Array[Vector2] = []
const PLANET_HIDE_ZOOM = 0.6 # powyżej tego zoomu planety się chowają
func _ready():
if GameData.game_lunched == false:
_generate_galaxy(Settings.NUMBER_OF_SYSTEMS)
TimeDispaly.visible = true
GameData.game_lunched = true
func _process(delta):
var zoom_level = (camera.zoom.x + camera.zoom.y) / 2.0
for planet in get_tree().get_nodes_in_group("planets"):
planet.visible = zoom_level > PLANET_HIDE_ZOOM
func _generate_galaxy(count: int):
for i in range(count):
var star = StarScene.instantiate()
var safe_position = get_safe_star_position()
if safe_position != Vector2.ZERO:
star.star_name = Names.sector_names[randi() % Names.sector_names.size()]
star.planet_count = randi_range(Settings.min_planet, Settings.max_planet)
star.global_position = safe_position
add_child(star)
else:
# Przerwij pętlę, gdy nie można już znaleźć bezpiecznej pozycji
print("Zatrzymano generowanie po znalezieniu %s systemów." % i)
break
star.get_node("Sprite2D").texture = load("res://assets/stars/s%d.png" % randi_range(1,8))
add_child(star)
# generowanie planet dla danej gwiazdy
for j in range(star.planet_count):
var planet = PlanetScene.instantiate()
planet.pname = Names.planet_names[randi() % Names.planet_names.size()]
planet.orbit_radius = 45 + j * 40
planet.orbit_speed = randf_range(0.004, 0.01)
planet.size = randi_range(1, 3)
#assign_max_population(planet)
generate_planet_resources(planet) # <-- tu losujemy surowce
var angle = randf() * TAU
planet.position = Vector2(cos(angle), sin(angle)) * planet.orbit_radius
planet.res_rich = randf()
planet.biosfere = pow(randf_range(0.0, 1.0), 3) # float od 0 do 1
if planet.biosfere > 0.7:
planet.get_node("Sprite2D").texture = load("res://assets/planets/p%d.png" % randi_range(1,9))
else:
planet.get_node("Sprite2D").texture = load("res://assets/planets/p%d.png" % randi_range(10,18))
planet.get_node("Sprite2D").scale = Vector2(0.053*planet.size/2, 0.053*planet.size/2)
star.add_child(planet) # Planeta należy do gwiazdy!
star.planets.append(planet)
print("--- Koniec listy ---")
# Lista wszystkich możliwych surowców
var RESOURCE_TYPES = Names.RESOURCE_TYPES
func generate_planet_resources(planet):
planet.resources = {} # resetujemy słownik
for resource in RESOURCE_TYPES:
var res_name = resource.name
var chance = resource.chance
var exists = randi() % 100 < chance
var amount = 0
planet.resources[res_name] = {"exist": exists, "amount": amount}
#func assign_max_population(planet):
## planet_size = 1 (mała), 2 (średnia), 3 (duża)
#match planet.size:
#1:
#planet.max_pop = randi_range(1000, 5000)
#2:
#planet.max_pop = randi_range(10000, 20000)
#3:
#planet.max_pop = randi_range(40000, 80000)
#_:
#planet.max_pop = 0 # zabezpieczenie, gdyby coś poszło nie tak
func _input(event):
if event.is_action_pressed("ui_cancel"): # np. klawisz ESC
show_menu()
func show_menu():
var cam = $Camera2D
if cam:
cam.enabled = false
var menu_instance = MenuScene.instantiate()
TimeDispaly.visible = false
add_child(menu_instance)
menu_instance.z_index = 100 # na wierzchu wszystkiego
get_tree().paused = true # pauzuje grę, jeśli chcesz
#Te zmienne muszą być zadeklarowane poza funkcją (np. na początku skryptu)
## Funkcja zwracająca bezpieczną pozycję lub Vector2.ZERO po niepowodzeniu
func get_safe_star_position() -> Vector2:
const SQ_MIN_DISTANCE = Settings.MIN_DISTANCE * Settings.MIN_DISTANCE
var attempts = 0
while attempts < Settings.MAX_PLACEMENT_ATTEMPTS:
# 1. Losowanie nowej, potencjalnej pozycji (float)
var potential_pos = Vector2(
randf_range(Settings.MARGIN, Settings.x - Settings.MARGIN),
randf_range(Settings.MARGIN, Settings.y - Settings.MARGIN)
)
# 2. Sprawdzenie, czy pozycja jest bezpieczna
var is_safe = true
for existing_pos in existing_star_positions:
# Szybkie porównanie kwadratu odległości (wydajniejsze)
if existing_pos.distance_squared_to(potential_pos) < SQ_MIN_DISTANCE:
is_safe = false
break # Znaleziono kolizję, przerwij pętlę i spróbuj ponownie
if is_safe:
# Pozycja bezpieczna. Zapisz ją i zwróć.
existing_star_positions.append(potential_pos)
return potential_pos
attempts += 1
# 3. Limit prób osiągnięty
return Vector2.ZERO # Wektor zerowy sygnalizuje, że nie znaleziono pozycji