Implementing explosion physics

Godot Version

4.5

Question

I’m trying to make an object that explodes into shards upon touching the floor, and the shards fly up and then down in an arc. The part where the object breaks down into shards is working fine, but I’m struggling with writing the code for the physics of the shards. Here’s what I have:

var moving : bool = false

var acceleration = Vector2.ZERO
var speed : int = 100
var velocity = Vector2.ZERO

var fall : bool = false

func _ready():	
	acceleration = Vector2(randi_range(-100, 100), randi_range(-300, -100))

func _physics_process(delta: float) -> void:
	if moving:
		if velocity.length() >= speed:
			fall = true
		
		if fall:
			velocity.y -= acceleration.y * delta
			velocity.x += acceleration.x * delta
		else:
			velocity += acceleration * delta
		rotation = velocity.angle()
		position += velocity * delta

The shards do fly up and then down in an arc, but it doesn’t look organic at all. What should I change in thee code to make it better?

My quickest answer would be to use more organic interpolation methods like smoothstep(), since linear interpolation by itself usually always looks unnatural. This video is a nice one about smoothing out interpolations to make them look better

1 Like

Alright, I changed the code a bit.

func _physics_process(delta: float) -> void:
	if moving:
		if velocity.length() >= speed:
			fall = true
		
		if fall:
			velocity.y += smoothstep(0, 1, acceleration.y * delta)
			if acceleration.x < 0:
				velocity.x -= smoothstep(0, 1, -acceleration.x * delta)
			else:
				velocity.x += smoothstep(0, 1, acceleration.x * delta)
		else:
			if acceleration.x < 0:
				velocity.x -= smoothstep(0, 1, -acceleration.x * delta)
			else:
				velocity.x += smoothstep(0, 1, acceleration.x * delta)
			velocity.y -= smoothstep(0, 1, acceleration.y * delta)
		rotation = lerp_angle(rotation, velocity.angle(), 0.01)
		position += velocity * delta

But I’m not really sure how to speed the movement up, or make it so it’s fast at the beginning and slows down at the apex (currently it’s slow at the beginning and then gradually speeds up). I’m kind of new to this physics bit of programming, so I would appreciate some help!

Alright, by using ease instead of smoothstep I got the result I wanted. Thanks!

func _physics_process(delta: float) -> void:
	if moving:
		if velocity.length() >= speed:
			fall = true
		
		if fall:
			velocity.y += ease(acceleration.y * delta, 0.2)
			if acceleration.x < 0:
				velocity.x -= ease(-acceleration.x * delta, 0.2)
			else:
				velocity.x += ease(acceleration.x * delta, 0.2)
		else:
			if acceleration.x < 0:
				velocity.x -= ease(-acceleration.x * 100 * delta, 4.8)
			else:
				velocity.x += ease(acceleration.x * 100 * delta, 4.8)
			velocity.y -= ease(acceleration.y * delta * 100, 4.8)
		rotation = lerp_angle(rotation, velocity.angle(), 0.01)
		position += velocity
1 Like