refactored droplet mode-ing

This commit is contained in:
Ed Guloien 2026-05-03 00:34:46 -04:00
parent 536b212426
commit f00568c781
3 changed files with 61 additions and 21 deletions

View File

@ -93,11 +93,11 @@ shape = SubResource("RectangleShape2D_jsxgm")
debug_color = Color(0.5959702, 0.54461277, 0.08352526, 0.41960785) debug_color = Color(0.5959702, 0.54461277, 0.08352526, 0.41960785)
[node name="big_bucket" type="Node2D" parent="." unique_id=1340688088] [node name="big_bucket" type="Node2D" parent="." unique_id=1340688088]
position = Vector2(-115, 91) position = Vector2(360, 460)
metadata/_edit_group_ = true metadata/_edit_group_ = true
[node name="platform4" type="StaticBody2D" parent="big_bucket" unique_id=1712494835] [node name="platform4" type="StaticBody2D" parent="big_bucket" unique_id=1712494835]
position = Vector2(450.99997, 440) position = Vector2(11, 74)
rotation = 1.5717075 rotation = 1.5717075
metadata/_edit_group_ = true metadata/_edit_group_ = true
@ -107,7 +107,7 @@ shape = SubResource("RectangleShape2D_jsxgm")
debug_color = Color(0.5959702, 0.54461277, 0.08352526, 0.41960785) debug_color = Color(0.5959702, 0.54461277, 0.08352526, 0.41960785)
[node name="platform5" type="StaticBody2D" parent="big_bucket" unique_id=1995856626] [node name="platform5" type="StaticBody2D" parent="big_bucket" unique_id=1995856626]
position = Vector2(512, 498.99997) position = Vector2(72.00003, 132.99997)
rotation = 0.0012022424 rotation = 0.0012022424
metadata/_edit_group_ = true metadata/_edit_group_ = true
@ -117,7 +117,7 @@ shape = SubResource("RectangleShape2D_jsxgm")
debug_color = Color(0.5959702, 0.54461277, 0.08352526, 0.41960785) debug_color = Color(0.5959702, 0.54461277, 0.08352526, 0.41960785)
[node name="platform7" type="StaticBody2D" parent="big_bucket" unique_id=146253526] [node name="platform7" type="StaticBody2D" parent="big_bucket" unique_id=146253526]
position = Vector2(650, 498.99997) position = Vector2(210.00003, 132.99997)
rotation = 0.00064454623 rotation = 0.00064454623
metadata/_edit_group_ = true metadata/_edit_group_ = true
@ -127,7 +127,7 @@ shape = SubResource("RectangleShape2D_jsxgm")
debug_color = Color(0.5959702, 0.54461277, 0.08352526, 0.41960785) debug_color = Color(0.5959702, 0.54461277, 0.08352526, 0.41960785)
[node name="platform6" type="StaticBody2D" parent="big_bucket" unique_id=749418854] [node name="platform6" type="StaticBody2D" parent="big_bucket" unique_id=749418854]
position = Vector2(710.00006, 437.00003) position = Vector2(270.0001, 71.00003)
rotation = -1.5774848 rotation = -1.5774848
metadata/_edit_group_ = true metadata/_edit_group_ = true

View File

@ -1,26 +1,65 @@
class_name Droplet extends RigidBody2D class_name Droplet extends RigidBody2D
# bounce mode seems to settle with a consistent surface, but is erratic # default mode: a bit sluggish, tendency to pile
# stick mode seems to make sand castles, but is very calm # bounce mode: doesn't settle down at all, but keeps flat surface
enum Mode { BOUNCE, STICK } # bounce_wip: wonky AF, probably due to extra compute
const mode: Mode = Mode.BOUNCE # 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
class DropletConfig:
var bounce
var friction
var linear_damp
var angular_damp
func _init(mode):
linear_damp = ProjectSettings.get_setting("physics/2d/default_linear_damp")
angular_damp = ProjectSettings.get_setting("physics/2d/default_angular_damp")
if mode == Mode.DEFAULT:
bounce = 0
friction = 0.1
elif mode == Mode.BOUNCE:
bounce = 0.5
friction = 0.1
elif mode == Mode.BOUNCE_WIP:
bounce = 0.5
friction = 0.1
elif mode == Mode.STICK:
bounce = 0.1
friction = 0.3
else: # WIP
bounce = 0.1
friction = 1
func _ready(): func _ready():
var config = DropletConfig.new(MODE)
var mat = PhysicsMaterial.new() var mat = PhysicsMaterial.new()
mat.bounce = .1 if mode == Mode.BOUNCE else 0 mat.bounce = config.bounce
mat.friction = 0.0 mat.friction = config.friction
physics_material_override = mat physics_material_override = mat
linear_damp = config.linear_damp
angular_damp = config.angular_damp
# setup body entered signal, seems to also matter for STICK mode # setup body entered signal, seems to also matter for STICK mode
contact_monitor = true if not MODE == Mode.DEFAULT:
max_contacts_reported = 10 contact_monitor = true
body_entered.connect(_on_body_entered) max_contacts_reported = 10
body_entered.connect(_on_body_entered)
func _physics_process(delta): func _physics_process(delta):
pass if MODE == Mode.WIP:
for body in get_colliding_bodies():
if body is RigidBody2D:
var dir = global_position - body.global_position
var dist = dir.length()
if dist < 64:
## IIUC: should act to keep close droplets together
var force = -dir.normalized() * (1.0 - dist / 64.0)
body.apply_central_force(force * 100)
func _integrate_forces(state): func _integrate_forces(state):
if mode == Mode.STICK: # this is probably overkill since we are overriding the default physics engine
if MODE == Mode.STICK:
var v = state.linear_velocity var v = state.linear_velocity
var contacts = state.get_contact_count() var contacts = state.get_contact_count()
for i in range(contacts): for i in range(contacts):
@ -34,7 +73,7 @@ func _integrate_forces(state):
body.apply_central_impulse(normal * v.length() * (other_damp/contacts)) body.apply_central_impulse(normal * v.length() * (other_damp/contacts))
func _on_body_entered(body): func _on_body_entered(body):
if mode == Mode.BOUNCE: if MODE == Mode.BOUNCE_WIP:
# trying to elicit stronger response from rigidBody that was struck # trying to elicit stronger response from rigidBody that was struck
# ends up being kind of erratic # ends up being kind of erratic
# at damp_factor .75: settles laterally, but erratic past half-full # at damp_factor .75: settles laterally, but erratic past half-full

View File

@ -3,17 +3,18 @@ class_name Model extends Node2D
const PERIOD: int = 20 # smaller makes droplets faster const PERIOD: int = 20 # smaller makes droplets faster
var CURRENT_TIME: int = 0 var CURRENT_TIME: int = 0
var last_droplet: int = 0 var last_droplet: int = 0
const DROP_PT_X = 450
func _ready(): func _ready():
pass # Replace with function body. pass # Replace with function body.
func _process(delta: float): func _process(delta: float):
CURRENT_TIME += delta * 100 CURRENT_TIME += delta * 100
if CURRENT_TIME - last_droplet > PERIOD: if CURRENT_TIME - last_droplet > PERIOD:
last_droplet = CURRENT_TIME last_droplet = CURRENT_TIME
# print("new droplet at time: ", str(CURRENT_TIME)) # print("new droplet at time: ", str(CURRENT_TIME))
var droplet = preload("res://scenes/droplet.tscn").instantiate() var droplet = preload("res://scenes/droplet.tscn").instantiate()
var shape = droplet.get_node("CollisionShape2D") var shape = droplet.get_node("CollisionShape2D")
shape.shape.radius = 5 shape.shape.radius = 5
droplet.global_position = Vector2(450, 100) droplet.global_position = Vector2(DROP_PT_X, 100)
add_child(droplet) add_child(droplet)