From f1d07693dd57ebe8b140db04bc6ee93c849996cf Mon Sep 17 00:00:00 2001 From: nitekot Date: Wed, 15 Jul 2020 20:03:45 +0300 Subject: [PATCH] Brain as object --- character/pioneeres/Pioneeres.gd | 10 +++- character/pioneeres/Pioneeres.tscn | 3 ++ character/pioneeres/brain/AtomicAction.gd | 11 ++-- character/pioneeres/brain/Brain.gd | 21 +++++--- character/pioneeres/brain/DelayAction.gd | 4 +- character/pioneeres/brain/GoToAction.gd | 16 +++--- character/pioneeres/brain/InteractAction.gd | 10 ++-- character/pioneeres/brain/Navigator.gd | 58 +++++++++++++++++++++ character/pioneeres/brain/Navigator.tscn | 24 +++++++++ levels/TestLevel2.tscn | 32 ++++-------- project.godot | 14 ++++- 11 files changed, 148 insertions(+), 55 deletions(-) create mode 100644 character/pioneeres/brain/Navigator.gd create mode 100644 character/pioneeres/brain/Navigator.tscn diff --git a/character/pioneeres/Pioneeres.gd b/character/pioneeres/Pioneeres.gd index ffe184e..77b799f 100644 --- a/character/pioneeres/Pioneeres.gd +++ b/character/pioneeres/Pioneeres.gd @@ -1,10 +1,16 @@ extends "../Character.gd" + +onready var brain: Brain = Brain.new(self) +onready var navigator: Navigator = Navigator.new() + + func _ready(): var scene_root = get_tree().current_scene self.connect("dying", scene_root, "_on_Pioneeres_dying") - if $Brain: - $Brain.start() + if $Actions: + brain.set_actions($Actions.get_children()) + brain.start() func _on_HurtBox_area_entered(area): die() diff --git a/character/pioneeres/Pioneeres.tscn b/character/pioneeres/Pioneeres.tscn index eed828c..a2e38f6 100644 --- a/character/pioneeres/Pioneeres.tscn +++ b/character/pioneeres/Pioneeres.tscn @@ -28,4 +28,7 @@ collision_mask = 4 [node name="CollisionShape2D" type="CollisionShape2D" parent="HurtBox" index="0"] position = Vector2( 0, -5 ) shape = SubResource( 2 ) + +[node name="EmotionBubble" parent="." index="5"] +emotion = "alert" [connection signal="area_entered" from="HurtBox" to="." method="_on_HurtBox_area_entered"] diff --git a/character/pioneeres/brain/AtomicAction.gd b/character/pioneeres/brain/AtomicAction.gd index 4294df1..d43dfe5 100644 --- a/character/pioneeres/brain/AtomicAction.gd +++ b/character/pioneeres/brain/AtomicAction.gd @@ -3,19 +3,18 @@ extends Node class_name AtomicAction signal done(action) - -var brain +var actor var icon = "" -func perform(_brain): - brain = _brain +func perform(_actor): + actor = _actor print(self, " perform") - connect("done", brain, "action_finished") + connect("done", actor.brain, "action_finished") func _notify_done(): print(self, " done") emit_signal("done", self) - disconnect("done", brain, "action_finished") + disconnect("done", actor.brain, "action_finished") func _to_string() -> String: return "AtomicAction" diff --git a/character/pioneeres/brain/Brain.gd b/character/pioneeres/brain/Brain.gd index b798ac0..8b17f32 100644 --- a/character/pioneeres/brain/Brain.gd +++ b/character/pioneeres/brain/Brain.gd @@ -1,21 +1,26 @@ -extends Node2D +class_name Brain -onready var actions = $Actions.get_children() -onready var actor = get_parent() +var actions +var actor + +func _init (_actor): + actor = _actor + +func set_actions(_actions): + actions = _actions func start(): - print(actions) - _perform_next_action() + print('Brain works ',actor.name) + if actions: + _perform_next_action() func action_finished(action: AtomicAction): print(self, " action ", action, " finished") - if actions.empty(): - actions = $Actions.get_children() _perform_next_action() func _perform_next_action(): var action: AtomicAction = actions.pop_front() print("next_Action: ", action) - action.perform(self) + action.perform(actor) if action.icon != "": actor.emotion_bubble.show_emotion(action.icon) diff --git a/character/pioneeres/brain/DelayAction.gd b/character/pioneeres/brain/DelayAction.gd index dd8f7ec..d91ac34 100644 --- a/character/pioneeres/brain/DelayAction.gd +++ b/character/pioneeres/brain/DelayAction.gd @@ -7,8 +7,8 @@ export(float, 1, 30) var wait_time func _ready(): icon = "sleep" -func perform(brain): - .perform(brain) +func perform(actor): + .perform(actor) $Timer.start(wait_time) func _on_Timer_timeout(): diff --git a/character/pioneeres/brain/GoToAction.gd b/character/pioneeres/brain/GoToAction.gd index a2b549e..8b26afb 100644 --- a/character/pioneeres/brain/GoToAction.gd +++ b/character/pioneeres/brain/GoToAction.gd @@ -3,16 +3,14 @@ extends AtomicAction class_name GoToAction onready var target: Position2D = $Destination -var navigation -func perform(_actor): - .perform(brain) - var actor: Node2D = _actor - navigation = actor.find_node("Navigation") - navigation.set_destination(target.global_position) - navigation.connect("arrived", self, "_on_navigation_finished") + +func perform(actor): + .perform(actor) + actor.navigator.set_destination(target.global_position) + actor.navigator.connect("arrived", self, "_on_navigation_finished") func _on_navigation_finished(): _notify_done() - navigation.disconnect("arrived", self, "_on_navigation_finished") - navigation = null + actor.navigator.disconnect("arrived", self, "_on_navigation_finished") + diff --git a/character/pioneeres/brain/InteractAction.gd b/character/pioneeres/brain/InteractAction.gd index 8d0f2b6..9b5ace9 100644 --- a/character/pioneeres/brain/InteractAction.gd +++ b/character/pioneeres/brain/InteractAction.gd @@ -5,13 +5,13 @@ class_name InteractAction func _ready(): icon = "idea" -func perform(brain): - .perform(brain) - brain.actor.interact() - brain.actor.connect("interaction_finished", self, "_on_interaction_finished") +func perform(actor): + .perform(actor) + actor.interact() + actor.connect("interaction_finished", self, "_on_interaction_finished") func _on_interaction_finished(): - brain.actor.disconnect("interaction_finished", self, "_on_interaction_finished") + actor.disconnect("interaction_finished", self, "_on_interaction_finished") _notify_done() func _to_string() -> String: diff --git a/character/pioneeres/brain/Navigator.gd b/character/pioneeres/brain/Navigator.gd new file mode 100644 index 0000000..2ad33f7 --- /dev/null +++ b/character/pioneeres/brain/Navigator.gd @@ -0,0 +1,58 @@ +extends Node2D +class_name Navigator + +signal arrived +signal direction_update(direction) + +export(float, 0.1, 40) var arrival_threshhold := 10.0 +export(float, 10, 200) var raycast_length := 100 + +onready var raycast: RayCast2D = $NavigationRaycast + +onready var direction_indicator: RayCast2D = $RayCast2D +onready var target = $Target + +var _destination: Vector2 = Vector2.INF +var _preferred_direction = PI / 2 + +func _ready(): + _randomize_preferred_direction() + +func set_destination(destination: Vector2): + _destination = destination + +func _physics_process(delta): + if not _is_active(): + return + elif _is_arrived(): + _destination = Vector2.INF + emit_signal("direction_update", Vector2.ZERO) + emit_signal("arrived") + else: + target.global_position = _destination + var direction = global_position.direction_to(_destination) + raycast.look_at(_destination) + var distance_to_collision = raycast.get_collision_point().distance_to(global_position) + if raycast.is_colliding() && _remaining_distance() > distance_to_collision: + var displacement = raycast.get_collision_normal().rotated(_preferred_direction) + var displacement_scale = (raycast_length - distance_to_collision) / raycast_length + var displacement_scale_inv = 1 / displacement_scale + direction = direction * displacement_scale + displacement * displacement_scale + direction_indicator.look_at(global_position + direction) + + emit_signal("direction_update", direction) + +func _is_active() -> bool: + return _destination != Vector2.INF + +func _is_arrived() -> bool: + if _remaining_distance() < arrival_threshhold: + emit_signal("arrived") + _destination = Vector2.INF + return _destination == Vector2.INF + +func _remaining_distance() -> float: + return _destination.distance_to(global_position) + +func _randomize_preferred_direction(): + _preferred_direction = sign(randf() - 0.3) * PI / 2 diff --git a/character/pioneeres/brain/Navigator.tscn b/character/pioneeres/brain/Navigator.tscn new file mode 100644 index 0000000..f428fe2 --- /dev/null +++ b/character/pioneeres/brain/Navigator.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://assets/emotes/emote_anger.png" type="Texture" id=1] +[ext_resource path="res://character/pioneeres/brain/Navigator.gd" type="Script" id=2] + + +[node name="Navigation" type="Node2D"] +position = Vector2( 0, -4 ) +script = ExtResource( 2 ) +__meta__ = { +"_edit_group_": true +} + +[node name="NavigationRaycast" type="RayCast2D" parent="."] +enabled = true +cast_to = Vector2( 100, 0 ) + +[node name="Target" type="Sprite" parent="."] +visible = false +z_index = 1 +texture = ExtResource( 1 ) + +[node name="RayCast2D" type="RayCast2D" parent="."] +cast_to = Vector2( 50, 0 ) diff --git a/levels/TestLevel2.tscn b/levels/TestLevel2.tscn index f5f132b..5dcd18e 100644 --- a/levels/TestLevel2.tscn +++ b/levels/TestLevel2.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=13 format=2] +[gd_scene load_steps=11 format=2] [ext_resource path="res://levels/BaseLevel.tscn" type="PackedScene" id=1] [ext_resource path="res://character/pioneeres/Pioneeres.tscn" type="PackedScene" id=2] @@ -9,8 +9,6 @@ [ext_resource path="res://objects/toilet/Toilet.tscn" type="PackedScene" id=7] [ext_resource path="res://character/pioneeres/brain/InteractAction.tscn" type="PackedScene" id=8] [ext_resource path="res://character/pioneeres/brain/DelayAction.tscn" type="PackedScene" id=9] -[ext_resource path="res://character/pioneeres/brain/Brain.gd" type="Script" id=10] -[ext_resource path="res://character/pioneeres/brain/Navigation.tscn" type="PackedScene" id=11] [ext_resource path="res://character/pioneeres/brain/GoToAction.tscn" type="PackedScene" id=12] [node name="TestLevel2" instance=ExtResource( 1 )] @@ -54,27 +52,22 @@ position = Vector2( 340, 347 ) [node name="Pioneeres" parent="Objects" index="7" instance=ExtResource( 2 )] position = Vector2( 34, 229 ) -[node name="Brain" type="Node2D" parent="Objects/Pioneeres" index="8"] -script = ExtResource( 10 ) +[node name="Actions" type="Node" parent="Objects/Pioneeres" index="8"] -[node name="Navigation" parent="Objects/Pioneeres/Brain" index="0" instance=ExtResource( 11 )] - -[node name="Actions" type="Node" parent="Objects/Pioneeres/Brain" index="1"] - -[node name="DelayAction" parent="Objects/Pioneeres/Brain/Actions" index="0" instance=ExtResource( 9 )] +[node name="DelayAction" parent="Objects/Pioneeres/Actions" index="0" instance=ExtResource( 9 )] wait_time = 5.0 -[node name="InteractAction" parent="Objects/Pioneeres/Brain/Actions" index="1" instance=ExtResource( 8 )] +[node name="InteractAction" parent="Objects/Pioneeres/Actions" index="1" instance=ExtResource( 8 )] -[node name="GoToAction" parent="Objects/Pioneeres/Brain/Actions" index="2" instance=ExtResource( 12 )] +[node name="GoToAction" parent="Objects/Pioneeres/Actions" index="2" instance=ExtResource( 12 )] -[node name="Destination" parent="Objects/Pioneeres/Brain/Actions/GoToAction" index="0"] -position = Vector2( 155, 304 ) +[node name="Target" type="Position2D" parent="Objects/Pioneeres/Actions/GoToAction" index="1"] +position = Vector2( 228.728, 275.946 ) -[node name="GoToAction2" parent="Objects/Pioneeres/Brain/Actions" index="3" instance=ExtResource( 12 )] +[node name="GoToAction2" parent="Objects/Pioneeres/Actions" index="3" instance=ExtResource( 12 )] -[node name="Destination" parent="Objects/Pioneeres/Brain/Actions/GoToAction2" index="0"] -position = Vector2( 33, 225 ) +[node name="Target" type="Position2D" parent="Objects/Pioneeres/Actions/GoToAction2" index="1"] +position = Vector2( 129.393, 233.182 ) [node name="Pioneeres2" parent="Objects" index="8" instance=ExtResource( 2 )] position = Vector2( 272, 192 ) @@ -90,8 +83,3 @@ position = Vector2( 240, -27 ) [node name="Foreground" parent="." index="6"] tile_data = PoolIntArray( -524270, 0, 0, -524269, 0, 2, -458734, 0, 65536, -458733, 0, 65538, -393198, 0, 65536, -393197, 0, 65538, -327662, 0, 65536, -327661, 0, 65538, -262126, 0, 65536, -262125, 0, 65538, -196590, 0, 131072, -196589, 0, 131074, 458772, 0, 0, 458773, 0, 2, 458776, 0, 0, 458777, 0, 1, 458778, 0, 1, 458779, 0, 2, 524308, 0, 65536, 524309, 0, 65538, 524312, 0, 65536, 524313, 0, 65537, 524314, 0, 65537, 524315, 0, 65538, 589836, 0, 0, 589837, 0, 2, 589839, 0, 0, 589840, 0, 1, 589841, 0, 1, 589842, 0, 2, 589844, 0, 65536, 589845, 0, 65538, 589848, 0, 65536, 589849, 0, 65537, 589850, 0, 65537, 589851, 0, 65538, 655372, 0, 131072, 655373, 0, 131074, 655375, 0, 131072, 655376, 0, 131073, 655377, 0, 131073, 655378, 0, 131074, 655380, 0, 131072, 655381, 0, 131074, 655384, 0, 131072, 655385, 0, 131073, 655386, 0, 131073, 655387, 0, 131074 ) -[connection signal="direction_update" from="Objects/Pioneeres/Brain/Navigation" to="Objects/Pioneeres" method="_on_direction"] - -[editable path="Objects/Pioneeres/Brain/Actions/GoToAction"] - -[editable path="Objects/Pioneeres/Brain/Actions/GoToAction2"] diff --git a/project.godot b/project.godot index a394b37..97c92ad 100644 --- a/project.godot +++ b/project.godot @@ -14,6 +14,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://character/pioneeres/brain/AtomicAction.gd" }, { +"base": "Reference", +"class": "Brain", +"language": "GDScript", +"path": "res://character/pioneeres/brain/Brain.gd" +}, { "base": "AtomicAction", "class": "DelayAction", "language": "GDScript", @@ -28,12 +33,19 @@ _global_script_classes=[ { "class": "InteractAction", "language": "GDScript", "path": "res://character/pioneeres/brain/InteractAction.gd" +}, { +"base": "Node2D", +"class": "Navigator", +"language": "GDScript", +"path": "res://character/pioneeres/brain/Navigator.gd" } ] _global_script_class_icons={ "AtomicAction": "", +"Brain": "", "DelayAction": "", "GoToAction": "", -"InteractAction": "" +"InteractAction": "", +"Navigator": "" } [application]