弹簧关节
三根静止长度相同、刚度和阻尼各异的弹簧并排放置。
上方的编辑器正在运行这个项目。改一行代码,它就会重新加载。
用到的 Godot 类
DampedSpringJoint2DRigidBody2DLine2D
代码
scripts/main.gd
extends Node
const REST_LENGTH: float = 180.0
const BOB_RADIUS: float = 40.0
const SPRINGS: Array = [
{stiffness = 4.0, damping = 0.2, color = '#8da5f3'},
{stiffness = 14.0, damping = 0.6, color = '#8eef97'},
{stiffness = 40.0, damping = 2.0, color = '#fc7f7f'},
]
var bobs: Array[RigidBody2D] = []
var anchors: Array[Vector2] = []
var cords: Array[Line2D] = []
func _ready() -> void:
_add_background()
var view: Vector2 = get_viewport().get_visible_rect().size
for i in SPRINGS.size():
var top: Vector2 = Vector2(view.x * (i + 1) / (SPRINGS.size() + 1), view.y * 0.2)
var anchor: StaticBody2D = StaticBody2D.new()
anchor.position = top
anchor.add_child(_make_rect(Vector2(70, 16), Color('#2a2f3d')))
add_child(anchor)
var bob: RigidBody2D = _add_bob(top + Vector2(0, REST_LENGTH + 120), Color(SPRINGS[i].color))
var spring: DampedSpringJoint2D = DampedSpringJoint2D.new()
spring.position = top
spring.length = REST_LENGTH * 2.0
spring.rest_length = REST_LENGTH
spring.stiffness = SPRINGS[i].stiffness
spring.damping = SPRINGS[i].damping
add_child(spring)
spring.node_a = anchor.get_path()
spring.node_b = bob.get_path()
var cord: Line2D = Line2D.new()
cord.width = 3.0
cord.default_color = Color('#2a2f3d')
cord.points = PackedVector2Array([top, bob.position])
add_child(cord)
bobs.append(bob)
anchors.append(top)
cords.append(cord)
print('same rest length, three stiffness and damping pairs')
func _process(_delta: float) -> void:
for i in bobs.size():
cords[i].points = PackedVector2Array([anchors[i], bobs[i].position])
func _add_bob(at: Vector2, color: Color) -> RigidBody2D:
var circle: CircleShape2D = CircleShape2D.new()
circle.radius = BOB_RADIUS
var collision: CollisionShape2D = CollisionShape2D.new()
collision.shape = circle
var bob: RigidBody2D = RigidBody2D.new()
bob.position = at
bob.add_child(_make_circle(BOB_RADIUS, color))
bob.add_child(collision)
add_child(bob)
return bob
func _make_rect(size: Vector2, color: Color) -> 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
return rect
func _make_circle(radius: float, color: Color) -> Polygon2D:
var points: PackedVector2Array = PackedVector2Array()
for i in 24:
points.append(Vector2(cos(TAU * i / 24.0), sin(TAU * i / 24.0)) * radius)
var circle: Polygon2D = Polygon2D.new()
circle.polygon = points
circle.color = color
return circle
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)