Skip to content

Commit 1c8799a

Browse files
committed
Add example for walking on ropes
1 parent 46a8615 commit 1c8799a

3 files changed

Lines changed: 155 additions & 4 deletions

File tree

demo/rope_examples/scripts/character_body_2d_platformer.gd

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ var _rope_interaction: RopeInteraction
1010

1111

1212
func _ready() -> void:
13-
_rope_interaction = get_node_or_null("RopeInteraction")
13+
_rope_interaction = $RopeInteraction
1414

15-
var area: Area2D = get_node_or_null("Area2D")
16-
if area:
17-
area.area_entered.connect(_rope_area_entered)
15+
var area: Area2D = $Area2D
16+
area.area_entered.connect(_rope_area_entered)
1817

1918

2019
func _physics_process(delta: float) -> void:
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
extends CharacterBody2D
2+
3+
@export var speed: float = 300.0
4+
@export var jump_speed: float = 500.0
5+
@export var gravity: float = 1200.0
6+
7+
@onready var _rope_handle: RopeHandle = $RopeHandle
8+
9+
10+
func _ready() -> void:
11+
var area: Area2D = $Area2D
12+
area.body_entered.connect(_rope_entered)
13+
14+
# Reset the rope into east direction so there is less erratic movement until it reaches its resting position.
15+
# In an actual game this would obviously not be handled by the player code.
16+
var rope: Rope = $"%Rope"
17+
rope.reset(Vector2.RIGHT)
18+
19+
20+
func _physics_process(delta: float) -> void:
21+
var hdir := 0
22+
var grounded: bool = is_on_floor()
23+
var move_speed := speed
24+
var on_rope := _rope_handle.enable
25+
26+
if Input.is_key_pressed(KEY_A):
27+
hdir -= 1
28+
if Input.is_key_pressed(KEY_D):
29+
hdir += 1
30+
31+
if grounded:
32+
velocity.y = 0
33+
34+
if Input.is_key_pressed(KEY_SPACE):
35+
velocity.y -= jump_speed
36+
_rope_handle.enable = false
37+
38+
velocity.x = hdir * move_speed
39+
velocity.y += gravity * delta
40+
41+
move_and_slide()
42+
43+
if on_rope:
44+
_rope_handle.use_nearest_position()
45+
46+
47+
func _rope_entered(node: Node) -> void:
48+
# The rope area will have a collision generator which we use to get the actual rope node
49+
var shape_generator := node.get_node("RopeCollisionShapeGenerator") as RopeCollisionShapeGenerator
50+
if shape_generator:
51+
_rope_handle.rope_path = shape_generator.rope_path
52+
_rope_handle.enable = true
53+
_rope_handle.use_nearest_position()
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
[gd_scene load_steps=8 format=3 uid="uid://dosr2p68fwd6p"]
2+
3+
[ext_resource type="Script" path="res://addons/ropesim/Rope.gd" id="1_le2ut"]
4+
[ext_resource type="Script" path="res://addons/ropesim/RopeHandle.gd" id="2_0q18d"]
5+
[ext_resource type="Script" path="res://addons/ropesim/RopeCollisionShapeGenerator.gd" id="3_4yuxp"]
6+
[ext_resource type="Script" path="res://rope_examples/scripts/character_body_2d_platformer_walk_on_rope.gd" id="4_x28hd"]
7+
[ext_resource type="Texture2D" uid="uid://criwv6nuivcxy" path="res://rope_examples/icon.svg" id="5_mv4mo"]
8+
9+
[sub_resource type="RectangleShape2D" id="RectangleShape2D_fetoc"]
10+
size = Vector2(64, 64)
11+
12+
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vjdut"]
13+
size = Vector2(64, 12)
14+
15+
[node name="Node2D" type="Node2D"]
16+
17+
[node name="Label" type="Label" parent="."]
18+
offset_left = 10.0
19+
offset_top = 10.0
20+
offset_right = 104.0
21+
offset_bottom = 59.0
22+
text = "A/D: Walk
23+
Space: Jump"
24+
25+
[node name="Label2" type="Label" parent="."]
26+
offset_left = 16.0
27+
offset_top = 562.0
28+
offset_right = 1146.0
29+
offset_bottom = 689.0
30+
text = "There is no real mutual physics interaction going on. The player CharacterBody just collides with the rope CharacterBody.
31+
To bulge the rope at the player's position, a RopeHandle is used.
32+
The further down the handle is positioned, the further the rope will bend."
33+
autowrap_mode = 2
34+
35+
[node name="Label3" type="Label" parent="."]
36+
offset_left = 467.0
37+
offset_top = 14.0
38+
offset_right = 1142.0
39+
offset_bottom = 63.0
40+
text = "Demonstrates a simple setup to let a player walk on a rope while deforming the rope.
41+
For an actual game, it still needs some fine-tuning."
42+
autowrap_mode = 2
43+
44+
[node name="Rope" type="Node2D" parent="."]
45+
unique_name_in_owner = true
46+
position = Vector2(4, 333)
47+
script = ExtResource("1_le2ut")
48+
num_segments = 40
49+
rope_length = 900.0
50+
num_constraint_iterations = 20
51+
line_width = 6.0
52+
color = Color(0.533333, 0.384314, 0.258824, 1)
53+
54+
[node name="RopeHandle" type="Marker2D" parent="Rope"]
55+
position = Vector2(1149, -7)
56+
script = ExtResource("2_0q18d")
57+
rope_path = NodePath("..")
58+
strength = 1.0
59+
60+
[node name="CharacterBody2D" type="CharacterBody2D" parent="."]
61+
position = Vector2(112, 128)
62+
collision_layer = 3
63+
64+
[node name="RopeCollisionShapeGenerator" type="Node" parent="CharacterBody2D"]
65+
script = ExtResource("3_4yuxp")
66+
rope_path = NodePath("../../Rope")
67+
68+
[node name="PlayerA" type="CharacterBody2D" parent="."]
69+
process_physics_priority = -100
70+
position = Vector2(157, 156)
71+
collision_layer = 0
72+
script = ExtResource("4_x28hd")
73+
metadata/_edit_group_ = true
74+
75+
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerA"]
76+
position = Vector2(0, -32)
77+
shape = SubResource("RectangleShape2D_fetoc")
78+
79+
[node name="Icon" type="Sprite2D" parent="PlayerA"]
80+
position = Vector2(0, -32)
81+
scale = Vector2(0.5, 0.5)
82+
texture = ExtResource("5_mv4mo")
83+
84+
[node name="Area2D" type="Area2D" parent="PlayerA"]
85+
position = Vector2(0, -32)
86+
collision_layer = 0
87+
collision_mask = 2
88+
monitorable = false
89+
90+
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerA/Area2D"]
91+
position = Vector2(0, 28)
92+
shape = SubResource("RectangleShape2D_vjdut")
93+
94+
[node name="RopeHandle" type="Marker2D" parent="PlayerA"]
95+
position = Vector2(0, 23)
96+
script = ExtResource("2_0q18d")
97+
enable = false
98+
rope_position = 0.55
99+
precise = true

0 commit comments

Comments
 (0)