Box pile

Sixteen boxes dropped between two walls. The first thing to try when you want to see the solver work.

The editor above is running this project. Change a line and it reloads.

Godot classes used

RigidBody2DCollisionShape2DRectangleShape2D

The code

scripts/main.gd
extends Node

const BOX_SIZE: Vector2 = Vector2(54, 54)
const BOX_COUNT: int = 16
const WALL: float = 40.0


func _ready() -> void:
	_add_background()

	var view: Vector2 = get_viewport().get_visible_rect().size

	_add_static(Vector2(view.x * 0.5, view.y - 30), Vector2(view.x, 60))
	_add_static(Vector2(view.x * 0.5 - 240, view.y * 0.5), Vector2(WALL, view.y))
	_add_static(Vector2(view.x * 0.5 + 240, view.y * 0.5), Vector2(WALL, view.y))

	for i in BOX_COUNT:
		_add_box(Vector2(view.x * 0.5 + randf_range(-70, 70), view.y * 0.45 - i * 62))


func _add_box(at: Vector2) -> void:
	var shape: RectangleShape2D = RectangleShape2D.new()
	shape.size = BOX_SIZE

	var collision: CollisionShape2D = CollisionShape2D.new()
	collision.shape = shape

	var box: RigidBody2D = RigidBody2D.new()
	box.position = at
	box.rotation = randf_range(-0.3, 0.3)
	box.add_child(_make_rect(BOX_SIZE, Color.from_hsv(randf(), 0.4, 0.9)))
	box.add_child(collision)
	add_child(box)


func _add_static(center: Vector2, size: Vector2) -> void:
	var shape: RectangleShape2D = RectangleShape2D.new()
	shape.size = size

	var collision: CollisionShape2D = CollisionShape2D.new()
	collision.shape = shape

	var body: StaticBody2D = StaticBody2D.new()
	body.position = center
	body.add_child(_make_rect(size, Color('#2a2f3d')))
	body.add_child(collision)
	add_child(body)


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 _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)

More Physics examples