water-testing/scripts/droplet.gd

50 lines
1.7 KiB
GDScript

class_name Droplet extends RigidBody2D
# bounce mode seems to settle with a consistent surface, but is erratic
# stick mode seems to make sand castles, but is very calm
enum Mode { BOUNCE, STICK }
const mode: Mode = Mode.BOUNCE
func _ready():
var mat = PhysicsMaterial.new()
mat.bounce = .1 if mode == Mode.BOUNCE else 0
mat.friction = 0.0
physics_material_override = mat
# setup body entered signal, seems to also matter for STICK mode
contact_monitor = true
max_contacts_reported = 10
body_entered.connect(_on_body_entered)
func _physics_process(delta):
pass
func _integrate_forces(state):
if mode == Mode.STICK:
var v = state.linear_velocity
var contacts = state.get_contact_count()
for i in range(contacts):
var body = state.get_contact_collider_object(i)
var normal = state.get_contact_local_normal(i)
var self_damp = .9
var other_damp = 1 - self_damp
v = v.bounce(normal) * self_damp
state.linear_velocity = v # self bounce
if body is RigidBody2D: # other body
body.apply_central_impulse(normal * v.length() * (other_damp/contacts))
func _on_body_entered(body):
if mode == Mode.BOUNCE:
# trying to elicit stronger response from rigidBody that was struck
# ends up being kind of erratic
# at damp_factor .75: settles laterally, but erratic past half-full
# at damp_factor of .5, it's pretty calm, but then can't overfill (expected?)
var vel = get_linear_velocity()
const damp_factor = 0.7
var normal = (body.global_position - global_position).normalized()
# reflect velocity across collision direction
var bounced = vel.bounce(normal) # reflection
set_linear_velocity(bounced * damp_factor)
if body is RigidBody2D:
body.apply_central_impulse(-bounced * damp_factor)