initial commit
This commit is contained in:
4
.editorconfig
Normal file
4
.editorconfig
Normal file
@ -0,0 +1,4 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Normalize EOL for all files that Git considers text files.
|
||||
* text=auto eol=lf
|
||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
/android/
|
||||
1
icon.svg
Normal file
1
icon.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>
|
||||
|
After Width: | Height: | Size: 994 B |
37
icon.svg.import
Normal file
37
icon.svg.import
Normal file
@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b7sxyli8cn36w"
|
||||
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.svg"
|
||||
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
25
main.tscn
Normal file
25
main.tscn
Normal file
@ -0,0 +1,25 @@
|
||||
[gd_scene load_steps=9 format=3 uid="uid://dogqi2c58qdc0"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://j3j483itissq" path="res://scripts/star_system_generator.gd" id="1_ig7tw"]
|
||||
[ext_resource type="PackedScene" uid="uid://5uqp4amjj7ww" path="res://scenes/star.tscn" id="2_7mycd"]
|
||||
[ext_resource type="PackedScene" uid="uid://clt4qlsjcfgln" path="res://scenes/planet.tscn" id="3_272bh"]
|
||||
[ext_resource type="PackedScene" uid="uid://74ppvxcw8an4" path="res://scenes/moon.tscn" id="4_5vw27"]
|
||||
[ext_resource type="PackedScene" uid="uid://dm3s33o4xhqfv" path="res://scenes/station.tscn" id="5_kek77"]
|
||||
[ext_resource type="PackedScene" uid="uid://bawsujtlpmh5r" path="res://scenes/asteroid.tscn" id="6_4c57u"]
|
||||
[ext_resource type="PackedScene" uid="uid://cm5qsuunboxm3" path="res://scenes/developer_pawn.tscn" id="7_272bh"]
|
||||
[ext_resource type="PackedScene" uid="uid://ctlw5diis8h1x" path="res://scenes/map_canvas.tscn" id="8_5vw27"]
|
||||
|
||||
[node name="Node2D" type="Node2D"]
|
||||
script = ExtResource("1_ig7tw")
|
||||
star_scene = ExtResource("2_7mycd")
|
||||
planet_scene = ExtResource("3_272bh")
|
||||
moon_scene = ExtResource("4_5vw27")
|
||||
station_scene = ExtResource("5_kek77")
|
||||
asteroid_scene = ExtResource("6_4c57u")
|
||||
|
||||
[node name="DeveloperPawn" parent="." node_paths=PackedStringArray("map_canvas") instance=ExtResource("7_272bh")]
|
||||
input_pickable = true
|
||||
map_canvas = NodePath("../MapCanvas")
|
||||
|
||||
[node name="MapCanvas" parent="." node_paths=PackedStringArray("star_system_generator") instance=ExtResource("8_5vw27")]
|
||||
star_system_generator = NodePath("..")
|
||||
43
project.godot
Normal file
43
project.godot
Normal file
@ -0,0 +1,43 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="space_simulation"
|
||||
run/main_scene="uid://dogqi2c58qdc0"
|
||||
config/features=PackedStringArray("4.4", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[input]
|
||||
|
||||
scroll_up={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":4,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
scroll_down={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":5,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
ui_map_mode={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":77,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[physics]
|
||||
|
||||
3d/default_linear_damp=0.0
|
||||
3d/sleep_threshold_linear=0.0
|
||||
2d/default_gravity=0.0
|
||||
2d/default_gravity_vector=Vector2(0, 0)
|
||||
2d/default_linear_damp=0.0
|
||||
2d/sleep_threshold_linear=0.0
|
||||
7
scenes/asteroid.tscn
Normal file
7
scenes/asteroid.tscn
Normal file
@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bawsujtlpmh5r"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c816xae77cbmq" path="res://scripts/asteroid.gd" id="1_akfqu"]
|
||||
|
||||
[node name="Asteroid" type="RigidBody2D"]
|
||||
script = ExtResource("1_akfqu")
|
||||
metadata/_custom_type_script = "uid://c816xae77cbmq"
|
||||
9
scenes/developer_pawn.tscn
Normal file
9
scenes/developer_pawn.tscn
Normal file
@ -0,0 +1,9 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://cm5qsuunboxm3"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://baawsgn3k6wpp" path="res://scripts/developer_pawn.gd" id="1_lme2g"]
|
||||
|
||||
[node name="DeveloperPawn" type="CharacterBody2D" node_paths=PackedStringArray("camera")]
|
||||
script = ExtResource("1_lme2g")
|
||||
camera = NodePath("Camera2D")
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
11
scenes/map_canvas.tscn
Normal file
11
scenes/map_canvas.tscn
Normal file
@ -0,0 +1,11 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://ctlw5diis8h1x"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://drsuoxsqdxdql" path="res://scripts/map_canvas.gd" id="1_r1rlf"]
|
||||
[ext_resource type="Script" uid="uid://uh0k4c3qj4x0" path="res://scenes/map_drawer.gd" id="2_tspw4"]
|
||||
|
||||
[node name="MapCanvas" type="CanvasLayer" node_paths=PackedStringArray("map_drawer")]
|
||||
script = ExtResource("1_r1rlf")
|
||||
map_drawer = NodePath("Node2D")
|
||||
|
||||
[node name="Node2D" type="Node2D" parent="."]
|
||||
script = ExtResource("2_tspw4")
|
||||
70
scenes/map_drawer.gd
Normal file
70
scenes/map_drawer.gd
Normal file
@ -0,0 +1,70 @@
|
||||
class_name MapDrawer
|
||||
extends Node2D
|
||||
|
||||
# A reference to the StarSystemGenerator node, which will be set by the MapCanvas.
|
||||
var star_system_generator: Node
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
# This forces the canvas to redraw every frame.
|
||||
queue_redraw()
|
||||
func _draw() -> void:
|
||||
if not star_system_generator:
|
||||
return
|
||||
|
||||
# Draw a black background to obscure the main simulation view.
|
||||
var viewport_size = get_viewport().get_visible_rect().size
|
||||
draw_rect(Rect2(Vector2.ZERO, viewport_size), Color("3d3d3d"))
|
||||
|
||||
var max_distance = 0.0
|
||||
var all_bodies = star_system_generator.get_all_bodies()
|
||||
|
||||
# Find the furthest body from the star.
|
||||
for body in all_bodies:
|
||||
var distance = body.position.length()
|
||||
if distance > max_distance:
|
||||
max_distance = distance
|
||||
|
||||
# Determine the scale based on the viewport size.
|
||||
var system_diameter = max_distance * 2.0
|
||||
var draw_scale = min(viewport_size.x, viewport_size.y) / system_diameter
|
||||
draw_scale *= 0.8 # Add some padding to the view.
|
||||
|
||||
# Draw each celestial body on the canvas.
|
||||
for body in all_bodies:
|
||||
# Get the scaled position.
|
||||
var scaled_position = body.position * draw_scale + viewport_size / 2
|
||||
|
||||
# Define visual size based on body type.
|
||||
var radius = 0.0
|
||||
var color = Color.WHITE
|
||||
|
||||
match body.get_class_name():
|
||||
"Star":
|
||||
color = Color.GOLD
|
||||
"Planet":
|
||||
color = Color.BLUE
|
||||
"Moon":
|
||||
color = Color.PURPLE
|
||||
"Station":
|
||||
color = Color.WHITE
|
||||
"Asteroid":
|
||||
color = Color.BROWN
|
||||
_:
|
||||
color = Color.ORANGE_RED
|
||||
|
||||
if body is Star:
|
||||
radius = 10.0 # Make the star smaller for the map.
|
||||
elif body is Planet:
|
||||
radius = 8.0
|
||||
elif body is Moon:
|
||||
radius = 5.0
|
||||
elif body is Asteroid:
|
||||
radius = 4.0 # Make asteroids bigger for visibility.
|
||||
elif body is Station:
|
||||
radius = 6.0
|
||||
|
||||
# Draw the celestial body.
|
||||
draw_circle(scaled_position, radius, color)
|
||||
|
||||
# Position the text slightly to the side of the circle.
|
||||
draw_string(ThemeDB.fallback_font, scaled_position + Vector2(radius + 2, -5), body.name, HORIZONTAL_ALIGNMENT_LEFT, -1, ThemeDB.fallback_font_size, color)
|
||||
1
scenes/map_drawer.gd.uid
Normal file
1
scenes/map_drawer.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://uh0k4c3qj4x0
|
||||
7
scenes/moon.tscn
Normal file
7
scenes/moon.tscn
Normal file
@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://74ppvxcw8an4"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b1xsx7er22nxn" path="res://scripts/moon.gd" id="1_530pw"]
|
||||
|
||||
[node name="Moon" type="RigidBody2D"]
|
||||
script = ExtResource("1_530pw")
|
||||
metadata/_custom_type_script = "uid://bn1u2xood3vs6"
|
||||
7
scenes/planet.tscn
Normal file
7
scenes/planet.tscn
Normal file
@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://clt4qlsjcfgln"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://5f6ipgu65urb" path="res://scripts/planet.gd" id="1_cktii"]
|
||||
|
||||
[node name="Planet" type="RigidBody2D"]
|
||||
script = ExtResource("1_cktii")
|
||||
metadata/_custom_type_script = "uid://bn1u2xood3vs6"
|
||||
7
scenes/star.tscn
Normal file
7
scenes/star.tscn
Normal file
@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://5uqp4amjj7ww"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://um2sfghmii42" path="res://scripts/star.gd" id="1_mcqwg"]
|
||||
|
||||
[node name="Star" type="RigidBody2D"]
|
||||
script = ExtResource("1_mcqwg")
|
||||
metadata/_custom_type_script = "uid://bn1u2xood3vs6"
|
||||
7
scenes/station.tscn
Normal file
7
scenes/station.tscn
Normal file
@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://dm3s33o4xhqfv"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://ulw61oxppwdu" path="res://scripts/station.gd" id="1_rod8h"]
|
||||
|
||||
[node name="Station" type="RigidBody2D"]
|
||||
script = ExtResource("1_rod8h")
|
||||
metadata/_custom_type_script = "uid://bn1u2xood3vs6"
|
||||
19
scripts/asteroid.gd
Normal file
19
scripts/asteroid.gd
Normal file
@ -0,0 +1,19 @@
|
||||
class_name Asteroid
|
||||
extends CelestialBody
|
||||
|
||||
# The orbital radius for this asteroid.
|
||||
var orbital_radius: float
|
||||
|
||||
func get_class_name() -> String:
|
||||
return "Asteroid"
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
# An Asteroid has negligible mass for physics calculations.
|
||||
mass = 0.001
|
||||
radius = 5.0
|
||||
|
||||
# You can set a default texture here.
|
||||
# texture = preload("res://assets/asteroid_texture.png")
|
||||
|
||||
super._ready()
|
||||
1
scripts/asteroid.gd.uid
Normal file
1
scripts/asteroid.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://c816xae77cbmq
|
||||
94
scripts/celestial_body.gd
Normal file
94
scripts/celestial_body.gd
Normal file
@ -0,0 +1,94 @@
|
||||
class_name CelestialBody
|
||||
extends RigidBody2D
|
||||
|
||||
# The celestial body that this body orbits.
|
||||
@export var primary: CelestialBody
|
||||
|
||||
# Real-world gravitational constant.
|
||||
const G_REAL = 6.674e-11
|
||||
|
||||
# This is a placeholder for your pixel art texture.
|
||||
@export var texture: Texture2D
|
||||
|
||||
# The radius of the body, used for drawing and future collision detection.
|
||||
@export var radius: float = 10.0
|
||||
|
||||
# Real-world mass of the body in kilograms.
|
||||
@export_range(1.0, 1.989e+30, 1.0, "exp") var mass_real: float = 1.0
|
||||
|
||||
# The scaling factor for the simulation. A value of 1.0 means no scaling.
|
||||
var sim_scale: float = 1.0
|
||||
|
||||
# Default color based on body type for visualization.
|
||||
var body_color: Color = Color.ORANGE_RED
|
||||
|
||||
func get_class_name() -> String:
|
||||
return "CelestialBody"
|
||||
|
||||
func _ready() -> void:
|
||||
# Set the scaled mass based on the real-world mass and the simulation scale.
|
||||
# The scale is applied to the mass, so a smaller scale means a larger apparent mass.
|
||||
mass = mass_real / (sim_scale * sim_scale)
|
||||
|
||||
# We will handle gravity manually, so we set the built-in gravity scale to 0.
|
||||
gravity_scale = 0.0
|
||||
|
||||
# To make the simulation work without drag, we must set linear damping to 0.
|
||||
linear_damp = 0.0
|
||||
|
||||
# Set the color based on the class name for easy differentiation.
|
||||
|
||||
match get_class_name():
|
||||
"Star":
|
||||
body_color = Color.GOLD
|
||||
"Planet":
|
||||
body_color = Color.BLUE
|
||||
"Moon":
|
||||
body_color = Color.PURPLE
|
||||
"Station":
|
||||
body_color = Color.WHITE
|
||||
"Asteroid":
|
||||
body_color = Color.BROWN
|
||||
_:
|
||||
body_color = Color.ORANGE_RED
|
||||
|
||||
|
||||
# This callback is the correct place to apply custom forces to a RigidBody2D.
|
||||
func _integrate_forces(state: PhysicsDirectBodyState2D) -> void:
|
||||
if primary and is_instance_valid(primary):
|
||||
# Get the vector pointing from this body to its primary.
|
||||
var direction_to_primary = primary.global_position - state.transform.origin
|
||||
var distance_squared = direction_to_primary.length_squared()
|
||||
|
||||
# Prevent division by zero or a large force if bodies are on top of each other.
|
||||
if distance_squared > 1.0:
|
||||
# Calculate the magnitude of the gravitational force using Newton's law.
|
||||
# We now use the scaled masses, which is consistent with Godot's physics engine.
|
||||
# F = G * (m1 * m2) / r^2
|
||||
var force_magnitude = (G_REAL * self.mass * primary.mass) / distance_squared
|
||||
|
||||
# Apply the force in the direction of the primary.
|
||||
state.apply_central_force(direction_to_primary.normalized() * force_magnitude)
|
||||
|
||||
# We force a redraw here to update the body's visual representation.
|
||||
queue_redraw()
|
||||
|
||||
# Override the default drawing function to draw the body.
|
||||
# This is useful for debugging and visualization.
|
||||
func _draw() -> void:
|
||||
if texture:
|
||||
# If a texture is assigned, draw it.
|
||||
var size = Vector2(radius * 2, radius * 2)
|
||||
var offset = -size / 2.0
|
||||
draw_texture_rect(texture, Rect2(offset, size), false)
|
||||
else:
|
||||
# Otherwise, draw a simple placeholder circle.
|
||||
draw_circle(Vector2.ZERO, radius, body_color)
|
||||
|
||||
|
||||
# Calculates the velocity required for a stable circular orbit.
|
||||
func get_stable_orbit_velocity(primary_mass_real: float, distance_real: float) -> float:
|
||||
# The formula for real-world orbital velocity is v = sqrt(G * M / r)
|
||||
var real_world_velocity = sqrt((G_REAL * primary_mass_real) / distance_real)
|
||||
# Scale this velocity down to the simulation scale before returning.
|
||||
return real_world_velocity / sim_scale
|
||||
1
scripts/celestial_body.gd.uid
Normal file
1
scripts/celestial_body.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://bn1u2xood3vs6
|
||||
86
scripts/developer_pawn.gd
Normal file
86
scripts/developer_pawn.gd
Normal file
@ -0,0 +1,86 @@
|
||||
class_name DeveloperPawn
|
||||
extends CharacterBody2D
|
||||
|
||||
# Movement speed in pixels per second.
|
||||
@export var movement_speed: float = 500.0
|
||||
|
||||
# Zoom speed.
|
||||
@export var zoom_speed: float = 1.0
|
||||
|
||||
# Reference to the Camera2D node.
|
||||
@export var camera: Camera2D
|
||||
|
||||
# Reference to the new MapCanvas node.
|
||||
@export var map_canvas: CanvasLayer
|
||||
|
||||
var map_mode : bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
# Ensure all references are set.
|
||||
if not camera:
|
||||
print("ERROR: Camera2D reference not set on DeveloperPawn.")
|
||||
set_physics_process(false)
|
||||
return
|
||||
if not map_canvas:
|
||||
print("ERROR: MapCanvas reference not set on DeveloperPawn.")
|
||||
set_physics_process(false)
|
||||
return
|
||||
|
||||
# Disable the default physics processing on the pawn itself.
|
||||
# We will handle all movement manually for direct control.
|
||||
set_physics_process(false)
|
||||
|
||||
# Set the process mode to get input and move the pawn.
|
||||
set_process(true)
|
||||
|
||||
# Hide the map canvas initially.
|
||||
map_canvas.hide()
|
||||
|
||||
# Called every frame to handle input.
|
||||
func _process(delta: float) -> void:
|
||||
if not map_mode:
|
||||
handle_input(delta)
|
||||
|
||||
# Handles player input for movement and zooming.
|
||||
func handle_input(delta: float) -> void:
|
||||
# Get movement input from WASD keys.
|
||||
var input_vector = Vector2.ZERO
|
||||
if Input.is_action_pressed("ui_up"):
|
||||
input_vector.y -= 1
|
||||
if Input.is_action_pressed("ui_down"):
|
||||
input_vector.y += 1
|
||||
if Input.is_action_pressed("ui_left"):
|
||||
input_vector.x -= 1
|
||||
if Input.is_action_pressed("ui_right"):
|
||||
input_vector.x += 1
|
||||
|
||||
# Normalize the vector to prevent faster diagonal movement.
|
||||
input_vector = input_vector.normalized()
|
||||
|
||||
# Update the pawn's position directly.
|
||||
position += input_vector * movement_speed * delta
|
||||
|
||||
# Handles zoom input from the mouse wheel and map mode toggle.
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseButton:
|
||||
if camera and not map_mode:
|
||||
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
|
||||
# Zoom in by dividing the zoom vector.
|
||||
camera.zoom -= Vector2(zoom_speed, zoom_speed)
|
||||
elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
||||
# Zoom out by multiplying the zoom vector.
|
||||
camera.zoom += Vector2(zoom_speed, zoom_speed)
|
||||
|
||||
# Clamp the zoom to prevent it from getting too large or too small.
|
||||
# The minimum zoom is now 0.01, and the maximum is a larger value.
|
||||
camera.zoom.x = clamp(camera.zoom.x, 0.01, 250.0)
|
||||
camera.zoom.y = clamp(camera.zoom.y, 0.01, 250.0)
|
||||
|
||||
if event.is_action_pressed("ui_map_mode"):
|
||||
map_mode = not map_mode
|
||||
if map_mode:
|
||||
# If entering map mode, show the map canvas.
|
||||
map_canvas.show()
|
||||
else:
|
||||
# If exiting map mode, hide the map canvas.
|
||||
map_canvas.hide()
|
||||
1
scripts/developer_pawn.gd.uid
Normal file
1
scripts/developer_pawn.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://baawsgn3k6wpp
|
||||
22
scripts/map_canvas.gd
Normal file
22
scripts/map_canvas.gd
Normal file
@ -0,0 +1,22 @@
|
||||
class_name MapCanvas
|
||||
extends CanvasLayer
|
||||
|
||||
# A reference to the StarSystemGenerator node.
|
||||
@export var star_system_generator: Node
|
||||
|
||||
# A reference to the new MapDrawer node.
|
||||
@export var map_drawer: Node2D
|
||||
|
||||
func _ready() -> void:
|
||||
# Ensure the generator and drawer references are set.
|
||||
if not star_system_generator:
|
||||
print("ERROR: StarSystemGenerator reference not set on MapCanvas.")
|
||||
set_physics_process(false)
|
||||
return
|
||||
if not map_drawer:
|
||||
print("ERROR: MapDrawer reference not set on MapCanvas.")
|
||||
set_physics_process(false)
|
||||
return
|
||||
|
||||
# Pass the generator reference to the drawer node.
|
||||
map_drawer.star_system_generator = star_system_generator
|
||||
1
scripts/map_canvas.gd.uid
Normal file
1
scripts/map_canvas.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://drsuoxsqdxdql
|
||||
19
scripts/moon.gd
Normal file
19
scripts/moon.gd
Normal file
@ -0,0 +1,19 @@
|
||||
class_name Moon
|
||||
extends CelestialBody
|
||||
|
||||
# The orbital radius for this moon.
|
||||
var orbital_radius: float
|
||||
|
||||
func get_class_name() -> String:
|
||||
return "Moon"
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
# A Moon has a smaller mass than a planet.
|
||||
mass = 100.0
|
||||
radius = 10.0
|
||||
|
||||
# You can set a default texture here.
|
||||
# texture = preload("res://assets/moon_texture.png")
|
||||
|
||||
super._ready()
|
||||
1
scripts/moon.gd.uid
Normal file
1
scripts/moon.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://b1xsx7er22nxn
|
||||
19
scripts/planet.gd
Normal file
19
scripts/planet.gd
Normal file
@ -0,0 +1,19 @@
|
||||
class_name Planet
|
||||
extends CelestialBody
|
||||
|
||||
# The orbital radius for this planet.
|
||||
var orbital_radius: float
|
||||
|
||||
func get_class_name() -> String:
|
||||
return "Planet"
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
# A Planet has a smaller mass than a star.
|
||||
mass = 1000.0
|
||||
radius = 25.0
|
||||
|
||||
# You can set a default texture here.
|
||||
# texture = preload("res://assets/planet_texture.png")
|
||||
|
||||
super._ready()
|
||||
1
scripts/planet.gd.uid
Normal file
1
scripts/planet.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://5f6ipgu65urb
|
||||
17
scripts/star.gd
Normal file
17
scripts/star.gd
Normal file
@ -0,0 +1,17 @@
|
||||
class_name Star
|
||||
extends CelestialBody
|
||||
|
||||
func get_class_name() -> String:
|
||||
return "Star"
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
# A Star has no primary and a very large mass.
|
||||
primary = null
|
||||
mass = 100000.0
|
||||
radius = 50.0
|
||||
|
||||
# You can set a default texture here, or assign it in the Inspector.
|
||||
# texture = preload("res://assets/star_texture.png")
|
||||
|
||||
super._ready()
|
||||
1
scripts/star.gd.uid
Normal file
1
scripts/star.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://um2sfghmii42
|
||||
205
scripts/star_system_generator.gd
Normal file
205
scripts/star_system_generator.gd
Normal file
@ -0,0 +1,205 @@
|
||||
class_name StarSystemGenerator
|
||||
extends Node2D
|
||||
|
||||
# Number of bodies to generate for each type.
|
||||
@export var num_planets: int = 5
|
||||
@export var num_moons_per_planet: int = 2
|
||||
@export var num_stations: int = 3
|
||||
|
||||
|
||||
# Exported scenes to be instantiated. Drag and drop the scene files
|
||||
# for each body from the Godot FileSystem dock into these properties.
|
||||
@export var star_scene: PackedScene
|
||||
@export var planet_scene: PackedScene
|
||||
@export var moon_scene: PackedScene
|
||||
@export var station_scene: PackedScene
|
||||
@export var asteroid_scene: PackedScene
|
||||
|
||||
# --- Simulation Parameters ---
|
||||
@export var sim_scale: float = 1e+9 # A scale of 1 unit per 1 billion meters.
|
||||
|
||||
# --- Star Parameters ---
|
||||
# Increasing the star's mass to increase overall gravitational influence.
|
||||
const STAR_MASS_REAL = 1.989e+30 # Mass of the Sun in kg.
|
||||
const STAR_RADIUS = 50.0
|
||||
|
||||
# --- Planet Parameters ---
|
||||
# Increasing the distances to give planets more space and allow for higher velocities.
|
||||
const PLANET_DISTANCE_MIN = 50.0 * 1.5e+10 # 50 AU
|
||||
const PLANET_DISTANCE_MAX = 500.0 * 1.5e+10 # 500 AU
|
||||
const PLANET_COUNT_MIN = 3
|
||||
const PLANET_COUNT_MAX = 8
|
||||
|
||||
# --- Moon Parameters ---
|
||||
const MOON_DISTANCE_MIN = 2e8 # 20,000 km
|
||||
const MOON_DISTANCE_MAX = 3e9 # 100,000 km
|
||||
const MOON_COUNT_MIN = 0
|
||||
const MOON_COUNT_MAX = 4
|
||||
|
||||
# --- Asteroid Parameters ---
|
||||
# Minimum and maximum number of asteroids to generate.
|
||||
@export var MIN_ASTEROIDS: int = 50
|
||||
@export var MAX_ASTEROIDS: int = 200
|
||||
|
||||
const ASTEROID_DISTANCE_MIN = 3.2e11
|
||||
const ASTEROID_DISTANCE_MAX = 4.8e11
|
||||
|
||||
# --- Station Parameters ---
|
||||
const STATION_COUNT_MIN = 1
|
||||
const STATION_COUNT_MAX = 3
|
||||
|
||||
var star: CelestialBody
|
||||
var planets: Array
|
||||
var moons: Array
|
||||
var asteroids: Array
|
||||
var stations: Array
|
||||
|
||||
const NAME_TEMPLATE_STR = "%s_%s"
|
||||
|
||||
func _ready() -> void:
|
||||
generate_star_system()
|
||||
|
||||
func generate_star_system() -> void:
|
||||
randomize()
|
||||
|
||||
star = create_star()
|
||||
add_child(star)
|
||||
|
||||
planets = create_planets(star)
|
||||
for planet in planets:
|
||||
add_child(planet)
|
||||
|
||||
asteroids = create_asteroids(star)
|
||||
for asteroid in asteroids:
|
||||
add_child(asteroid)
|
||||
|
||||
stations = create_stations(star)
|
||||
for station in stations:
|
||||
add_child(station)
|
||||
|
||||
func get_all_bodies() -> Array:
|
||||
var all_bodies = []
|
||||
all_bodies.append(star)
|
||||
all_bodies.append_array(planets)
|
||||
all_bodies.append_array(asteroids)
|
||||
all_bodies.append_array(stations)
|
||||
all_bodies.append_array(moons)
|
||||
return all_bodies
|
||||
|
||||
func create_star() -> CelestialBody:
|
||||
var star_instance = star_scene.instantiate() as CelestialBody
|
||||
star_instance.position = Vector2.ZERO
|
||||
star_instance.mass_real = STAR_MASS_REAL
|
||||
star_instance.radius = STAR_RADIUS
|
||||
star_instance.sim_scale = sim_scale
|
||||
return star_instance
|
||||
|
||||
func create_planets(primary_body: CelestialBody) -> Array:
|
||||
var planets = []
|
||||
var planet_count = randi_range(PLANET_COUNT_MIN, PLANET_COUNT_MAX)
|
||||
for i in range(planet_count):
|
||||
var planet_instance = planet_scene.instantiate() as CelestialBody
|
||||
planet_instance.name = NAME_TEMPLATE_STR % [planet_instance.get_class_name(), i]
|
||||
planet_instance.primary = primary_body
|
||||
planet_instance.mass_real = randf_range(5.972e+24, 6.39e+26) # Earth to Saturn mass
|
||||
planet_instance.radius = randf_range(30.0, 80.0)
|
||||
planet_instance.sim_scale = sim_scale
|
||||
|
||||
var distance_real = randf_range(PLANET_DISTANCE_MIN, PLANET_DISTANCE_MAX)
|
||||
var distance_scaled = distance_real / sim_scale
|
||||
|
||||
var velocity_scaled = planet_instance.get_stable_orbit_velocity(primary_body.mass_real, distance_real)
|
||||
var orbit_angle = randf_range(0.0, PI * 2)
|
||||
|
||||
planet_instance.position.x = distance_scaled * cos(orbit_angle)
|
||||
planet_instance.position.y = distance_scaled * sin(orbit_angle)
|
||||
|
||||
planet_instance.linear_velocity = Vector2(0, velocity_scaled).rotated(orbit_angle + PI / 2.0)
|
||||
|
||||
planets.append(planet_instance)
|
||||
|
||||
var planet_moons = create_moons(planet_instance)
|
||||
for moon in planet_moons:
|
||||
planet_instance.add_child(moon)
|
||||
moons.append(moon)
|
||||
|
||||
return planets
|
||||
|
||||
func create_moons(primary_body: CelestialBody) -> Array:
|
||||
var moons = []
|
||||
var moon_count = randi_range(MOON_COUNT_MIN, MOON_COUNT_MAX)
|
||||
for i in range(moon_count):
|
||||
var moon_instance = moon_scene.instantiate() as CelestialBody
|
||||
moon_instance.name = NAME_TEMPLATE_STR % [moon_instance.get_class_name(), i]
|
||||
moon_instance.primary = primary_body
|
||||
moon_instance.mass_real = randf_range(7.342e+22, 1.48e+23) # Moon to Triton mass
|
||||
moon_instance.radius = randf_range(10.0, 20.0)
|
||||
moon_instance.sim_scale = sim_scale
|
||||
|
||||
var distance_real = randf_range(MOON_DISTANCE_MIN, MOON_DISTANCE_MAX)
|
||||
var distance_scaled = distance_real / sim_scale
|
||||
|
||||
var velocity_scaled = moon_instance.get_stable_orbit_velocity(primary_body.mass_real, distance_real)
|
||||
var orbit_angle = randf_range(0.0, PI * 2)
|
||||
|
||||
moon_instance.position.x = primary_body.position.x + distance_scaled * cos(orbit_angle)
|
||||
moon_instance.position.y = primary_body.position.y + distance_scaled * sin(orbit_angle)
|
||||
|
||||
moon_instance.linear_velocity = primary_body.linear_velocity + Vector2(0, velocity_scaled).rotated(orbit_angle + PI / 2.0)
|
||||
|
||||
moons.append(moon_instance)
|
||||
|
||||
return moons
|
||||
|
||||
func create_asteroids(primary_body: CelestialBody) -> Array:
|
||||
var asteroids = []
|
||||
var asteroid_count = randi_range(MIN_ASTEROIDS, MAX_ASTEROIDS)
|
||||
|
||||
for i in range(asteroid_count):
|
||||
var asteroid_instance = asteroid_scene.instantiate() as CelestialBody
|
||||
asteroid_instance.name = NAME_TEMPLATE_STR % [asteroid_instance.get_class_name(), i]
|
||||
asteroid_instance.primary = primary_body
|
||||
asteroid_instance.mass_real = randf_range(1e+12, 1e+16) # A realistic asteroid mass range
|
||||
asteroid_instance.radius = randf_range(2.0, 8.0)
|
||||
asteroid_instance.sim_scale = sim_scale
|
||||
|
||||
var distance_real = randf_range(ASTEROID_DISTANCE_MIN, ASTEROID_DISTANCE_MAX)
|
||||
var distance_scaled = distance_real / sim_scale
|
||||
|
||||
var velocity_scaled = asteroid_instance.get_stable_orbit_velocity(primary_body.mass_real, distance_real)
|
||||
var orbit_angle = randf_range(0.0, PI * 2)
|
||||
|
||||
asteroid_instance.position.x = distance_scaled * cos(orbit_angle)
|
||||
asteroid_instance.position.y = distance_scaled * sin(orbit_angle)
|
||||
|
||||
asteroid_instance.linear_velocity = Vector2(0, velocity_scaled).rotated(orbit_angle + PI / 2.0)
|
||||
|
||||
asteroids.append(asteroid_instance)
|
||||
|
||||
return asteroids
|
||||
|
||||
func create_stations(primary_body: CelestialBody) -> Array:
|
||||
var stations = []
|
||||
var station_count = randi_range(STATION_COUNT_MIN, STATION_COUNT_MAX)
|
||||
for i in range(station_count):
|
||||
var station_instance = station_scene.instantiate() as CelestialBody
|
||||
station_instance.name = NAME_TEMPLATE_STR % [station_instance.get_class_name(), i]
|
||||
station_instance.primary = primary_body
|
||||
station_instance.mass_real = randf_range(5e+5, 1e+6) # Realistic mass for a large space station
|
||||
station_instance.radius = randf_range(15.0, 25.0)
|
||||
station_instance.sim_scale = sim_scale
|
||||
|
||||
var distance_real = randf_range(PLANET_DISTANCE_MIN, PLANET_DISTANCE_MAX)
|
||||
var distance_scaled = distance_real / sim_scale
|
||||
|
||||
var velocity_scaled = station_instance.get_stable_orbit_velocity(primary_body.mass_real, distance_real)
|
||||
var orbit_angle = randf_range(0.0, PI * 2)
|
||||
|
||||
station_instance.position.x = distance_scaled * cos(orbit_angle)
|
||||
station_instance.position.y = distance_scaled * sin(orbit_angle)
|
||||
|
||||
station_instance.linear_velocity = Vector2(0, velocity_scaled).rotated(orbit_angle + PI / 2.0)
|
||||
|
||||
stations.append(station_instance)
|
||||
|
||||
return stations
|
||||
1
scripts/star_system_generator.gd.uid
Normal file
1
scripts/star_system_generator.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://j3j483itissq
|
||||
19
scripts/station.gd
Normal file
19
scripts/station.gd
Normal file
@ -0,0 +1,19 @@
|
||||
class_name Station
|
||||
extends CelestialBody
|
||||
|
||||
# The orbital radius for this station.
|
||||
var orbital_radius: float
|
||||
|
||||
func get_class_name() -> String:
|
||||
return "Station"
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
# A Station has negligible mass for physics calculations.
|
||||
mass = 0.001
|
||||
radius = 15.0
|
||||
|
||||
# You can set a default texture here.
|
||||
# texture = preload("res://assets/station_texture.png")
|
||||
|
||||
super._ready()
|
||||
1
scripts/station.gd.uid
Normal file
1
scripts/station.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://ulw61oxppwdu
|
||||
Reference in New Issue
Block a user