Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extends Node2D
- @export var simulation_speed: float = 1.0
- @export var orbit_scale: float = 150.0
- @export_enum("Figure-8", "Lagrange Triangle", "Butterfly") var orbit_pattern: int = 0
- @export var trail_length: int = 75
- @export var trail_width: float = 6.0
- @export var glow_intensity: float = 2.5
- var bodies: Array = []
- var body_visuals: Array = []
- var time: float = 0.0
- var center: Vector2
- class Body:
- var angle: float
- var orbit_radius: float
- var orbit_speed: float
- var phase: float
- var color: Color
- var trail_points: Array = []
- func _init(a: float, r: float, s: float, p: float, c: Color):
- angle = a
- orbit_radius = r
- orbit_speed = s
- phase = p
- color = c
- func _ready():
- center = get_viewport_rect().size / 2.0
- setup_orbital_system()
- await get_tree().process_frame
- create_visual_effects()
- func setup_orbital_system():
- bodies.clear()
- match orbit_pattern:
- 0:
- bodies.append(Body.new(
- 0.0, orbit_scale * 0.8, 1.2, 0.0,
- Color(1.0, 0.5, 0.2, 1.0)
- ))
- bodies.append(Body.new(
- TAU * 0.33, orbit_scale * 0.8, 1.2, TAU * 0.33,
- Color(0.2, 0.7, 1.0, 1.0)
- ))
- bodies.append(Body.new(
- TAU * 0.66, orbit_scale * 0.8, 1.2, TAU * 0.66,
- Color(1.0, 1.0, 0.3, 1.0)
- ))
- 1:
- for i in range(3):
- var angle = (i * TAU / 3.0)
- bodies.append(Body.new(
- angle, orbit_scale, 1.0, 0.0,
- [Color(1.0, 0.3, 0.3), Color(0.3, 1.0, 0.5), Color(0.5, 0.5, 1.0)][i]
- ))
- 2:
- bodies.append(Body.new(
- 0.0, orbit_scale * 0.6, 1.5, 0.0,
- Color(1.0, 0.2, 0.6, 1.0)
- ))
- bodies.append(Body.new(
- PI, orbit_scale * 0.6, 1.5, PI,
- Color(0.2, 1.0, 0.8, 1.0)
- ))
- bodies.append(Body.new(
- PI * 0.5, orbit_scale * 1.0, 0.8, 0.0,
- Color(0.8, 0.8, 1.0, 1.0)
- ))
- func create_visual_effects():
- for i in range(bodies.size()):
- var body = bodies[i]
- var container = Node2D.new()
- container.name = "Body" + str(i)
- add_child(container)
- var light = PointLight2D.new()
- light.enabled = true
- light.color = body.color
- light.energy = glow_intensity
- light.texture_scale = 1.0
- light.blend_mode = Light2D.BLEND_MODE_ADD
- container.add_child(light)
- var particles = CPUParticles2D.new()
- particles.emitting = true
- particles.amount = 100
- particles.lifetime = 0.8
- particles.local_coords = false
- particles.emission_shape = CPUParticles2D.EMISSION_SHAPE_SPHERE
- particles.emission_sphere_radius = 5.0
- particles.gravity = Vector2.ZERO
- particles.initial_velocity_min = 3.0
- particles.initial_velocity_max = 10.0
- particles.linear_accel_min = -15.0
- particles.linear_accel_max = -20.0
- particles.damping_min = 10.0
- particles.damping_max = 15.0
- particles.scale_amount_min = 2.0
- particles.scale_amount_max = 4.0
- particles.color = body.color
- container.add_child(particles)
- var trail_line = Line2D.new()
- trail_line.width = trail_width
- trail_line.default_color = body.color
- trail_line.joint_mode = Line2D.LINE_JOINT_ROUND
- trail_line.begin_cap_mode = Line2D.LINE_CAP_ROUND
- trail_line.end_cap_mode = Line2D.LINE_CAP_ROUND
- trail_line.antialiased = true
- add_child(trail_line)
- var glow_line = Line2D.new()
- glow_line.width = trail_width * 2.5
- var glow_color = body.color
- glow_color.a = 0.3
- glow_line.default_color = glow_color
- glow_line.joint_mode = Line2D.LINE_JOINT_ROUND
- glow_line.begin_cap_mode = Line2D.LINE_CAP_ROUND
- glow_line.end_cap_mode = Line2D.LINE_CAP_ROUND
- glow_line.antialiased = true
- add_child(glow_line)
- body_visuals.append({
- "container": container,
- "light": light,
- "particles": particles,
- "trail_line": trail_line,
- "glow_line": glow_line
- })
- func _process(delta):
- time += delta * simulation_speed
- update_bodies()
- update_visuals()
- func update_bodies():
- for i in range(bodies.size()):
- var body = bodies[i]
- body.angle += body.orbit_speed * 0.02
- var x_offset = cos(body.angle + body.phase) * body.orbit_radius
- var y_offset = sin(body.angle + body.phase) * body.orbit_radius * 0.85
- if orbit_pattern == 0:
- var figure8_offset = sin(body.angle * 2.0) * orbit_scale * 0.3
- x_offset += figure8_offset
- var position = center + Vector2(x_offset, y_offset)
- body.trail_points.push_front(position)
- if body.trail_points.size() > trail_length:
- body.trail_points.resize(trail_length)
- func update_visuals():
- for i in range(bodies.size()):
- var body = bodies[i]
- var visuals = body_visuals[i]
- if body.trail_points.is_empty():
- continue
- var pos = body.trail_points[0]
- visuals["container"].global_position = pos
- var pulse = 1.0 + sin(time * 3.0 + i * TAU / 3.0) * 0.2
- visuals["light"].energy = glow_intensity * pulse
- var trail_line = visuals["trail_line"]
- trail_line.clear_points()
- var num_points = min(body.trail_points.size(), trail_length)
- for j in range(num_points):
- trail_line.add_point(body.trail_points[j])
- var glow_line = visuals["glow_line"]
- glow_line.clear_points()
- for j in range(0, num_points, 3):
- glow_line.add_point(body.trail_points[j])
- func reset_simulation():
- for body in bodies:
- body.trail_points.clear()
- body.angle = randf() * TAU
- time = 0.0
- func change_pattern(pattern_index: int):
- orbit_pattern = pattern_index
- for visual in body_visuals:
- visual["container"].queue_free()
- visual["trail_line"].queue_free()
- visual["glow_line"].queue_free()
- body_visuals.clear()
- bodies.clear()
- setup_orbital_system()
- await get_tree().process_frame
- create_visual_effects()
Advertisement
Add Comment
Please, Sign In to add comment