aboutsummaryrefslogtreecommitdiff
path: root/src/rope.odin
diff options
context:
space:
mode:
authoriamcheeseman <[hidden email]>2026-01-17 18:19:57 -0500
committeriamcheeseman <[hidden email]>2026-01-17 18:19:57 -0500
commitdb10e319cc2201924815b2d8c9a4c2d21c2bfbb6 (patch)
tree17c7d1b0e485dc07161cbdca80ae2239fd6146c5 /src/rope.odin
parenteee06361048e34f6ca21348e8776636da95ef3f8 (diff)
Verlet ropes :)
Diffstat (limited to 'src/rope.odin')
-rw-r--r--src/rope.odin81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/rope.odin b/src/rope.odin
new file mode 100644
index 0000000..c6ade8d
--- /dev/null
+++ b/src/rope.odin
@@ -0,0 +1,81 @@
+package demonchime
+
+import "core:log"
+import "core:math"
+
+import rl "vendor:raylib"
+
+Rope :: struct {
+ handle: Entity_Handle,
+ hanging_id: Image_Id,
+ verlet: Verlet_Rope,
+}
+
+step_ropes :: proc(dt: f32) {
+ iter := iter_entity_list(state.rope_list)
+ for rope in entity_list_iter(&iter) {
+ update_verlet_rope(&rope.verlet)
+ }
+}
+
+draw_ropes :: proc() {
+ iter := iter_entity_list(state.rope_list)
+ for rope in entity_list_iter(&iter) {
+ for i in 0..<len(rope.verlet.nodes) - 1 {
+ cur := rope.verlet.nodes[i]
+ nex := rope.verlet.nodes[i + 1]
+ rl.DrawLineV(cur.pos, nex.pos, rl.WHITE)
+ }
+
+ a := rope.verlet.nodes[len(rope.verlet.nodes) - 1]
+ b := rope.verlet.nodes[len(rope.verlet.nodes) - 2]
+
+ dir := b.pos - a.pos
+ rotation := math.atan2(dir.y, dir.x) * math.DEG_PER_RAD + 90
+
+ img := get_image(rope.hanging_id)
+ draw_texture(
+ img,
+ a.pos,
+ offset = Vec2{f32(img.width) * 0.5, 0},
+ rotation = rotation,
+ )
+ }
+}
+
+clear_ropes :: proc() {
+ iter := iter_entity_list(state.rope_list)
+ for rope in entity_list_iter(&iter) {
+ delete(rope.verlet.nodes)
+ delete_entity(&state.rope_list, rope.handle)
+ }
+}
+
+on_room_open_rope :: proc(room_id: Room_Id) {
+ clear_ropes()
+}
+
+object_spawner_rope :: proc(obj: Object_Resource) {
+ image_id, is_image_id := convert_path_to_resource(obj, "image").(Image_Id)
+ if !is_image_id {
+ image_id = .Small_Lamp
+ }
+ node_length := obj.properties["node_length"].(i32)
+ length := obj.properties["length"].(i32)
+
+ nodes := make([]Verlet_Node, length)
+ for &node, i in nodes {
+ node = create_verlet_node(
+ obj.pos + Vec2{0, f32(i) * f32(node_length)},
+ i == 0,
+ )
+ }
+
+ make_entity(&state.rope_list, Rope{
+ hanging_id = image_id,
+ verlet = Verlet_Rope{
+ nodes = nodes,
+ node_length = f32(node_length),
+ },
+ })
+}