diff --git a/scripts/droplet.gd b/scripts/droplet.gd index 50d5286..447999c 100644 --- a/scripts/droplet.gd +++ b/scripts/droplet.gd @@ -2,11 +2,11 @@ class_name Droplet extends RigidBody2D # default mode: a bit sluggish, tendency to pile # bounce mode: doesn't settle down at all, but keeps flat surface -# bounce_wip: wonky AF, probably due to extra compute +# sinker: new droplet sinks, pile grows outward # stick mode: piles tightly, very calm # wip mode: interesting, the base stays together, and the new one jumps into place -enum Mode { DEFAULT, BOUNCE, BOUNCE_WIP, STICK, WIP } -const MODE: Mode = Mode.WIP +enum Mode { DEFAULT, BOUNCE, SINKER, RICE, WIP } +var MODE: Mode class DropletConfig: var bounce @@ -22,10 +22,10 @@ class DropletConfig: elif mode == Mode.BOUNCE: bounce = 0.5 friction = 0.1 - elif mode == Mode.BOUNCE_WIP: - bounce = 0.5 + elif mode == Mode.SINKER: + bounce = 0 friction = 0.1 - elif mode == Mode.STICK: + elif mode == Mode.RICE: bounce = 0.1 friction = 0.3 else: # WIP @@ -44,7 +44,7 @@ func _ready(): if not MODE == Mode.DEFAULT: contact_monitor = true max_contacts_reported = 10 - body_entered.connect(_on_body_entered) + # body_entered.connect(_on_body_entered) func _physics_process(delta): if MODE == Mode.WIP: @@ -59,7 +59,7 @@ func _physics_process(delta): func _integrate_forces(state): # this is probably overkill since we are overriding the default physics engine - if MODE == Mode.STICK: + if MODE == Mode.RICE: var v = state.linear_velocity var contacts = state.get_contact_count() for i in range(contacts): @@ -71,18 +71,14 @@ func _integrate_forces(state): 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_WIP: - # 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) + elif MODE == Mode.SINKER: + # only contribute to the target rigid bodies, let source droplet handle it's own bounce + var v = state.linear_velocity + for i in range(state.get_contact_count()): + var body = state.get_contact_collider_object(i) + var normal = state.get_contact_local_normal(i) + if body is RigidBody2D: + var impact_speed = v.dot(-normal) + if impact_speed > 0: + var boost = normal * impact_speed * 1 + body.apply_central_impulse(boost) diff --git a/scripts/model.gd b/scripts/model.gd index 6e1c380..02d0ee3 100644 --- a/scripts/model.gd +++ b/scripts/model.gd @@ -1,9 +1,14 @@ class_name Model extends Node2D -const PERIOD: int = 20 # smaller makes droplets faster var CURRENT_TIME: int = 0 var last_droplet: int = 0 + +# tuning knobs +const PERIOD: int = 10 # smaller makes droplets faster const DROP_PT_X = 450 +const DROP_PT_Y = 400 +const DROP_SIZE = 2 +const DROP_TYPE = Droplet.Mode.SINKER func _ready(): pass # Replace with function body. @@ -15,6 +20,7 @@ func _process(delta: float): # print("new droplet at time: ", str(CURRENT_TIME)) var droplet = preload("res://scenes/droplet.tscn").instantiate() var shape = droplet.get_node("CollisionShape2D") - shape.shape.radius = 5 - droplet.global_position = Vector2(DROP_PT_X, 100) + shape.shape.radius = DROP_SIZE + droplet.MODE = DROP_TYPE + droplet.global_position = Vector2(DROP_PT_X, DROP_PT_Y) add_child(droplet)