Orbit and spin
Three nested Node2D and two rotations. The child orbits because the parent turns, and the grandchild orbits the child.
The editor above is running this project. Change a line and it reloads.
Godot classes used
Node2DLine2DPolygon2D
The code
scripts/main.gd
extends Node
const HUB_SPEED: float = 0.35
const PLANET_SPEED: float = 1.5
const ORBIT_RADIUS: float = 220.0
const MOON_RADIUS: float = 78.0
var hub: Node2D
var planet: Node2D
func _ready() -> void:
_add_background()
var view: Vector2 = get_viewport().get_visible_rect().size
hub = Node2D.new()
hub.position = view * 0.5
hub.add_child(_make_ring(ORBIT_RADIUS))
hub.add_child(_make_rect(Vector2(ORBIT_RADIUS, 8), Color('#2a2f3d'), Vector2(ORBIT_RADIUS * 0.5, 0)))
hub.add_child(_make_circle(40.0, Color('#f3d48d')))
add_child(hub)
planet = Node2D.new()
planet.position = Vector2(ORBIT_RADIUS, 0)
planet.add_child(_make_ring(MOON_RADIUS))
planet.add_child(_make_rect(Vector2(MOON_RADIUS, 6), Color('#2a2f3d'), Vector2(MOON_RADIUS * 0.5, 0)))
planet.add_child(_make_circle(26.0, Color('#8da5f3')))
hub.add_child(planet)
var moon: Node2D = Node2D.new()
moon.position = Vector2(MOON_RADIUS, 0)
moon.add_child(_make_circle(12.0, Color('#8eef97')))
planet.add_child(moon)
_add_label('the hub spins, the planet rides that rotation, the moon rides the planet', Vector2(40, 40))
func _process(delta: float) -> void:
hub.rotation += HUB_SPEED * delta
planet.rotation += PLANET_SPEED * delta
func _make_ring(radius: float) -> Line2D:
var ring: Line2D = Line2D.new()
ring.width = 2.0
ring.default_color = Color('#2a2f3d')
for i in 49:
ring.add_point(Vector2(cos(TAU * i / 48.0), sin(TAU * i / 48.0)) * radius)
return ring
func _make_rect(size: Vector2, color: Color, at: Vector2) -> Polygon2D:
var rect: Polygon2D = Polygon2D.new()
rect.polygon = PackedVector2Array([-size * 0.5, Vector2(size.x, -size.y) * 0.5, size * 0.5, Vector2(-size.x, size.y) * 0.5])
rect.color = color
rect.position = at
return rect
func _make_circle(radius: float, color: Color) -> Polygon2D:
var points: PackedVector2Array = PackedVector2Array()
for i in 28:
points.append(Vector2(cos(TAU * i / 28.0), sin(TAU * i / 28.0)) * radius)
var circle: Polygon2D = Polygon2D.new()
circle.polygon = points
circle.color = color
return circle
func _add_label(text: String, at: Vector2) -> void:
var label: Label = Label.new()
label.text = text
label.position = at
label.add_theme_color_override('font_color', Color('#999999'))
label.add_theme_font_size_override('font_size', 20)
add_child(label)
func _add_background() -> void:
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
add_child(background)
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)