From 76e69e6a6b25307a437a576efa4842938becef3a Mon Sep 17 00:00:00 2001 From: Antonio Dell'Annunziata Date: Mon, 24 Feb 2025 22:03:56 +0100 Subject: [PATCH] Add operation sequences --- cut_sequence.gd | 50 ++++++++ cut_sequence_point.gd | 20 +++ cut_sequence_point.tscn | 20 +++ feedback_canvas_modulate.gd | 1 - guideline_point.gd | 18 --- guidelines.gd | 13 -- operation.gd | 42 ++++++ project.godot | 6 + prototype_dark_cut.tscn | 249 ++++++++++-------------------------- test_body_2.png | Bin 0 -> 17240 bytes test_body_2.png.import | 34 +++++ test_scalpel.gd | 11 +- 12 files changed, 248 insertions(+), 216 deletions(-) create mode 100644 cut_sequence.gd create mode 100644 cut_sequence_point.gd create mode 100644 cut_sequence_point.tscn delete mode 100644 guideline_point.gd delete mode 100644 guidelines.gd create mode 100644 operation.gd create mode 100644 test_body_2.png create mode 100644 test_body_2.png.import diff --git a/cut_sequence.gd b/cut_sequence.gd new file mode 100644 index 0000000..f5cb364 --- /dev/null +++ b/cut_sequence.gd @@ -0,0 +1,50 @@ +class_name CutSequence +extends Node2D + +signal sequence_failed +signal sequence_succeeded + +var cut_sequence_points: Array[CutSequencePoint] = [] +func _ready(): + _build_sequence() + + +func _build_sequence(): + for c in get_children(): + if c is CutSequencePoint: + c.point_cut.connect(_trigger_point_cut.bind(c)) + cut_sequence_points.push_back(c) + + +var cut_indices: Array[int] = [] +func _trigger_point_cut(point: CutSequencePoint): + var cut_index = cut_sequence_points.find(point) + var is_cut_valid = false + if cut_indices.is_empty(): + is_cut_valid = cut_index == 0 or cut_index == cut_sequence_points.size() - 1 + if not is_cut_valid: + print("Failed cut: Expected %i or %i as first point, but got %i." % [0, cut_sequence_points.size() - 1, cut_index]) + else: + var direction = -1 if cut_indices[0] == 0 else 1 + is_cut_valid = cut_index + direction == cut_indices[-1] # Expect the next index + if not is_cut_valid: + print("Failed cut: Expected %i as next point, but got %i." % [cut_indices[-1] - direction, cut_index]) + + if not is_cut_valid: + _fail_sequence() + return + + point.confirm_cut() + cut_indices.push_back(cut_index) + if cut_indices.size() == cut_sequence_points.size(): + _succeed_sequence() + +func _fail_sequence(): + print("Fail cut sequence") + for i in cut_indices: + cut_sequence_points[i].reset_cut() + cut_indices.clear() + sequence_failed.emit() + +func _succeed_sequence(): + sequence_succeeded.emit() diff --git a/cut_sequence_point.gd b/cut_sequence_point.gd new file mode 100644 index 0000000..f86627f --- /dev/null +++ b/cut_sequence_point.gd @@ -0,0 +1,20 @@ +class_name CutSequencePoint +extends Sprite2D + +signal point_cut + +var scalpel: Scalpel +func _ready(): + scalpel = get_tree().get_first_node_in_group("cutter") + +func _on_area_2d_area_entered(area): + if area != scalpel.cut_area or not scalpel.is_cutting: return + point_cut.emit() + +func confirm_cut(): + visible = false + $Area2D.set_deferred("monitoring", false) + +func reset_cut(): + visible = true + $Area2D.set_deferred("monitoring", true) diff --git a/cut_sequence_point.tscn b/cut_sequence_point.tscn new file mode 100644 index 0000000..9e3effd --- /dev/null +++ b/cut_sequence_point.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=4 format=3 uid="uid://x5powiwrfash"] + +[ext_resource type="Texture2D" uid="uid://gf7us6an3mhu" path="res://test_star.png" id="1_o3e76"] +[ext_resource type="Script" path="res://cut_sequence_point.gd" id="2_um6ol"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_e2fuh"] +radius = 8.24621 + +[node name="CutSequencePoint" type="Sprite2D"] +scale = Vector2(0.5, 0.5) +texture = ExtResource("1_o3e76") +script = ExtResource("2_um6ol") + +[node name="Area2D" type="Area2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +position = Vector2(0, 2) +shape = SubResource("CircleShape2D_e2fuh") + +[connection signal="area_entered" from="Area2D" to="." method="_on_area_2d_area_entered"] diff --git a/feedback_canvas_modulate.gd b/feedback_canvas_modulate.gd index 85f5647..86e0f06 100644 --- a/feedback_canvas_modulate.gd +++ b/feedback_canvas_modulate.gd @@ -12,4 +12,3 @@ func show_hurt_feedback(): tween.tween_property(self, "color", Color(1.0,0,0, .2), .1) tween.tween_property(self, "color", default_color, .3) tween.tween_callback(func(): is_tweening = false) - diff --git a/guideline_point.gd b/guideline_point.gd deleted file mode 100644 index 44b9b67..0000000 --- a/guideline_point.gd +++ /dev/null @@ -1,18 +0,0 @@ -class_name GuidelinePoint -extends Sprite2D - -@export_node_path("Node2D") var connections: Array[NodePath] = [] - -@onready var area = $Area2D - -var scalpel: Scalpel - -func _ready(): - area.connect("area_exited", _on_area_entered) - scalpel = get_tree().get_first_node_in_group("cutter") - - -func _on_area_entered(area: Area2D): - if area != scalpel.cut_area or not scalpel.is_cutting: return - queue_free() - diff --git a/guidelines.gd b/guidelines.gd deleted file mode 100644 index d325e77..0000000 --- a/guidelines.gd +++ /dev/null @@ -1,13 +0,0 @@ -extends Node2D - -class Connection: - var source: NodePath - var targets: Array[NodePath] - -var guideline_points: Array[Node] - -func _ready(): - guideline_points = get_children().filter(func(c): return c is GuidelinePoint) - -func _process(delta): - if get_child_count() == 0: get_parent().operation_succeeded() diff --git a/operation.gd b/operation.gd new file mode 100644 index 0000000..a113b64 --- /dev/null +++ b/operation.gd @@ -0,0 +1,42 @@ +class_name Operation +extends Node + +var steps: Array[Node2D] = [] +var active_step: Node2D = null + +func _ready(): + var children = get_children() + for child in children: + if child is Node2D: + steps.push_back(child) + if child is CutSequence: + child.sequence_succeeded.connect(_on_cut_sequence_succeeded.bind(child)) + child.sequence_failed.connect(_on_cut_sequence_failed.bind(child)) + _disable_node2d(child) + + active_step = steps[0] + _enable_node2d(active_step) + + +func _on_cut_sequence_succeeded(cut_sequence: CutSequence): + _disable_node2d(active_step) + var next_index = steps.find(cut_sequence) + 1 + if next_index == 4: + _enable_node2d(%TestBody2) + _disable_node2d(%TestBody1) + + active_step = steps[next_index] + _enable_node2d(active_step) + + +func _on_cut_sequence_failed(cut_sequence: CutSequence): + pass + +func _enable_node2d(node: Node2D): + node.set_deferred("visible", true) + node.set_deferred("process_mode", Node.PROCESS_MODE_INHERIT) + + +func _disable_node2d(node: Node2D): + node.set_deferred("visible", false) + node.set_deferred("process_mode", Node.PROCESS_MODE_DISABLED) diff --git a/project.godot b/project.godot index 21fc49d..474fddd 100644 --- a/project.godot +++ b/project.godot @@ -19,6 +19,12 @@ config/icon="res://icon.svg" window/stretch/mode="viewport" +[layer_names] + +2d_physics/layer_1="Operation" +2d_physics/layer_2="Pickup" +2d_physics/layer_3="Body" + [rendering] renderer/rendering_method="gl_compatibility" diff --git a/prototype_dark_cut.tscn b/prototype_dark_cut.tscn index cbf876c..fb30211 100644 --- a/prototype_dark_cut.tscn +++ b/prototype_dark_cut.tscn @@ -5,10 +5,11 @@ [ext_resource type="Texture2D" uid="uid://bp10w3bh1gn14" path="res://test_body_1.png" id="2_atjyl"] [ext_resource type="Texture2D" uid="uid://cg3dg7iqif56d" path="res://test_scalpel.png" id="3_a4jra"] [ext_resource type="Script" path="res://test_scalpel.gd" id="4_5ba3g"] -[ext_resource type="Texture2D" uid="uid://gf7us6an3mhu" path="res://test_star.png" id="4_frsoy"] -[ext_resource type="Script" path="res://guidelines.gd" id="6_0fd2w"] -[ext_resource type="Script" path="res://guideline_point.gd" id="8_5qgyw"] +[ext_resource type="Texture2D" uid="uid://b82j8773uke65" path="res://test_body_2.png" id="5_piyi3"] +[ext_resource type="Script" path="res://operation.gd" id="7_mteqj"] [ext_resource type="Script" path="res://feedback_canvas_modulate.gd" id="9_4ghh6"] +[ext_resource type="Script" path="res://cut_sequence.gd" id="10_gcaa6"] +[ext_resource type="PackedScene" uid="uid://x5powiwrfash" path="res://cut_sequence_point.tscn" id="11_hcsao"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pgu75"] bg_color = Color(0.417457, 0, 0.105249, 1) @@ -23,8 +24,6 @@ height = 142.904 [sub_resource type="CircleShape2D" id="CircleShape2D_qmwrh"] radius = 5.65684 -[sub_resource type="CircleShape2D" id="CircleShape2D_0bwgd"] - [node name="PrototypeDarkCut" type="Node"] script = ExtResource("1_vl0qk") @@ -60,6 +59,10 @@ size_flags_vertical = 4 theme_override_styles/fill = SubResource("StyleBoxFlat_pgu75") value = 100.0 +[node name="FeedbackCanvasModulate" type="CanvasModulate" parent="."] +unique_name_in_owner = true +script = ExtResource("9_4ghh6") + [node name="UtilsDropoff" type="Sprite2D" parent="."] position = Vector2(1020.25, 43) scale = Vector2(0.761429, 0.14494) @@ -75,14 +78,22 @@ position = Vector2(613, 358) texture = ExtResource("1_7i8d4") [node name="TestBody1" type="Sprite2D" parent="."] +unique_name_in_owner = true position = Vector2(620, 399) texture = ExtResource("2_atjyl") [node name="Area2D" type="Area2D" parent="TestBody1"] +collision_layer = 4 +collision_mask = 4 [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="TestBody1/Area2D"] polygon = PackedVector2Array(0, -250, -39.2, -250, -45.6, -246, -48.9, -246, -54.9, -239, -56.2, -239, -61.1, -230, -62.6, -230, -67.5, -210, -69, -210, -69, -181.7, -65, -168, -65, -163.3, -49, -143, -47, -128.8, -47, -124.8, -63.3, -122, -67.3, -122, -102.9, -109.8, -113.5, -116, -124.4, -116, -148.3, -106, -150, -106, -150, 49.2, -146, 67.4, -146, 71.4, -138, 93.4, -138, 99.7, -132, 106.7, -132, 109, -115.2, 109, -108.2, 102, -106.5, 102, -101.5, 86, -100, 86, -99, 35, -99, 16.8, -96.5, 26, -96, 93, -100, 140.9, -100, 163.1, -95.7, 192, -94.9, 192, -91, 246.1, -91, 250, 61, 250, 61, 236.5, 58, 230.5, 58, 217.1, 68, 38.1, 68, 64.3, 74, 82.3, 74, 85, 82, 91, 82, 92.8, 93, 93.8, 93, 95, 109.8, 95, 117.7, 88, 119.8, 88, 128.8, 9, 129.9, 9, 131.9, -42, 133.1, -42, 132, -84, 132, -90.7, 121, -103.8, 121, -105.6, 113, -107.6, 113, -109.2, 90.1, -107.1, 87, -112.5, 87, -114.9, 75, -125, 75, -127.2, 44.8, -124, 31.2, -124, 33, -144.9, 33, -151.3, 48.9, -169, 50.4, -169, 54.4, -179, 56, -179, 56, -200.6, 43, -219.7, 43, -222, 30, -232, 30, -233.2, 0, -248.3) +[node name="TestBody2" type="Sprite2D" parent="."] +unique_name_in_owner = true +position = Vector2(620, 399) +texture = ExtResource("5_piyi3") + [node name="TestScalpel" type="Sprite2D" parent="." groups=["cutter"]] position = Vector2(949, 41) rotation = -2.0542 @@ -91,11 +102,15 @@ texture = ExtResource("3_a4jra") script = ExtResource("4_5ba3g") [node name="PickupArea" type="Area2D" parent="TestScalpel"] +collision_layer = 2 +collision_mask = 2 [node name="CollisionShape2D" type="CollisionShape2D" parent="TestScalpel/PickupArea"] shape = SubResource("CapsuleShape2D_jndi4") [node name="CutArea" type="Area2D" parent="TestScalpel"] +collision_layer = 5 +collision_mask = 5 [node name="CollisionShape2D" type="CollisionShape2D" parent="TestScalpel/CutArea"] position = Vector2(9.33812, -65.1214) @@ -105,204 +120,76 @@ debug_color = Color(0.879882, 0.304191, 0.394852, 0.42) [node name="CutHurtTimer" type="Timer" parent="TestScalpel"] unique_name_in_owner = true -[node name="Guidelines" type="Node2D" parent="."] -script = ExtResource("6_0fd2w") +[node name="Operation" type="Node" parent="."] +script = ExtResource("7_mteqj") -[node name="TestStar_1" type="Sprite2D" parent="Guidelines"] -position = Vector2(557, 313) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_2")]) +[node name="CutSequence" type="Node2D" parent="Operation"] +script = ExtResource("10_gcaa6") -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_1"] +[node name="CutSequencePoint" parent="Operation/CutSequence" instance=ExtResource("11_hcsao")] +position = Vector2(558, 316) -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_1/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") +[node name="CutSequencePoint2" parent="Operation/CutSequence" instance=ExtResource("11_hcsao")] +position = Vector2(584, 321) -[node name="TestStar_2" type="Sprite2D" parent="Guidelines"] -position = Vector2(574, 318) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_1"), NodePath("../TestStar_3")]) +[node name="CutSequencePoint3" parent="Operation/CutSequence" instance=ExtResource("11_hcsao")] +position = Vector2(614, 326) -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_2"] +[node name="CutSequencePoint4" parent="Operation/CutSequence" instance=ExtResource("11_hcsao")] +position = Vector2(644, 318) -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_2/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") +[node name="CutSequencePoint5" parent="Operation/CutSequence" instance=ExtResource("11_hcsao")] +position = Vector2(668, 311) -[node name="TestStar_3" type="Sprite2D" parent="Guidelines"] -position = Vector2(593, 323) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_2"), NodePath("../TestStar_4")]) +[node name="CutSequence2" type="Node2D" parent="Operation"] +position = Vector2(-4, 69) +script = ExtResource("10_gcaa6") -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_3"] +[node name="CutSequencePoint" parent="Operation/CutSequence2" instance=ExtResource("11_hcsao")] +position = Vector2(618, 257) -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_3/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") +[node name="CutSequencePoint2" parent="Operation/CutSequence2" instance=ExtResource("11_hcsao")] +position = Vector2(615, 285) -[node name="TestStar_4" type="Sprite2D" parent="Guidelines"] -position = Vector2(609, 324) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_3"), NodePath("../TestStar_5"), NodePath("../TestStar_8")]) +[node name="CutSequencePoint3" parent="Operation/CutSequence2" instance=ExtResource("11_hcsao")] +position = Vector2(615, 310) -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_4"] +[node name="CutSequencePoint4" parent="Operation/CutSequence2" instance=ExtResource("11_hcsao")] +position = Vector2(615, 334) -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_4/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") +[node name="CutSequence3" type="Node2D" parent="Operation"] +position = Vector2(-4, 69) +script = ExtResource("10_gcaa6") -[node name="TestStar_5" type="Sprite2D" parent="Guidelines"] -position = Vector2(627, 324) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_4"), NodePath("../TestStar_6")]) +[node name="CutSequencePoint" parent="Operation/CutSequence3" instance=ExtResource("11_hcsao")] +position = Vector2(615, 334) -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_5"] +[node name="CutSequencePoint2" parent="Operation/CutSequence3" instance=ExtResource("11_hcsao")] +position = Vector2(598, 342) -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_5/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") +[node name="CutSequencePoint3" parent="Operation/CutSequence3" instance=ExtResource("11_hcsao")] +position = Vector2(580, 350) -[node name="TestStar_6" type="Sprite2D" parent="Guidelines"] -position = Vector2(647, 322) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_5"), NodePath("../TestStar_7")]) +[node name="CutSequencePoint4" parent="Operation/CutSequence3" instance=ExtResource("11_hcsao")] +position = Vector2(562, 355) -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_6"] +[node name="CutSequence4" type="Node2D" parent="Operation"] +position = Vector2(-4, 69) +script = ExtResource("10_gcaa6") -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_6/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") +[node name="CutSequencePoint" parent="Operation/CutSequence4" instance=ExtResource("11_hcsao")] +position = Vector2(615, 334) -[node name="TestStar_7" type="Sprite2D" parent="Guidelines"] -position = Vector2(666, 318) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_6")]) +[node name="CutSequencePoint2" parent="Operation/CutSequence4" instance=ExtResource("11_hcsao")] +position = Vector2(628, 342) -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_7"] +[node name="CutSequencePoint3" parent="Operation/CutSequence4" instance=ExtResource("11_hcsao")] +position = Vector2(647, 353) -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_7/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") +[node name="CutSequencePoint4" parent="Operation/CutSequence4" instance=ExtResource("11_hcsao")] +position = Vector2(665, 355) -[node name="TestStar_8" type="Sprite2D" parent="Guidelines"] -position = Vector2(609, 345) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_4"), NodePath("../TestStar_9")]) - -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_8"] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_8/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") - -[node name="TestStar_9" type="Sprite2D" parent="Guidelines"] -position = Vector2(608, 368) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_8"), NodePath("../TestStar_910")]) - -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_9"] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_9/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") - -[node name="TestStar_910" type="Sprite2D" parent="Guidelines"] -position = Vector2(609, 385) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_9"), NodePath("../TestStar_911"), NodePath("../TestStar_914")]) - -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_910"] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_910/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") - -[node name="TestStar_911" type="Sprite2D" parent="Guidelines"] -position = Vector2(594, 399) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_910"), NodePath("../TestStar_912")]) - -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_911"] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_911/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") - -[node name="TestStar_912" type="Sprite2D" parent="Guidelines"] -position = Vector2(572, 398) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_911"), NodePath("../TestStar_913")]) - -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_912"] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_912/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") - -[node name="TestStar_913" type="Sprite2D" parent="Guidelines"] -position = Vector2(552, 398) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_912")]) - -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_913"] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_913/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") - -[node name="TestStar_914" type="Sprite2D" parent="Guidelines"] -position = Vector2(626, 401) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_910"), NodePath("../TestStar_915")]) - -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_914"] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_914/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") - -[node name="TestStar_915" type="Sprite2D" parent="Guidelines"] -position = Vector2(646, 402) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_914"), NodePath("../TestStar1_916")]) - -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar_915"] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar_915/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") - -[node name="TestStar1_916" type="Sprite2D" parent="Guidelines"] -position = Vector2(666, 403) -scale = Vector2(0.5, 0.5) -texture = ExtResource("4_frsoy") -script = ExtResource("8_5qgyw") -connections = Array[NodePath]([NodePath("../TestStar_915")]) - -[node name="Area2D" type="Area2D" parent="Guidelines/TestStar1_916"] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Guidelines/TestStar1_916/Area2D"] -shape = SubResource("CircleShape2D_0bwgd") - -[node name="FeedbackCanvasModulate" type="CanvasModulate" parent="."] -unique_name_in_owner = true -script = ExtResource("9_4ghh6") +[node name="GrabBat" type="Node2D" parent="Operation"] [connection signal="value_changed" from="UI/HBoxContainer/PatienceBar" to="." method="_on_patience_bar_value_changed"] [connection signal="area_entered" from="UtilsDropoff/Area2D" to="TestScalpel" method="_on_dropoff_area_entered"] diff --git a/test_body_2.png b/test_body_2.png new file mode 100644 index 0000000000000000000000000000000000000000..2abce5c575dfd278e73211b615f24a6ab7dca503 GIT binary patch literal 17240 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 literal 0 HcmV?d00001 diff --git a/test_body_2.png.import b/test_body_2.png.import new file mode 100644 index 0000000..42e15d8 --- /dev/null +++ b/test_body_2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b82j8773uke65" +path="res://.godot/imported/test_body_2.png-d7075535262222be1c971d9545bf8b7c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://test_body_2.png" +dest_files=["res://.godot/imported/test_body_2.png-d7075535262222be1c971d9545bf8b7c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/test_scalpel.gd b/test_scalpel.gd index 5fc1e06..b7e162b 100644 --- a/test_scalpel.gd +++ b/test_scalpel.gd @@ -1,14 +1,17 @@ class_name Scalpel extends Sprite2D +signal cut_started +signal cut_ended + var is_clickable = false var is_picked_up = false var is_dropable = false var is_cutting_possible = false var is_cutting = false -@onready var pickup_area = $PickupArea -@onready var cut_area = $CutArea +@onready var pickup_area: Area2D = $PickupArea +@onready var cut_area: Area2D = $CutArea @onready var feedback_canvas_modulate: FeedbackCanvasModulate = %FeedbackCanvasModulate func _ready(): @@ -70,8 +73,9 @@ func start_cutting(): _scalpel_degrees_default = rotation_degrees rotation_degrees = SCALPEL_ROTATION_CUTTING _on_cut_hurt_timer_timeout() - %CutHurtTimer.start(1) + %CutHurtTimer.start(2) is_cutting = true + cut_started.emit() func stop_cutting(): if not is_cutting: return @@ -79,6 +83,7 @@ func stop_cutting(): rotation_degrees = _scalpel_degrees_default %CutHurtTimer.stop() is_cutting = false + cut_ended.emit() func _on_cut_hurt_timer_timeout():