Scaled down simulation

This commit is contained in:
olof.pettersson
2025-09-15 16:01:22 +02:00
parent 34f1dd0b19
commit e8c04e820d
11 changed files with 241 additions and 135 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
# Godot 4+ specific ignores
.godot/
.vscode/
/android/
/addons/

View File

@ -11,13 +11,17 @@
[node name="Node2D" type="Node2D"]
script = ExtResource("1_h2yge")
min_asteroid_belts = 0
min_planets = 1
max_planets = 4
max_moons = 10
max_asteroid_belts = 2
max_star_stations = 0
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")
sim_scale = 1e+09
sim_scale = 0.21
[node name="DeveloperPawn" parent="." node_paths=PackedStringArray("map_canvas") instance=ExtResource("7_272bh")]
input_pickable = true

27
main.tscn6546160625.tmp Normal file
View File

@ -0,0 +1,27 @@
[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_h2yge"]
[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_h2yge")
min_asteroid_belts = 0
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")
sim_scale = 1e+09
[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("..")

View File

@ -10,7 +10,7 @@ func get_class_name() -> String:
# 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
#mass = 0.001
radius = 5.0
# You can set a default texture here.

View File

@ -5,7 +5,7 @@ extends RigidBody2D
@export var primary: CelestialBody
# Real-world gravitational constant.
const G_REAL = 6.674e-11
const G = 0.0001
# This is a placeholder for your pixel art texture.
@export var texture: Texture2D
@ -13,8 +13,6 @@ const G_REAL = 6.674e-11
# 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
@ -27,6 +25,7 @@ var orbit_radius_real : float = 0.0
var linear_velocity_real : Vector2 = Vector2.ZERO
var global_position_real : Vector2 = Vector2.ZERO
var current_central_force_real : Vector2 = Vector2.ZERO
var direction_to_primary : Vector2 = Vector2.ZERO
func get_class_name() -> String:
return "CelestialBody"
@ -34,13 +33,17 @@ func get_class_name() -> String:
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
# 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
angular_damp = 0.0
can_sleep = false
custom_integrator = true
# Set the color based on the class name for easy differentiation.
match get_class_name():
@ -58,24 +61,24 @@ func _ready() -> void:
body_color = Color.ORANGE_RED
var is_first_integration : bool = true
# 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_real - global_position_real
var distance_squared = direction_to_primary.length_squared()
#print(distance_squared / (sim_scale * sim_scale))
direction_to_primary = self.global_position.direction_to(primary.global_position)
var distance_squared = self.global_position.distance_squared_to(primary.global_position)
# 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_real * primary.mass_real) / (distance_squared)
var force_magnitude = (G * self.mass * primary.mass) / (distance_squared)
# Apply the force in the direction of the primary.
current_central_force_real = (direction_to_primary.normalized() * force_magnitude)
state.apply_central_force(current_central_force_real / sim_scale)
current_central_force_real = (direction_to_primary * force_magnitude)
state.apply_central_force(current_central_force_real)
# We force a redraw here to update the body's visual representation.
queue_redraw()
@ -94,14 +97,16 @@ func _draw() -> void:
func calculate_initial_orbit_real(primary: CelestialBody, orbiter : CelestialBody):
print("Orbital velocity for: " + str(orbiter))
# The formula for real-world orbital velocity is v = sqrt(G * M / r)
var magnitude = sqrt((G_REAL * primary.mass_real) / primary.global_position_real.distance_to(orbiter.global_position_real))
var magnitude = sqrt(G * (primary.mass) / primary.global_position.distance_to(orbiter.global_position))
print(magnitude)
# Calculate the relative position vector from the star to the body
var unit_vector = primary.global_position_real.direction_to(orbiter.global_position_real)
var unit_vector = primary.global_position.direction_to(orbiter.global_position)
print(unit_vector)
# Calculate a perpendicular vector (swapping and negating components)
var orbit_direction = Vector2(unit_vector.y, -unit_vector.x)
print(orbit_direction)
# Scale this velocity down to the simulation scale before returning.
return orbit_direction * magnitude
return orbit_direction * magnitude + primary.linear_velocity

View File

@ -1,104 +1,163 @@
class_name MapDrawer
extends Node2D
# A reference to the StarSystemGenerator node, which will be set by the MapCanvas.
var star_system_generator: StarSystemGenerator
# The body at the center of the map view.
var focal_body: CelestialBody
# The list of bodies to be rendered in the current view.
var bodies_to_draw: Array[CelestialBody] = []
# The scale used for drawing, stored to be accessible by the input handler.
var draw_scale: float = 1.0
# A reference to the generator, with a setter to initialize the view.
var star_system_generator: StarSystemGenerator:
set(value):
star_system_generator = value
# When the reference is set, initialize the view on the star.
if star_system_generator and star_system_generator.has_generated:
set_view(star_system_generator.get_system_data().star)
func _process(_delta: float) -> void:
# This forces the canvas to redraw every frame.
if not focal_body:
set_view(star_system_generator.get_system_data().star)
queue_redraw()
func _draw() -> void:
if not star_system_generator:
# --- Main Public Method ---
# Sets the view to a new central body and rebuilds the list of what to draw.
func set_view(new_focal_body: CelestialBody) -> void:
if not is_instance_valid(new_focal_body):
return
focal_body = new_focal_body
bodies_to_draw.clear()
# 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("000000"))
# The view always includes the focal body.
bodies_to_draw.append(focal_body)
# Add all direct children that are celestial bodies.
for child in focal_body.get_children():
if child is CelestialBody:
bodies_to_draw.append(child)
# If the star is the focus, also find and draw the asteroid belts.
if focal_body is Star:
var system_data = star_system_generator.get_system_data()
for belt in system_data.belts:
# We'll handle drawing belts separately in the _draw function.
pass
# --- Input Handling ---
func _unhandled_input(event: InputEvent) -> void:
if not focal_body:
return
# Handle Zoom In with Left Click
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():
for body in bodies_to_draw:
# Calculate the body's position on screen for hit-testing.
var relative_pos = body.global_position - focal_body.global_position
var scaled_pos = relative_pos * draw_scale + get_viewport_center()
var radius = _get_body_draw_radius(body)
if event.position.distance_to(scaled_pos) < radius * 2.0: # A larger click target
set_view(body)
get_viewport().set_input_as_handled()
return
# Handle Zoom Out with Right Click
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT and event.is_pressed():
if is_instance_valid(focal_body.primary):
set_view(focal_body.primary)
get_viewport().set_input_as_handled()
# --- Drawing Logic ---
func _draw() -> void:
# [cite_start]Draw a black background. [cite: 4]
draw_rect(Rect2(Vector2.ZERO, get_viewport_size()), Color.BLACK)
if not is_instance_valid(focal_body):
focal_body = star_system_generator.get_system_data().star
return
# 1. Determine the scale for the current view.
var max_distance = 0.0
var system_data = star_system_generator.get_system_data()
var all_bodies = system_data.all_bodies()
# Find the furthest body from the star.
for body in all_bodies:
var distance = body.global_position.length()
#print(body)
for body in bodies_to_draw:
if body == focal_body: continue
var distance = body.global_position.distance_to(focal_body.global_position)
if distance > max_distance:
max_distance = distance
# Determine the scale based on the viewport size.
# Add a default zoom level if focused on a body with no children.
if max_distance == 0.0:
max_distance = 5.0e8 # An arbitrary distance for a nice solo view.
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_scale = min(get_viewport_size().x, get_viewport_size().y) / system_diameter
draw_scale *= 0.8 # Add some padding.
for belt in system_data.belts:
var scaled_radius = Vector2(belt.centered_radius, 0.0) * draw_scale + viewport_size / 2
draw_circle(viewport_size / 2, (scaled_radius - viewport_size / 2).length(), Color.WHITE, false, 1.0)
#draw_string(ThemeDB.fallback_font, scaled_position + Vector2(radius + 2, -5), "Asteroid Belt", HORIZONTAL_ALIGNMENT_LEFT, -1, ThemeDB.fallback_font_size, Color.WHITE)
# Draw each celestial body on the canvas.
for body in all_bodies:
# Get the scaled position.
var scaled_position = body.global_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
# 2. Draw asteroid belts if the star is the focus.
if focal_body is Star:
for belt in star_system_generator.get_system_data().belts:
var relative_radius = belt.centered_radius - focal_body.global_position.length()
var scaled_radius = relative_radius * draw_scale
draw_circle(get_viewport_center(), scaled_radius, Color.WHITE, false)
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.
if body is Planet or body is Moon or body is Station:
draw_string(ThemeDB.fallback_font, scaled_position + Vector2(radius + 2, -5), body.name, HORIZONTAL_ALIGNMENT_LEFT, -1, ThemeDB.fallback_font_size, color)
draw_circle(viewport_size / 2, (scaled_position - viewport_size / 2).length(), Color.WHITE, false, 1.0)
draw_circle(scaled_position, radius, color)
# 3. Draw each celestial body relative to the focal body.
for body in bodies_to_draw:
var relative_pos = body.global_position - focal_body.global_position
var scaled_pos = relative_pos * draw_scale + get_viewport_center()
draw_string(ThemeDB.fallback_font, Vector2.ZERO + Vector2(10, 15), str(Engine.time_scale), HORIZONTAL_ALIGNMENT_LEFT, -1, ThemeDB.fallback_font_size, Color.HOT_PINK)
var radius = _get_body_draw_radius(body)
var color = _get_body_draw_color(body)
var velocity: Vector2 = body.linear_velocity * draw_scale
var force: Vector2 = body.current_central_force_real * draw_scale / body.sim_scale
# Draw orbit line for all children
if body != focal_body and body is not Asteroid:
draw_circle(get_viewport_center(), scaled_pos.distance_to(get_viewport_center()), Color(Color.WHITE, 0.2), false)
draw_string(ThemeDB.fallback_font, scaled_pos + Vector2(radius + 5, 5), body.name, HORIZONTAL_ALIGNMENT_LEFT, -1, ThemeDB.fallback_font_size, color)
# Draw the body itself.
draw_circle(scaled_pos, radius, color)
# Draw velocity and force vectors.
var velocity: Vector2 = body.linear_velocity.normalized() * 25.0
var force: Vector2 = body.direction_to_primary * 25.0 # Normalize force for consistent arrow size
draw_arrow(scaled_pos, scaled_pos + velocity, Color.GREEN)
draw_arrow(scaled_pos, scaled_pos + force, Color.RED)
# --- Helper Functions ---
func get_viewport_size() -> Vector2:
return get_viewport().get_visible_rect().size
func get_viewport_center() -> Vector2:
return get_viewport_size() / 2.0
func _get_body_draw_radius(body: CelestialBody) -> float:
if body is Star: return 15.0
elif body is Planet: return 10.0
elif body is Moon: return 6.0
elif body is Station: return 7.0
elif body is Asteroid: return 4.0
return 5.0
func _get_body_draw_color(body: CelestialBody) -> Color:
match body.get_class_name():
"Star": return Color.GOLD
"Planet": return Color.BLUE
"Moon": return Color.PURPLE
"Station": return Color.WHITE
"Asteroid": return Color.BROWN
return Color.ORANGE_RED
# Draw the velocity arrow
#
## Draw the force arrow
draw_arrow(scaled_position, scaled_position + force, Color(1, 0, 0))
draw_arrow(scaled_position, scaled_position + velocity, Color(0, 1, 0))
func draw_arrow(start: Vector2, end: Vector2, color: Color):
var head_size = max(1, (end - start).length() / 50) # Adjust the divisor for desired size
var direction = (end - start).normalized()
draw_line(start, end, color, 2.0)
var dir = (end - start).normalized()
var p1 = end - dir * 8 + dir.orthogonal() * 5
var p2 = end - dir * 8 - dir.orthogonal() * 5
draw_polygon(PackedVector2Array([end, p1, p2]), PackedColorArray([color, color, color]))
# Draw the line
draw_line(start, end, color)
# Draw the triangular arrowhead at the tip
var points = PackedVector2Array()
points.push_back(end)
points.push_back(end - direction * head_size + Vector2(-head_size, head_size))
points.push_back(end - direction * head_size + Vector2(-head_size, -head_size))
draw_polygon(points, PackedColorArray([color]))

View File

@ -10,7 +10,7 @@ func get_class_name() -> String:
# 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
#mass = 100.0
radius = 10.0
# You can set a default texture here.

View File

@ -10,7 +10,7 @@ func get_class_name() -> String:
# 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
#mass = 1000.0
radius = 25.0
# You can set a default texture here.

View File

@ -8,7 +8,6 @@ func get_class_name() -> String:
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.

View File

@ -32,13 +32,15 @@ extends Node2D
# A scaling parameter to convert real-world units to game units.
# 1 meter = sim_scale game units.
@export_group("Simulation Scale")
@export var sim_scale: float = 1.0e-9
@export_range(10e-12, 1.0, 10.e-3) var sim_scale: float = 1.0e-6
# A factor to scale the initial orbital distances to make the system visually compelling.
@export var min_ring_distance: float = 2.0e10
@export var min_ring_distance: float = 500
@export var min_planetary_orbit_radius : float = 50
# A factor to determine the buffer between orbits based on mass.
@export var orbit_buffer_factor: float = 1
const orbit_buffer_constant : float = 1.0e-13
const orbit_buffer_constant : float = 300
var orbit_buffer : float = orbit_buffer_constant * orbit_buffer_factor
# A flag to check if the system has been generated.
@ -46,7 +48,12 @@ var has_generated: bool = false
# Constants for real-world physics calculations.
const G = 6.67430e-11 # Gravitational constant (N·m²/kg²)
const SUN_MASS = 1.989e30 # Mass of the sun (kg)
#const SUN_MASS = 1.989e30 # Mass of the sun (kg)
const SUN_MASS = 10.000
const PLANETARY_MASS = SUN_MASS / 10
const MOON_MASS = PLANETARY_MASS / 10
const ASTEROID_MASS = MOON_MASS / 10
const STATION_MASS = ASTEROID_MASS / 10
var system_data : SystemData
@ -61,6 +68,8 @@ func generate_star_system() -> void:
# Create the star at the center of the system.
var star_instance = _create_star()
add_child(star_instance)
# Generate and place all celestial bodies in randomized order.
_generate_and_place_bodies(star_instance)
@ -69,12 +78,11 @@ func _create_star() -> RigidBody2D:
var star_instance = star_scene.instantiate() as Star
system_data.star = star_instance
star_instance.name = "Star"
add_child(star_instance)
star_instance.sim_scale = sim_scale
# Set the star's properties.
star_instance.orbit_radius_real = 0.0
star_instance.mass_real = SUN_MASS
star_instance.mass = SUN_MASS
star_instance.linear_velocity_real = Vector2.ZERO
star_instance.modulate = Color("ffe066") # Yellow
@ -112,15 +120,15 @@ func _generate_and_place_bodies(primary: RigidBody2D) -> void:
planet_instance.name = "Planet " + str(current_orbit_radius)
planet_instance.primary = primary
planet_instance.sim_scale = sim_scale
planet_instance.mass_real = randf_range(1e24, 1e25)
planet_instance.mass = PLANETARY_MASS # randf_range(1e24, 1e25)
# Calculate orbit based on the last placed body.
planet_instance.orbit_radius_real = current_orbit_radius + (planet_instance.mass_real * orbit_buffer)
planet_instance.orbit_radius_real = current_orbit_radius + (planet_instance.mass * orbit_buffer)
_create_body_in_ring(primary, planet_instance)
_create_moons_and_stations(planet_instance)
current_orbit_radius = planet_instance.orbit_radius_real + (planet_instance.mass_real * orbit_buffer)
current_orbit_radius = planet_instance.orbit_radius_real + (planet_instance.mass * orbit_buffer)
"asteroid_belt":
var belt = _create_asteroid_belt(primary, current_orbit_radius)
@ -134,38 +142,40 @@ func _generate_and_place_bodies(primary: RigidBody2D) -> void:
station_instance.name = "Star Station " + str(current_orbit_radius)
station_instance.primary = primary
station_instance.sim_scale = sim_scale
station_instance.mass_real = 1e8 # A very small mass
station_instance.mass = STATION_MASS # A very small mass
station_instance.orbit_radius_real = current_orbit_radius + (station_instance.mass_real * orbit_buffer)
station_instance.orbit_radius_real = current_orbit_radius + (station_instance.mass * orbit_buffer)
_create_body_in_ring(primary, station_instance)
current_orbit_radius = station_instance.orbit_radius_real + (station_instance.mass_real * orbit_buffer)
current_orbit_radius = station_instance.orbit_radius_real + (station_instance.mass * orbit_buffer)
print("Star system generation complete.")
# Creates moons and stations around a primary body.
func _create_moons_and_stations(primary: RigidBody2D) -> void:
var num_moons = randi_range(min_moons, max_moons)
var moon_orbit_radius = 5e7
var moon_orbit_radius = min_planetary_orbit_radius
for i in range(num_moons):
var moon_instance = moon_scene.instantiate() as CelestialBody
system_data.moons.append(moon_instance)
moon_instance.name = "Moon " + str(i + 1)
moon_instance.primary = primary
moon_instance.sim_scale = sim_scale
moon_instance.mass_real = randf_range(1e22, 1e23)
moon_instance.orbit_radius_real = moon_orbit_radius + randf_range(1e7, 5e7)
moon_instance.mass = MOON_MASS # randf_range(1e22, 1e23)
moon_instance.orbit_radius_real = moon_orbit_radius + randf_range(0, 50)
_create_body_in_ring(primary, moon_instance)
moon_orbit_radius = moon_instance.orbit_radius_real
# Generate a space station.
var station_instance = station_scene.instantiate() as CelestialBody
system_data.stations.append(station_instance)
station_instance.name = "Station"
station_instance.primary = primary
station_instance.sim_scale = sim_scale
station_instance.mass_real = 1e8
station_instance.orbit_radius_real = moon_orbit_radius + 5e7
station_instance.mass = STATION_MASS
station_instance.orbit_radius_real = moon_orbit_radius + randf_range(0, 50)
_create_body_in_ring(primary, station_instance)
# Creates a single asteroid belt.
@ -178,11 +188,11 @@ func _create_asteroid_belt(primary: RigidBody2D, initial_offset: float) -> Aster
asteroid_instance.name = "Asteroid " + str(i + 1)
asteroid_instance.primary = primary
asteroid_instance.sim_scale = sim_scale
asteroid_instance.mass_real = randf_range(1e10, 1e23)
asteroid_instance.mass = ASTEROID_MASS # randf_range(1e10, 1e23)
belt.asteroids.append(asteroid_instance)
belt.mass = belt.asteroids.reduce(func(accum, asteroid : CelestialBody): return accum + asteroid.mass_real, 0.0)
belt.mass = belt.asteroids.reduce(func(accum, asteroid : CelestialBody): return accum + asteroid.mass, 0.0)
var offset = belt.mass * orbit_buffer
belt.centered_radius = initial_offset + offset
@ -196,21 +206,19 @@ func _create_asteroid_belt(primary: RigidBody2D, initial_offset: float) -> Aster
# Helper function to instantiate and place a body in a ring.
func _create_body_in_ring(primary: CelestialBody, body_instance: CelestialBody) -> void:
var stable_velocity = calculate_stable_orbit_velocity(body_instance.orbit_radius_real, primary.mass_real)
#var stable_velocity = calculate_stable_orbit_velocity(body_instance.orbit_radius_real, primary.mass_real)
var initial_position_vector = Vector2(body_instance.orbit_radius_real, 0).rotated(randf() * TAU)
body_instance.global_position_real = primary.global_position_real + initial_position_vector
body_instance.global_position = body_instance.global_position_real / sim_scale
var body_velocity_vector = Vector2(0, stable_velocity).rotated(initial_position_vector.angle() + PI / 2)
body_instance.linear_velocity_real = body_instance.calculate_initial_orbit_real(primary, body_instance)
body_instance.global_position = primary.global_position_real + initial_position_vector
primary.add_child(body_instance)
print("Created " + body_instance.name + " with radius " + str(body_instance.orbit_radius_real) + " and mass " + str(body_instance.mass_real))
body_instance.linear_velocity = body_instance.calculate_initial_orbit_real(primary, body_instance)
print("Created " + body_instance.name + " with radius " + str(body_instance.orbit_radius_real) + " and mass " + str(body_instance.mass))
print("Initial orbital velocity is: " + str(body_instance.linear_velocity))
# Calculates the velocity required for a stable circular orbit.
func calculate_stable_orbit_velocity(orbit_radius: float, primary_mass: float) -> float:
return sqrt(G * primary_mass / orbit_radius)
#func calculate_stable_orbit_velocity(orbit_radius: float, primary_mass: float) -> float:
#return sqrt(G * primary_mass / orbit_radius)
# Recursively finds all celestial bodies in the scene.
func get_all_bodies() -> Array:
@ -236,6 +244,7 @@ class AsteroidBelt:
class SystemData:
var star : CelestialBody
var planets : Array[CelestialBody]
var moons: Array[CelestialBody]
var stations : Array[CelestialBody]
var belts : Array[AsteroidBelt]
@ -243,6 +252,8 @@ class SystemData:
var bodies : Array[CelestialBody] = [star]
bodies.append_array(planets)
bodies.append_array(stations)
bodies.append_array(moons)
var all_asteroids : Array[CelestialBody] = []
for belt in belts:

View File

@ -10,7 +10,7 @@ func get_class_name() -> String:
# 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
#mass = 0.001
radius = 15.0
# You can set a default texture here.