From 4bc8bb372fe1844aaa4ee78d7f66951c6cf24afb Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Sun, 15 Dec 2019 10:57:12 -0500 Subject: [PATCH 01/23] Build the initial project --- .gitignore | 1 + default_env.tres | 5 +++++ icon.png | Bin 0 -> 3433 bytes icon.png.import | 34 ++++++++++++++++++++++++++++++++++ project.godot | 23 +++++++++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100644 .gitignore create mode 100644 default_env.tres create mode 100644 icon.png create mode 100644 icon.png.import create mode 100644 project.godot diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56594a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.import/ \ No newline at end of file diff --git a/default_env.tres b/default_env.tres new file mode 100644 index 0000000..98f26a7 --- /dev/null +++ b/default_env.tres @@ -0,0 +1,5 @@ +[gd_resource type="Environment" load_steps=2 format=2] +[sub_resource type="ProceduralSky" id=1] +[resource] +background_mode = 2 +background_sky = SubResource( 1 ) diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2b658158b6a2211b656d83fee35e3941e5ad376a GIT binary patch literal 3433 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 LNkvXXu0mjfd922> literal 0 HcmV?d00001 diff --git a/icon.png.import b/icon.png.import new file mode 100644 index 0000000..96cbf46 --- /dev/null +++ b/icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..b360758 --- /dev/null +++ b/project.godot @@ -0,0 +1,23 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=4 + +_global_script_classes=[ ] +_global_script_class_icons={ + +} + +[application] + +config/name="godot-steering-toolkit" +config/icon="res://icon.png" + +[rendering] + +environment/default_environment="res://default_env.tres" From c00b1242c81282cb6fd948618c3439cc28499f5d Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Mon, 16 Dec 2019 11:22:03 -0500 Subject: [PATCH 02/23] Implement Face, Evade Pursue, Arrive, Flee, Seek The MVP document goes over the main behaviors that need to be implemented prior to having a product. --- default_env.tres | 2 + project.godot | 69 +++++++++++++++++++++- root.tscn | 3 + src/Steering/AgentLocation.gd | 6 ++ src/Steering/Behaviors/Arrive.gd | 46 +++++++++++++++ src/Steering/Behaviors/Evade.gd | 10 ++++ src/Steering/Behaviors/Face.gd | 22 +++++++ src/Steering/Behaviors/Flee.gd | 13 ++++ src/Steering/Behaviors/MatchOrientation.gd | 42 +++++++++++++ src/Steering/Behaviors/Pursue.gd | 35 +++++++++++ src/Steering/Behaviors/Seek.gd | 16 +++++ src/Steering/SteeringAgent.gd | 12 ++++ src/Steering/SteeringBehavior.gd | 18 ++++++ src/Steering/TargetAcceleration.gd | 14 +++++ 14 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 root.tscn create mode 100644 src/Steering/AgentLocation.gd create mode 100644 src/Steering/Behaviors/Arrive.gd create mode 100644 src/Steering/Behaviors/Evade.gd create mode 100644 src/Steering/Behaviors/Face.gd create mode 100644 src/Steering/Behaviors/Flee.gd create mode 100644 src/Steering/Behaviors/MatchOrientation.gd create mode 100644 src/Steering/Behaviors/Pursue.gd create mode 100644 src/Steering/Behaviors/Seek.gd create mode 100644 src/Steering/SteeringAgent.gd create mode 100644 src/Steering/SteeringBehavior.gd create mode 100644 src/Steering/TargetAcceleration.gd diff --git a/default_env.tres b/default_env.tres index 98f26a7..20207a4 100644 --- a/default_env.tres +++ b/default_env.tres @@ -1,5 +1,7 @@ [gd_resource type="Environment" load_steps=2 format=2] + [sub_resource type="ProceduralSky" id=1] + [resource] background_mode = 2 background_sky = SubResource( 1 ) diff --git a/project.godot b/project.godot index b360758..ec6e359 100644 --- a/project.godot +++ b/project.godot @@ -8,9 +8,74 @@ config_version=4 -_global_script_classes=[ ] +_global_script_classes=[ { +"base": "Reference", +"class": "AgentLocation", +"language": "GDScript", +"path": "res://src/Steering/AgentLocation.gd" +}, { +"base": "SteeringBehavior", +"class": "Arrive", +"language": "GDScript", +"path": "res://src/Steering/Behaviors/Arrive.gd" +}, { +"base": "Pursue", +"class": "Evade", +"language": "GDScript", +"path": "res://src/Steering/Behaviors/Evade.gd" +}, { +"base": "MatchOrientation", +"class": "Face", +"language": "GDScript", +"path": "res://src/Steering/Behaviors/Face.gd" +}, { +"base": "Seek", +"class": "Flee", +"language": "GDScript", +"path": "res://src/Steering/Behaviors/Flee.gd" +}, { +"base": "SteeringBehavior", +"class": "MatchOrientation", +"language": "GDScript", +"path": "res://src/Steering/Behaviors/MatchOrientation.gd" +}, { +"base": "SteeringBehavior", +"class": "Pursue", +"language": "GDScript", +"path": "res://src/Steering/Behaviors/Pursue.gd" +}, { +"base": "SteeringBehavior", +"class": "Seek", +"language": "GDScript", +"path": "res://src/Steering/Behaviors/Seek.gd" +}, { +"base": "AgentLocation", +"class": "SteeringAgent", +"language": "GDScript", +"path": "res://src/Steering/SteeringAgent.gd" +}, { +"base": "Reference", +"class": "SteeringBehavior", +"language": "GDScript", +"path": "res://src/Steering/SteeringBehavior.gd" +}, { +"base": "Reference", +"class": "TargetAcceleration", +"language": "GDScript", +"path": "res://src/Steering/TargetAcceleration.gd" +} ] _global_script_class_icons={ - +"AgentLocation": "", +"Arrive": "", +"Evade": "", +"Face": "", +"Flee": "", +"MatchOrientation": "", +"Pursue": "", +"Seek": "", +"SteeringAgent": "", +"SteeringBehavior": "", +"TargetAcceleration": "" } [application] diff --git a/root.tscn b/root.tscn new file mode 100644 index 0000000..b171e8d --- /dev/null +++ b/root.tscn @@ -0,0 +1,3 @@ +[gd_scene format=2] + +[node name="Node2D" type="Node2D"] diff --git a/src/Steering/AgentLocation.gd b/src/Steering/AgentLocation.gd new file mode 100644 index 0000000..2eecad8 --- /dev/null +++ b/src/Steering/AgentLocation.gd @@ -0,0 +1,6 @@ +extends Reference +class_name AgentLocation + + +var position: = Vector3.ZERO +var orientation: = 0.0 diff --git a/src/Steering/Behaviors/Arrive.gd b/src/Steering/Behaviors/Arrive.gd new file mode 100644 index 0000000..f5dd188 --- /dev/null +++ b/src/Steering/Behaviors/Arrive.gd @@ -0,0 +1,46 @@ +extends SteeringBehavior +class_name Arrive + + +var target: AgentLocation +var arrival_tolerance: float +var deceleration_radius: float +var time_to_target: = 0.1 + + +func _init(agent: SteeringAgent, target: AgentLocation).(agent) -> void: + self.target = target + + +func _arrive(acceleration: TargetAcceleration, target_position: Vector3) -> TargetAcceleration: + var to_target: = target_position - agent.position + var distance: = to_target.length() + + if distance <= arrival_tolerance: + return acceleration.set_zero() + + var target_speed: = agent.max_linear_speed + + if distance <= deceleration_radius: + target_speed *= distance / deceleration_radius + + var target_velocity: = to_target * target_speed/distance + + target_velocity = (target_velocity - agent.linear_velocity) * 1.0 / time_to_target + + acceleration.linear = limit_length(target_velocity, agent.max_linear_acceleration) + acceleration.angular = 0 + + return acceleration + + +func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: + return _arrive(acceleration, target.position) + + +static func limit_length(vector: Vector3, limit: float) -> Vector3: + var len2: = vector.length_squared() + var limit2: = limit * limit + if len2 > limit2: + vector *= sqrt(limit2 / len2) + return vector diff --git a/src/Steering/Behaviors/Evade.gd b/src/Steering/Behaviors/Evade.gd new file mode 100644 index 0000000..50a73a5 --- /dev/null +++ b/src/Steering/Behaviors/Evade.gd @@ -0,0 +1,10 @@ +extends Pursue +class_name Evade + + +func _init(agent: SteeringAgent, target: SteeringAgent, max_predict_time: = 1.0).(agent, target, max_predict_time): + pass + + +func get_max_linear_acceleration() -> float: + return -agent.max_linear_acceleration diff --git a/src/Steering/Behaviors/Face.gd b/src/Steering/Behaviors/Face.gd new file mode 100644 index 0000000..453187a --- /dev/null +++ b/src/Steering/Behaviors/Face.gd @@ -0,0 +1,22 @@ +extends MatchOrientation +class_name Face + + +func _init(agent: SteeringAgent, target: AgentLocation).(agent, target) -> void: + pass + + +func _face(acceleration: TargetAcceleration, target_position: Vector3) -> TargetAcceleration: + var to_target: = target_position - agent.position + + var distance_squared: = to_target.length_squared() + if distance_squared < agent.zero_linear_speed_threshold: + return acceleration.set_zero() + + var orientation = Vector3.UP.angle_to(to_target) + + return _match_orientation(acceleration, orientation) + + +func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: + return _face(acceleration, target.position) diff --git a/src/Steering/Behaviors/Flee.gd b/src/Steering/Behaviors/Flee.gd new file mode 100644 index 0000000..6e9d286 --- /dev/null +++ b/src/Steering/Behaviors/Flee.gd @@ -0,0 +1,13 @@ +extends Seek +class_name Flee + + +func _init(agent: SteeringAgent, target: AgentLocation).(agent, target) -> void: + pass + + +func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: + acceleration.linear = (agent.position - target.position).normalized() * agent.max_linear_acceleration + acceleration.angular = 0 + + return acceleration diff --git a/src/Steering/Behaviors/MatchOrientation.gd b/src/Steering/Behaviors/MatchOrientation.gd new file mode 100644 index 0000000..f536bb4 --- /dev/null +++ b/src/Steering/Behaviors/MatchOrientation.gd @@ -0,0 +1,42 @@ +extends SteeringBehavior +class_name MatchOrientation + + +var target: AgentLocation +var alignment_tolerance: float +var deceleration_radius: float +var time_to_target: float = 0.1 + + +func _init(agent: SteeringAgent, target: AgentLocation).(agent) -> void: + self.target = target + + +func _match_orientation(acceleration: TargetAcceleration, target_orientation: float) -> TargetAcceleration: + var rotation: = wrapf(target_orientation - agent.orientation, -PI, PI) + + var rotation_size: = -rotation if rotation < 0 else rotation + + if rotation_size <= alignment_tolerance: + return acceleration.set_zero() + + var target_rotation: = agent.max_angular_speed + + if rotation_size <= deceleration_radius: + target_rotation *= rotation_size / deceleration_radius + + target_rotation *= rotation / rotation_size + + acceleration.angular = (target_rotation - agent.angular_velocity) / time_to_target + + var limited_acceleration: = -acceleration.angular if acceleration.angular < 0 else acceleration.angular + if limited_acceleration > agent.max_angular_acceleration: + acceleration.angular *= agent.max_angular_acceleration / limited_acceleration + + acceleration.linear = Vector3.ZERO + + return acceleration + + +func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: + return _match_orientation(acceleration, target.orientation) diff --git a/src/Steering/Behaviors/Pursue.gd b/src/Steering/Behaviors/Pursue.gd new file mode 100644 index 0000000..d40ec7f --- /dev/null +++ b/src/Steering/Behaviors/Pursue.gd @@ -0,0 +1,35 @@ +extends SteeringBehavior +class_name Pursue + + +var target: SteeringAgent +var max_predict_time: float + + +func _init(agent: SteeringAgent, target: SteeringAgent, max_predict_time: = 1.0).(agent) -> void: + self.target = target + self.max_predict_time = max_predict_time + + +func get_max_linear_acceleration() -> float: + return agent.max_linear_acceleration + + +func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: + var target_position: = target.position + var distance_squared: = (target_position - agent.position).length_squared() + + var speed_squared: = agent.linear_velocity.length_squared() + var predict_time: = max_predict_time + + if speed_squared > 0: + var predict_time_squared: = distance_squared / speed_squared + if predict_time_squared < max_predict_time * max_predict_time: + predict_time = sqrt(predict_time_squared) + + acceleration.linear = ((target_position + (target.linear_velocity * predict_time))-agent.position).normalized() + acceleration.linear *= agent.max_linear_acceleration + + acceleration.angular = 0 + + return acceleration diff --git a/src/Steering/Behaviors/Seek.gd b/src/Steering/Behaviors/Seek.gd new file mode 100644 index 0000000..9f95536 --- /dev/null +++ b/src/Steering/Behaviors/Seek.gd @@ -0,0 +1,16 @@ +extends SteeringBehavior +class_name Seek + + +var target: AgentLocation + + +func _init(agent: SteeringAgent, target: AgentLocation).(agent) -> void: + self.target = target + + +func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: + acceleration.linear = (target.position - agent.position).normalized() * agent.max_linear_acceleration + acceleration.angular = 0 + + return acceleration diff --git a/src/Steering/SteeringAgent.gd b/src/Steering/SteeringAgent.gd new file mode 100644 index 0000000..7ad60c8 --- /dev/null +++ b/src/Steering/SteeringAgent.gd @@ -0,0 +1,12 @@ +extends AgentLocation +class_name SteeringAgent + + +var zero_linear_speed_threshold: = 0.01 +var max_linear_speed: = 0.0 +var max_linear_acceleration: = 0.0 +var max_angular_speed: = 0.0 +var max_angular_acceleration: = 0.0 +var linear_velocity: = Vector3.ZERO +var angular_velocity: = 0.0 +var bounding_radius: = 0.0 diff --git a/src/Steering/SteeringBehavior.gd b/src/Steering/SteeringBehavior.gd new file mode 100644 index 0000000..6d3e8ab --- /dev/null +++ b/src/Steering/SteeringBehavior.gd @@ -0,0 +1,18 @@ +extends Reference +class_name SteeringBehavior + + +var enabled: = true +var agent: SteeringAgent + + +func _init(agent: SteeringAgent) -> void: + self.agent = agent + + +func calculate_steering(acceleration: TargetAcceleration) -> TargetAcceleration: + return _calculate_internal_steering(acceleration) if enabled else acceleration.zero() + + +func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: + return acceleration.set_zero() diff --git a/src/Steering/TargetAcceleration.gd b/src/Steering/TargetAcceleration.gd new file mode 100644 index 0000000..ccc6472 --- /dev/null +++ b/src/Steering/TargetAcceleration.gd @@ -0,0 +1,14 @@ +extends Reference +class_name TargetAcceleration + + +var linear: = Vector3.ZERO +var angular: = 0.0 + + +func set_zero() -> TargetAcceleration: + linear.x = 0.0 + linear.y = 0.0 + linear.z = 0.0 + angular = 0.0 + return self From 9b02baaba652d678089a0f67f9c0a4f9966fc78b Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Mon, 16 Dec 2019 16:14:46 -0500 Subject: [PATCH 03/23] Create a toy demo for Seek and Flee behaviors --- project.godot | 27 +++++++ src/Steering/Demos/SeekFlee/Boundary.gd | 13 ++++ src/Steering/Demos/SeekFlee/Coward.gd | 38 ++++++++++ src/Steering/Demos/SeekFlee/Coward.tscn | 13 ++++ src/Steering/Demos/SeekFlee/Player.gd | 26 +++++++ src/Steering/Demos/SeekFlee/SeekFlee.tscn | 80 +++++++++++++++++++++ src/Steering/Demos/SeekFlee/SeekFleeDemo.gd | 8 +++ src/Steering/Demos/SeekFlee/Seeker.gd | 38 ++++++++++ src/Steering/Demos/SeekFlee/Seeker.tscn | 13 ++++ src/Steering/Demos/SeekFlee/Spawner.gd | 28 ++++++++ 10 files changed, 284 insertions(+) create mode 100644 src/Steering/Demos/SeekFlee/Boundary.gd create mode 100644 src/Steering/Demos/SeekFlee/Coward.gd create mode 100644 src/Steering/Demos/SeekFlee/Coward.tscn create mode 100644 src/Steering/Demos/SeekFlee/Player.gd create mode 100644 src/Steering/Demos/SeekFlee/SeekFlee.tscn create mode 100644 src/Steering/Demos/SeekFlee/SeekFleeDemo.gd create mode 100644 src/Steering/Demos/SeekFlee/Seeker.gd create mode 100644 src/Steering/Demos/SeekFlee/Seeker.tscn create mode 100644 src/Steering/Demos/SeekFlee/Spawner.gd diff --git a/project.godot b/project.godot index ec6e359..29e0df1 100644 --- a/project.godot +++ b/project.godot @@ -83,6 +83,33 @@ _global_script_class_icons={ config/name="godot-steering-toolkit" config/icon="res://icon.png" +[input] + +sf_left={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) + ] +} +sf_right={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null) + ] +} +sf_up={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null) + ] +} +sf_down={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null) + ] +} + [rendering] environment/default_environment="res://default_env.tres" diff --git a/src/Steering/Demos/SeekFlee/Boundary.gd b/src/Steering/Demos/SeekFlee/Boundary.gd new file mode 100644 index 0000000..a9439e5 --- /dev/null +++ b/src/Steering/Demos/SeekFlee/Boundary.gd @@ -0,0 +1,13 @@ +extends StaticBody2D + + +var rect: Rect2 + + +func _ready() -> void: + var extents: = ($CollisionShape2D.shape as RectangleShape2D).extents + rect = Rect2(-extents, extents*2) + + +func _draw() -> void: + draw_rect(rect, Color.yellowgreen) diff --git a/src/Steering/Demos/SeekFlee/Coward.gd b/src/Steering/Demos/SeekFlee/Coward.gd new file mode 100644 index 0000000..f623504 --- /dev/null +++ b/src/Steering/Demos/SeekFlee/Coward.gd @@ -0,0 +1,38 @@ +extends KinematicBody2D + + +onready var radius: = ($CollisionShape2D.shape as CircleShape2D).radius + +var agent: SteeringAgent +var player_agent: AgentLocation +var flee: Flee +var accel: = TargetAcceleration.new() +var velocity: = Vector2.ZERO +var speed: float +var color: Color + + +func _ready() -> void: + agent = SteeringAgent.new() + agent.max_linear_acceleration = speed/10 + agent.max_linear_speed = speed + + flee = Flee.new(agent, player_agent) + + +func _draw() -> void: + draw_circle(Vector2.ZERO, radius, color) + + +func _physics_process(delta: float) -> void: + _update_agent() + accel = flee.calculate_steering(accel) + + velocity = (velocity + Vector2(accel.linear.x, accel.linear.y)).clamped(agent.max_linear_speed) + velocity = move_and_slide(velocity) + if velocity.length_squared() > 0: + update() + + +func _update_agent() -> void: + agent.position = Vector3(global_position.x, global_position.y, 0) diff --git a/src/Steering/Demos/SeekFlee/Coward.tscn b/src/Steering/Demos/SeekFlee/Coward.tscn new file mode 100644 index 0000000..5240047 --- /dev/null +++ b/src/Steering/Demos/SeekFlee/Coward.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://src/Steering/Demos/SeekFlee/Coward.gd" type="Script" id=1] + +[sub_resource type="CircleShape2D" id=1] + +[node name="Coward" type="KinematicBody2D"] +collision_layer = 4 +collision_mask = 6 +script = ExtResource( 1 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource( 1 ) diff --git a/src/Steering/Demos/SeekFlee/Player.gd b/src/Steering/Demos/SeekFlee/Player.gd new file mode 100644 index 0000000..5a7ab70 --- /dev/null +++ b/src/Steering/Demos/SeekFlee/Player.gd @@ -0,0 +1,26 @@ +extends KinematicBody2D + + +onready var _radius: = ($CollisionShape2D.shape as CircleShape2D).radius + +export var speed: = 150.0 + +var player_agent: = AgentLocation.new() + + +func _draw() -> void: + draw_circle(Vector2.ZERO, _radius, Color.red) + + +func _get_movement() -> Vector2: + return Vector2(Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"), + Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up")) + + +func _physics_process(delta: float) -> void: + var movement: = _get_movement() + if movement.length_squared() < 0.01: + return + + move_and_slide(movement * speed) + player_agent.position = Vector3(global_position.x, global_position.y, 0) diff --git a/src/Steering/Demos/SeekFlee/SeekFlee.tscn b/src/Steering/Demos/SeekFlee/SeekFlee.tscn new file mode 100644 index 0000000..d191561 --- /dev/null +++ b/src/Steering/Demos/SeekFlee/SeekFlee.tscn @@ -0,0 +1,80 @@ +[gd_scene load_steps=10 format=2] + +[ext_resource path="res://src/Steering/Demos/SeekFlee/Player.gd" type="Script" id=1] +[ext_resource path="res://src/Steering/Demos/SeekFlee/Spawner.gd" type="Script" id=2] +[ext_resource path="res://src/Steering/Demos/SeekFlee/SeekFleeDemo.gd" type="Script" id=3] +[ext_resource path="res://src/Steering/Demos/SeekFlee/Seeker.tscn" type="PackedScene" id=4] +[ext_resource path="res://src/Steering/Demos/SeekFlee/Boundary.gd" type="Script" id=5] +[ext_resource path="res://src/Steering/Demos/SeekFlee/Coward.tscn" type="PackedScene" id=6] + +[sub_resource type="CircleShape2D" id=1] +radius = 30.0 + +[sub_resource type="RectangleShape2D" id=2] +extents = Vector2( 10, 300 ) + +[sub_resource type="RectangleShape2D" id=3] +extents = Vector2( 512, 10 ) + +[node name="SeekFleeDemo" type="Node2D"] +script = ExtResource( 3 ) +__meta__ = { +"_editor_description_": "A toy demo to demonstrate the usage for the Seek and Flee steering behaviors." +} + +[node name="Camera2D" type="Camera2D" parent="."] +current = true + +[node name="Player" type="KinematicBody2D" parent="."] +collision_mask = 2 +script = ExtResource( 1 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] +shape = SubResource( 1 ) + +[node name="LeftBoundary" type="StaticBody2D" parent="."] +position = Vector2( -512, 0 ) +collision_layer = 2 +collision_mask = 5 +script = ExtResource( 5 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="LeftBoundary"] +shape = SubResource( 2 ) + +[node name="RightBoundary" type="StaticBody2D" parent="."] +position = Vector2( 512, 0 ) +collision_layer = 2 +collision_mask = 5 +script = ExtResource( 5 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RightBoundary"] +shape = SubResource( 2 ) + +[node name="TopBoundary" type="StaticBody2D" parent="."] +position = Vector2( 0, -300 ) +collision_layer = 2 +collision_mask = 5 +script = ExtResource( 5 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="TopBoundary"] +shape = SubResource( 3 ) + +[node name="BottomBoundary" type="StaticBody2D" parent="."] +position = Vector2( 0, 300 ) +collision_layer = 2 +collision_mask = 5 +script = ExtResource( 5 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="BottomBoundary"] +shape = SubResource( 3 ) + +[node name="SeekerSpawner" type="Node2D" parent="."] +script = ExtResource( 2 ) +agent_scene = ExtResource( 4 ) +player = NodePath("../Player") + +[node name="FleeerSpawner" type="Node2D" parent="."] +script = ExtResource( 2 ) +agent_scene = ExtResource( 6 ) +player = NodePath("../Player") +agent_color = Color( 0.0980392, 0.886275, 0.517647, 1 ) diff --git a/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd b/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd new file mode 100644 index 0000000..f92ff1d --- /dev/null +++ b/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd @@ -0,0 +1,8 @@ +extends Node2D + + +var camera_boundaries: Rect2 + + +func _init() -> void: + camera_boundaries = Rect2(Vector2.ZERO, Vector2(ProjectSettings["display/window/size/width"], ProjectSettings["display/window/size/height"])) diff --git a/src/Steering/Demos/SeekFlee/Seeker.gd b/src/Steering/Demos/SeekFlee/Seeker.gd new file mode 100644 index 0000000..759873f --- /dev/null +++ b/src/Steering/Demos/SeekFlee/Seeker.gd @@ -0,0 +1,38 @@ +extends KinematicBody2D + + +onready var radius: = ($CollisionShape2D.shape as CircleShape2D).radius + +var agent: SteeringAgent +var player_agent: AgentLocation +var seek: Seek +var accel: = TargetAcceleration.new() +var velocity: = Vector2.ZERO +var speed: float +var color: Color + + +func _ready() -> void: + agent = SteeringAgent.new() + agent.max_linear_acceleration = speed/10 + agent.max_linear_speed = speed + + seek = Seek.new(agent, player_agent) + + +func _draw() -> void: + draw_circle(Vector2.ZERO, radius, color) + + +func _physics_process(delta: float) -> void: + _update_agent() + accel = seek.calculate_steering(accel) + + velocity = (velocity + Vector2(accel.linear.x, accel.linear.y)).clamped(agent.max_linear_speed) + velocity = move_and_slide(velocity) + if velocity.length_squared() > 0: + update() + + +func _update_agent() -> void: + agent.position = Vector3(global_position.x, global_position.y, 0) diff --git a/src/Steering/Demos/SeekFlee/Seeker.tscn b/src/Steering/Demos/SeekFlee/Seeker.tscn new file mode 100644 index 0000000..4ea2577 --- /dev/null +++ b/src/Steering/Demos/SeekFlee/Seeker.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://src/Steering/Demos/SeekFlee/Seeker.gd" type="Script" id=1] + +[sub_resource type="CircleShape2D" id=1] + +[node name="Seeker" type="KinematicBody2D"] +collision_layer = 4 +collision_mask = 6 +script = ExtResource( 1 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource( 1 ) diff --git a/src/Steering/Demos/SeekFlee/Spawner.gd b/src/Steering/Demos/SeekFlee/Spawner.gd new file mode 100644 index 0000000..afddacc --- /dev/null +++ b/src/Steering/Demos/SeekFlee/Spawner.gd @@ -0,0 +1,28 @@ +extends Node2D + + +onready var player_agent: AgentLocation = get_node(player).player_agent + + +export(PackedScene) var agent_scene: PackedScene +export var agent_count: = 10 +export var player: = NodePath() +export var min_speed: = 50.0 +export var max_speed: = 125.0 +export var agent_color: = Color.blue + + +func _ready() -> void: + var boundaries: Rect2 = owner.camera_boundaries + randomize() + for i in range(agent_count): + var new_pos: = Vector2( + rand_range(-boundaries.size.x/2, boundaries.size.x/2), + rand_range(-boundaries.size.y/2, boundaries.size.y/2) + ) + var agent: = agent_scene.instance() + agent.global_position = new_pos + agent.player_agent = player_agent + agent.speed = rand_range(min_speed, max_speed) + agent.color = agent_color + add_child(agent) From 7520939bdd280609f163de86d0efdc7217b5adf2 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Mon, 16 Dec 2019 23:12:18 -0500 Subject: [PATCH 04/23] Add docstring to currently implemented code. --- src/Steering/AgentLocation.gd | 3 +++ src/Steering/Behaviors/Arrive.gd | 4 ++++ src/Steering/Behaviors/Evade.gd | 5 +++++ src/Steering/Behaviors/Face.gd | 4 ++++ src/Steering/Behaviors/Flee.gd | 3 +++ src/Steering/Behaviors/MatchOrientation.gd | 4 ++++ src/Steering/Behaviors/Pursue.gd | 5 +++++ src/Steering/Behaviors/Seek.gd | 3 +++ src/Steering/Demos/SeekFlee/Boundary.gd | 3 +++ src/Steering/Demos/SeekFlee/Coward.gd | 6 ++++++ src/Steering/Demos/SeekFlee/Player.gd | 3 +++ src/Steering/Demos/SeekFlee/SeekFlee.tscn | 2 -- src/Steering/Demos/SeekFlee/SeekFleeDemo.gd | 8 +++++++- src/Steering/Demos/SeekFlee/Seeker.gd | 6 ++++++ src/Steering/Demos/SeekFlee/Spawner.gd | 6 ++++-- src/Steering/SteeringAgent.gd | 3 +++ src/Steering/SteeringBehavior.gd | 3 +++ src/Steering/TargetAcceleration.gd | 3 +++ 18 files changed, 69 insertions(+), 5 deletions(-) diff --git a/src/Steering/AgentLocation.gd b/src/Steering/AgentLocation.gd index 2eecad8..e0cea19 100644 --- a/src/Steering/AgentLocation.gd +++ b/src/Steering/AgentLocation.gd @@ -1,5 +1,8 @@ extends Reference class_name AgentLocation +""" +Data type to represent an agent with a location and an orientation +""" var position: = Vector3.ZERO diff --git a/src/Steering/Behaviors/Arrive.gd b/src/Steering/Behaviors/Arrive.gd index f5dd188..e972990 100644 --- a/src/Steering/Behaviors/Arrive.gd +++ b/src/Steering/Behaviors/Arrive.gd @@ -1,5 +1,9 @@ extends SteeringBehavior class_name Arrive +""" +Calculates acceleration to take an agent to its target's location. +The calculation will attempt to arrive with zero remaining velocity. +""" var target: AgentLocation diff --git a/src/Steering/Behaviors/Evade.gd b/src/Steering/Behaviors/Evade.gd index 50a73a5..091d48d 100644 --- a/src/Steering/Behaviors/Evade.gd +++ b/src/Steering/Behaviors/Evade.gd @@ -1,5 +1,10 @@ extends Pursue class_name Evade +""" +Calculates acceleration to take an agent away from where a target agent will be. + +The `max_predict_time` variable represents how far ahead to calculate the intersection point. +""" func _init(agent: SteeringAgent, target: SteeringAgent, max_predict_time: = 1.0).(agent, target, max_predict_time): diff --git a/src/Steering/Behaviors/Face.gd b/src/Steering/Behaviors/Face.gd index 453187a..e80ee5b 100644 --- a/src/Steering/Behaviors/Face.gd +++ b/src/Steering/Behaviors/Face.gd @@ -1,5 +1,9 @@ extends MatchOrientation class_name Face +""" +Calculates angular acceleration to rotate a target to face its target's position. +The acceleration will attempt to arrive with zero remaining angular velocity. +""" func _init(agent: SteeringAgent, target: AgentLocation).(agent, target) -> void: diff --git a/src/Steering/Behaviors/Flee.gd b/src/Steering/Behaviors/Flee.gd index 6e9d286..f3fba43 100644 --- a/src/Steering/Behaviors/Flee.gd +++ b/src/Steering/Behaviors/Flee.gd @@ -1,5 +1,8 @@ extends Seek class_name Flee +""" +Calculates acceleration to take an agent directly away from a target agent. +""" func _init(agent: SteeringAgent, target: AgentLocation).(agent, target) -> void: diff --git a/src/Steering/Behaviors/MatchOrientation.gd b/src/Steering/Behaviors/MatchOrientation.gd index f536bb4..fa7b6ca 100644 --- a/src/Steering/Behaviors/MatchOrientation.gd +++ b/src/Steering/Behaviors/MatchOrientation.gd @@ -1,5 +1,9 @@ extends SteeringBehavior class_name MatchOrientation +""" +Calculates an angular acceleration to match an agent's orientation to its target's. +The calculation will attempt to arrive with zero remaining angular velocity. +""" var target: AgentLocation diff --git a/src/Steering/Behaviors/Pursue.gd b/src/Steering/Behaviors/Pursue.gd index d40ec7f..9124c72 100644 --- a/src/Steering/Behaviors/Pursue.gd +++ b/src/Steering/Behaviors/Pursue.gd @@ -1,5 +1,10 @@ extends SteeringBehavior class_name Pursue +""" +Calculates acceleration to take an agent to intersect with where a target agent will be. + +The `max_predict_time` variable represents how far ahead to calculate the intersection point. +""" var target: SteeringAgent diff --git a/src/Steering/Behaviors/Seek.gd b/src/Steering/Behaviors/Seek.gd index 9f95536..610a6c1 100644 --- a/src/Steering/Behaviors/Seek.gd +++ b/src/Steering/Behaviors/Seek.gd @@ -1,5 +1,8 @@ extends SteeringBehavior class_name Seek +""" +Calculates acceleration to take an agent to a target agent's position as directly as possible +""" var target: AgentLocation diff --git a/src/Steering/Demos/SeekFlee/Boundary.gd b/src/Steering/Demos/SeekFlee/Boundary.gd index a9439e5..7bef08e 100644 --- a/src/Steering/Demos/SeekFlee/Boundary.gd +++ b/src/Steering/Demos/SeekFlee/Boundary.gd @@ -1,4 +1,7 @@ extends StaticBody2D +""" +Draws the bounding box of the static body wall. +""" var rect: Rect2 diff --git a/src/Steering/Demos/SeekFlee/Coward.gd b/src/Steering/Demos/SeekFlee/Coward.gd index f623504..b596ee1 100644 --- a/src/Steering/Demos/SeekFlee/Coward.gd +++ b/src/Steering/Demos/SeekFlee/Coward.gd @@ -1,4 +1,7 @@ extends KinematicBody2D +""" +AI agent that seeks to move away from the player's location as directly as possible. +""" onready var radius: = ($CollisionShape2D.shape as CircleShape2D).radius @@ -25,6 +28,9 @@ func _draw() -> void: func _physics_process(delta: float) -> void: + if not player_agent: + return + _update_agent() accel = flee.calculate_steering(accel) diff --git a/src/Steering/Demos/SeekFlee/Player.gd b/src/Steering/Demos/SeekFlee/Player.gd index 5a7ab70..00ef813 100644 --- a/src/Steering/Demos/SeekFlee/Player.gd +++ b/src/Steering/Demos/SeekFlee/Player.gd @@ -1,4 +1,7 @@ extends KinematicBody2D +""" +Class to control the player in basic left/right up/down movement. +""" onready var _radius: = ($CollisionShape2D.shape as CircleShape2D).radius diff --git a/src/Steering/Demos/SeekFlee/SeekFlee.tscn b/src/Steering/Demos/SeekFlee/SeekFlee.tscn index d191561..09a2cad 100644 --- a/src/Steering/Demos/SeekFlee/SeekFlee.tscn +++ b/src/Steering/Demos/SeekFlee/SeekFlee.tscn @@ -71,10 +71,8 @@ shape = SubResource( 3 ) [node name="SeekerSpawner" type="Node2D" parent="."] script = ExtResource( 2 ) agent_scene = ExtResource( 4 ) -player = NodePath("../Player") [node name="FleeerSpawner" type="Node2D" parent="."] script = ExtResource( 2 ) agent_scene = ExtResource( 6 ) -player = NodePath("../Player") agent_color = Color( 0.0980392, 0.886275, 0.517647, 1 ) diff --git a/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd b/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd index f92ff1d..5f01a2c 100644 --- a/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd +++ b/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd @@ -1,8 +1,14 @@ extends Node2D +""" +Access helper class for children to access window boundaries. +""" var camera_boundaries: Rect2 func _init() -> void: - camera_boundaries = Rect2(Vector2.ZERO, Vector2(ProjectSettings["display/window/size/width"], ProjectSettings["display/window/size/height"])) + camera_boundaries = Rect2( + Vector2.ZERO, + Vector2(ProjectSettings["display/window/size/width"], ProjectSettings["display/window/size/height"]) + ) diff --git a/src/Steering/Demos/SeekFlee/Seeker.gd b/src/Steering/Demos/SeekFlee/Seeker.gd index 759873f..3ec5946 100644 --- a/src/Steering/Demos/SeekFlee/Seeker.gd +++ b/src/Steering/Demos/SeekFlee/Seeker.gd @@ -1,4 +1,7 @@ extends KinematicBody2D +""" +AI agent that uses the Seek behavior to hone in on the player's location as directly as possible. +""" onready var radius: = ($CollisionShape2D.shape as CircleShape2D).radius @@ -25,6 +28,9 @@ func _draw() -> void: func _physics_process(delta: float) -> void: + if not player_agent: + return + _update_agent() accel = seek.calculate_steering(accel) diff --git a/src/Steering/Demos/SeekFlee/Spawner.gd b/src/Steering/Demos/SeekFlee/Spawner.gd index afddacc..e94c5df 100644 --- a/src/Steering/Demos/SeekFlee/Spawner.gd +++ b/src/Steering/Demos/SeekFlee/Spawner.gd @@ -1,12 +1,14 @@ extends Node2D +""" +Instantiates and configures a number of agent scenes within the level boundaries. +""" -onready var player_agent: AgentLocation = get_node(player).player_agent +onready var player_agent: AgentLocation = owner.get_node("Player").player_agent export(PackedScene) var agent_scene: PackedScene export var agent_count: = 10 -export var player: = NodePath() export var min_speed: = 50.0 export var max_speed: = 125.0 export var agent_color: = Color.blue diff --git a/src/Steering/SteeringAgent.gd b/src/Steering/SteeringAgent.gd index 7ad60c8..3f9a06c 100644 --- a/src/Steering/SteeringAgent.gd +++ b/src/Steering/SteeringAgent.gd @@ -1,5 +1,8 @@ extends AgentLocation class_name SteeringAgent +""" +Extended agent data type that adds velocity and speed data. +""" var zero_linear_speed_threshold: = 0.01 diff --git a/src/Steering/SteeringBehavior.gd b/src/Steering/SteeringBehavior.gd index 6d3e8ab..dfb8c54 100644 --- a/src/Steering/SteeringBehavior.gd +++ b/src/Steering/SteeringBehavior.gd @@ -1,5 +1,8 @@ extends Reference class_name SteeringBehavior +""" +Base class to calculate how an AI agent steers itself. +""" var enabled: = true diff --git a/src/Steering/TargetAcceleration.gd b/src/Steering/TargetAcceleration.gd index ccc6472..2a2a937 100644 --- a/src/Steering/TargetAcceleration.gd +++ b/src/Steering/TargetAcceleration.gd @@ -1,5 +1,8 @@ extends Reference class_name TargetAcceleration +""" +A linear and angular amount of acceleration. +""" var linear: = Vector3.ZERO From fb538b72cbc9867f53d0c966b9610e73defbcd83 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Thu, 19 Dec 2019 14:04:08 -0500 Subject: [PATCH 05/23] Reorganize project The GST namespace has been added to prevent class name conflicts, and the project has been reorganized to make extensions and purpose easier. --- mvp.md => docs/mvp.md | 0 techdetails.md => docs/techdetails.md | 0 default_env.tres => project/default_env.tres | 0 .../demos/seek_and_flee}/Boundary.gd | 0 .../demos/seek_and_flee}/Coward.gd | 12 +-- .../demos/seek_and_flee}/Coward.tscn | 2 +- .../demos/seek_and_flee}/Player.gd | 9 +- .../demos/seek_and_flee}/SeekFlee.tscn | 26 ++--- project/demos/seek_and_flee/SeekFleeDemo.gd | 37 +++++++ .../demos/seek_and_flee}/Seeker.gd | 12 +-- .../demos/seek_and_flee}/Seeker.tscn | 2 +- project/demos/seek_and_flee/Spawner.gd | 11 +++ icon.png => project/icon.png | Bin icon.png.import => project/icon.png.import | 0 project.godot => project/project.godot | 90 ++++++++++-------- .../src/GSTAgentLocation.gd | 2 +- .../src/GSTSteeringAgent.gd | 4 +- project/src/GSTSteeringBehavior.gd | 26 +++++ .../src/GSTTargetAcceleration.gd | 5 +- project/src/Utils.gd | 9 ++ project/src/behaviors/GSTArrive.gd | 42 ++++++++ .../src/behaviors/GSTEvade.gd | 11 ++- project/src/behaviors/GSTFace.gd | 26 +++++ project/src/behaviors/GSTFlee.gd | 17 ++++ .../src/behaviors/GSTMatchOrientation.gd | 24 ++--- .../src/behaviors/GSTPursue.gd | 26 ++--- project/src/behaviors/GSTSeek.gd | 20 ++++ root.tscn | 3 - src/Steering/Behaviors/Arrive.gd | 50 ---------- src/Steering/Behaviors/Face.gd | 26 ----- src/Steering/Behaviors/Flee.gd | 16 ---- src/Steering/Behaviors/Seek.gd | 19 ---- src/Steering/Demos/SeekFlee/SeekFleeDemo.gd | 14 --- src/Steering/Demos/SeekFlee/Spawner.gd | 30 ------ src/Steering/SteeringBehavior.gd | 21 ---- 35 files changed, 305 insertions(+), 287 deletions(-) rename mvp.md => docs/mvp.md (100%) rename techdetails.md => docs/techdetails.md (100%) rename default_env.tres => project/default_env.tres (100%) rename {src/Steering/Demos/SeekFlee => project/demos/seek_and_flee}/Boundary.gd (100%) rename {src/Steering/Demos/SeekFlee => project/demos/seek_and_flee}/Coward.gd (82%) rename {src/Steering/Demos/SeekFlee => project/demos/seek_and_flee}/Coward.tscn (76%) rename {src/Steering/Demos/SeekFlee => project/demos/seek_and_flee}/Player.gd (61%) rename {src/Steering/Demos/SeekFlee => project/demos/seek_and_flee}/SeekFlee.tscn (70%) create mode 100644 project/demos/seek_and_flee/SeekFleeDemo.gd rename {src/Steering/Demos/SeekFlee => project/demos/seek_and_flee}/Seeker.gd (82%) rename {src/Steering/Demos/SeekFlee => project/demos/seek_and_flee}/Seeker.tscn (76%) create mode 100644 project/demos/seek_and_flee/Spawner.gd rename icon.png => project/icon.png (100%) rename icon.png.import => project/icon.png.import (100%) rename project.godot => project/project.godot (64%) rename src/Steering/AgentLocation.gd => project/src/GSTAgentLocation.gd (84%) rename src/Steering/SteeringAgent.gd => project/src/GSTSteeringAgent.gd (86%) create mode 100644 project/src/GSTSteeringBehavior.gd rename src/Steering/TargetAcceleration.gd => project/src/GSTTargetAcceleration.gd (69%) create mode 100644 project/src/Utils.gd create mode 100644 project/src/behaviors/GSTArrive.gd rename src/Steering/Behaviors/Evade.gd => project/src/behaviors/GSTEvade.gd (52%) create mode 100644 project/src/behaviors/GSTFace.gd create mode 100644 project/src/behaviors/GSTFlee.gd rename src/Steering/Behaviors/MatchOrientation.gd => project/src/behaviors/GSTMatchOrientation.gd (53%) rename src/Steering/Behaviors/Pursue.gd => project/src/behaviors/GSTPursue.gd (61%) create mode 100644 project/src/behaviors/GSTSeek.gd delete mode 100644 root.tscn delete mode 100644 src/Steering/Behaviors/Arrive.gd delete mode 100644 src/Steering/Behaviors/Face.gd delete mode 100644 src/Steering/Behaviors/Flee.gd delete mode 100644 src/Steering/Behaviors/Seek.gd delete mode 100644 src/Steering/Demos/SeekFlee/SeekFleeDemo.gd delete mode 100644 src/Steering/Demos/SeekFlee/Spawner.gd delete mode 100644 src/Steering/SteeringBehavior.gd diff --git a/mvp.md b/docs/mvp.md similarity index 100% rename from mvp.md rename to docs/mvp.md diff --git a/techdetails.md b/docs/techdetails.md similarity index 100% rename from techdetails.md rename to docs/techdetails.md diff --git a/default_env.tres b/project/default_env.tres similarity index 100% rename from default_env.tres rename to project/default_env.tres diff --git a/src/Steering/Demos/SeekFlee/Boundary.gd b/project/demos/seek_and_flee/Boundary.gd similarity index 100% rename from src/Steering/Demos/SeekFlee/Boundary.gd rename to project/demos/seek_and_flee/Boundary.gd diff --git a/src/Steering/Demos/SeekFlee/Coward.gd b/project/demos/seek_and_flee/Coward.gd similarity index 82% rename from src/Steering/Demos/SeekFlee/Coward.gd rename to project/demos/seek_and_flee/Coward.gd index b596ee1..5434234 100644 --- a/src/Steering/Demos/SeekFlee/Coward.gd +++ b/project/demos/seek_and_flee/Coward.gd @@ -6,21 +6,19 @@ AI agent that seeks to move away from the player's location as directly as possi onready var radius: = ($CollisionShape2D.shape as CircleShape2D).radius -var agent: SteeringAgent -var player_agent: AgentLocation -var flee: Flee -var accel: = TargetAcceleration.new() +onready var agent: = GSTSteeringAgent.new() +onready var accel: = GSTTargetAcceleration.new() +onready var flee: = GSTFlee.new(agent, player_agent) + +var player_agent: GSTAgentLocation var velocity: = Vector2.ZERO var speed: float var color: Color func _ready() -> void: - agent = SteeringAgent.new() agent.max_linear_acceleration = speed/10 agent.max_linear_speed = speed - - flee = Flee.new(agent, player_agent) func _draw() -> void: diff --git a/src/Steering/Demos/SeekFlee/Coward.tscn b/project/demos/seek_and_flee/Coward.tscn similarity index 76% rename from src/Steering/Demos/SeekFlee/Coward.tscn rename to project/demos/seek_and_flee/Coward.tscn index 5240047..b0a2c84 100644 --- a/src/Steering/Demos/SeekFlee/Coward.tscn +++ b/project/demos/seek_and_flee/Coward.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://src/Steering/Demos/SeekFlee/Coward.gd" type="Script" id=1] +[ext_resource path="res://demos/seek_and_flee/Coward.gd" type="Script" id=1] [sub_resource type="CircleShape2D" id=1] diff --git a/src/Steering/Demos/SeekFlee/Player.gd b/project/demos/seek_and_flee/Player.gd similarity index 61% rename from src/Steering/Demos/SeekFlee/Player.gd rename to project/demos/seek_and_flee/Player.gd index 00ef813..4be9822 100644 --- a/src/Steering/Demos/SeekFlee/Player.gd +++ b/project/demos/seek_and_flee/Player.gd @@ -5,19 +5,18 @@ Class to control the player in basic left/right up/down movement. onready var _radius: = ($CollisionShape2D.shape as CircleShape2D).radius +onready var agent: = GSTAgentLocation.new() export var speed: = 150.0 -var player_agent: = AgentLocation.new() - func _draw() -> void: draw_circle(Vector2.ZERO, _radius, Color.red) func _get_movement() -> Vector2: - return Vector2(Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"), - Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up")) + return Vector2( Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"), + Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up")) func _physics_process(delta: float) -> void: @@ -26,4 +25,4 @@ func _physics_process(delta: float) -> void: return move_and_slide(movement * speed) - player_agent.position = Vector3(global_position.x, global_position.y, 0) + agent.position = Vector3(global_position.x, global_position.y, 0) diff --git a/src/Steering/Demos/SeekFlee/SeekFlee.tscn b/project/demos/seek_and_flee/SeekFlee.tscn similarity index 70% rename from src/Steering/Demos/SeekFlee/SeekFlee.tscn rename to project/demos/seek_and_flee/SeekFlee.tscn index 09a2cad..7b9c9b7 100644 --- a/src/Steering/Demos/SeekFlee/SeekFlee.tscn +++ b/project/demos/seek_and_flee/SeekFlee.tscn @@ -1,11 +1,11 @@ [gd_scene load_steps=10 format=2] -[ext_resource path="res://src/Steering/Demos/SeekFlee/Player.gd" type="Script" id=1] -[ext_resource path="res://src/Steering/Demos/SeekFlee/Spawner.gd" type="Script" id=2] -[ext_resource path="res://src/Steering/Demos/SeekFlee/SeekFleeDemo.gd" type="Script" id=3] -[ext_resource path="res://src/Steering/Demos/SeekFlee/Seeker.tscn" type="PackedScene" id=4] -[ext_resource path="res://src/Steering/Demos/SeekFlee/Boundary.gd" type="Script" id=5] -[ext_resource path="res://src/Steering/Demos/SeekFlee/Coward.tscn" type="PackedScene" id=6] +[ext_resource path="res://demos/seek_and_flee/Player.gd" type="Script" id=1] +[ext_resource path="res://demos/seek_and_flee/Spawner.gd" type="Script" id=2] +[ext_resource path="res://demos/seek_and_flee/SeekFleeDemo.gd" type="Script" id=3] +[ext_resource path="res://demos/seek_and_flee/Seeker.tscn" type="PackedScene" id=4] +[ext_resource path="res://demos/seek_and_flee/Boundary.gd" type="Script" id=5] +[ext_resource path="res://demos/seek_and_flee/Coward.tscn" type="PackedScene" id=6] [sub_resource type="CircleShape2D" id=1] radius = 30.0 @@ -68,11 +68,13 @@ script = ExtResource( 5 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="BottomBoundary"] shape = SubResource( 3 ) -[node name="SeekerSpawner" type="Node2D" parent="."] -script = ExtResource( 2 ) -agent_scene = ExtResource( 4 ) +[node name="Spawners" type="Node2D" parent="."] -[node name="FleeerSpawner" type="Node2D" parent="."] +[node name="SeekerSpawner" type="Node2D" parent="Spawners"] script = ExtResource( 2 ) -agent_scene = ExtResource( 6 ) -agent_color = Color( 0.0980392, 0.886275, 0.517647, 1 ) +Entity = ExtResource( 4 ) + +[node name="CowardSpawner" type="Node2D" parent="Spawners"] +script = ExtResource( 2 ) +Entity = ExtResource( 6 ) +entity_color = Color( 0, 1, 0.741176, 1 ) diff --git a/project/demos/seek_and_flee/SeekFleeDemo.gd b/project/demos/seek_and_flee/SeekFleeDemo.gd new file mode 100644 index 0000000..6f589cb --- /dev/null +++ b/project/demos/seek_and_flee/SeekFleeDemo.gd @@ -0,0 +1,37 @@ +extends Node2D +""" +Access helper class for children to access window boundaries. +""" + +onready var player: KinematicBody2D = $Player +onready var spawners: Node2D = $Spawners + +var camera_boundaries: Rect2 + + +func _init() -> void: + camera_boundaries = Rect2( + Vector2.ZERO, + Vector2( + ProjectSettings["display/window/size/width"], + ProjectSettings["display/window/size/height"] + ) + ) + + +func _ready() -> void: + var rng: = RandomNumberGenerator.new() + rng.randomize() + + for spawner in spawners.get_children(): + for i in range(spawner.entity_count): + var new_pos: = Vector2( + rng.randf_range(-camera_boundaries.size.x/2, camera_boundaries.size.x/2), + rng.randf_range(-camera_boundaries.size.y/2, camera_boundaries.size.y/2) + ) + var entity: KinematicBody2D = spawner.Entity.instance() + entity.global_position = new_pos + entity.player_agent = player.agent + entity.speed = rng.randf_range(spawner.min_speed, spawner.max_speed) + entity.color = spawner.entity_color + spawner.add_child(entity) diff --git a/src/Steering/Demos/SeekFlee/Seeker.gd b/project/demos/seek_and_flee/Seeker.gd similarity index 82% rename from src/Steering/Demos/SeekFlee/Seeker.gd rename to project/demos/seek_and_flee/Seeker.gd index 3ec5946..22598a3 100644 --- a/src/Steering/Demos/SeekFlee/Seeker.gd +++ b/project/demos/seek_and_flee/Seeker.gd @@ -6,21 +6,19 @@ AI agent that uses the Seek behavior to hone in on the player's location as dire onready var radius: = ($CollisionShape2D.shape as CircleShape2D).radius -var agent: SteeringAgent -var player_agent: AgentLocation -var seek: Seek -var accel: = TargetAcceleration.new() +onready var agent: = GSTSteeringAgent.new() +onready var accel: = GSTTargetAcceleration.new() +onready var seek: = GSTSeek.new(agent, player_agent) + +var player_agent: GSTAgentLocation var velocity: = Vector2.ZERO var speed: float var color: Color func _ready() -> void: - agent = SteeringAgent.new() agent.max_linear_acceleration = speed/10 agent.max_linear_speed = speed - - seek = Seek.new(agent, player_agent) func _draw() -> void: diff --git a/src/Steering/Demos/SeekFlee/Seeker.tscn b/project/demos/seek_and_flee/Seeker.tscn similarity index 76% rename from src/Steering/Demos/SeekFlee/Seeker.tscn rename to project/demos/seek_and_flee/Seeker.tscn index 4ea2577..511241e 100644 --- a/src/Steering/Demos/SeekFlee/Seeker.tscn +++ b/project/demos/seek_and_flee/Seeker.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://src/Steering/Demos/SeekFlee/Seeker.gd" type="Script" id=1] +[ext_resource path="res://demos/seek_and_flee/Seeker.gd" type="Script" id=1] [sub_resource type="CircleShape2D" id=1] diff --git a/project/demos/seek_and_flee/Spawner.gd b/project/demos/seek_and_flee/Spawner.gd new file mode 100644 index 0000000..6caa254 --- /dev/null +++ b/project/demos/seek_and_flee/Spawner.gd @@ -0,0 +1,11 @@ +extends Node2D +""" +Holds data to instantiate and configure a number of agent entities. +""" + + +export(PackedScene) var Entity: PackedScene +export var entity_count: = 10 +export var entity_color: = Color.blue +export var min_speed: = 50.0 +export var max_speed: = 125.0 diff --git a/icon.png b/project/icon.png similarity index 100% rename from icon.png rename to project/icon.png diff --git a/icon.png.import b/project/icon.png.import similarity index 100% rename from icon.png.import rename to project/icon.png.import diff --git a/project.godot b/project/project.godot similarity index 64% rename from project.godot rename to project/project.godot index 29e0df1..92be641 100644 --- a/project.godot +++ b/project/project.godot @@ -10,77 +10,83 @@ config_version=4 _global_script_classes=[ { "base": "Reference", -"class": "AgentLocation", +"class": "GSTAgentLocation", "language": "GDScript", -"path": "res://src/Steering/AgentLocation.gd" +"path": "res://src/GSTAgentLocation.gd" }, { -"base": "SteeringBehavior", -"class": "Arrive", +"base": "GSTSteeringBehavior", +"class": "GSTArrive", "language": "GDScript", -"path": "res://src/Steering/Behaviors/Arrive.gd" +"path": "res://src/behaviors/GSTArrive.gd" }, { -"base": "Pursue", -"class": "Evade", +"base": "GSTPursue", +"class": "GSTEvade", "language": "GDScript", -"path": "res://src/Steering/Behaviors/Evade.gd" +"path": "res://src/behaviors/GSTEvade.gd" }, { -"base": "MatchOrientation", -"class": "Face", +"base": "GSTMatchOrientation", +"class": "GSTFace", "language": "GDScript", -"path": "res://src/Steering/Behaviors/Face.gd" +"path": "res://src/behaviors/GSTFace.gd" }, { -"base": "Seek", -"class": "Flee", +"base": "GSTSeek", +"class": "GSTFlee", "language": "GDScript", -"path": "res://src/Steering/Behaviors/Flee.gd" +"path": "res://src/behaviors/GSTFlee.gd" }, { -"base": "SteeringBehavior", -"class": "MatchOrientation", +"base": "GSTSteeringBehavior", +"class": "GSTMatchOrientation", "language": "GDScript", -"path": "res://src/Steering/Behaviors/MatchOrientation.gd" +"path": "res://src/behaviors/GSTMatchOrientation.gd" }, { -"base": "SteeringBehavior", -"class": "Pursue", +"base": "GSTSteeringBehavior", +"class": "GSTPursue", "language": "GDScript", -"path": "res://src/Steering/Behaviors/Pursue.gd" +"path": "res://src/behaviors/GSTPursue.gd" }, { -"base": "SteeringBehavior", -"class": "Seek", +"base": "GSTSteeringBehavior", +"class": "GSTSeek", "language": "GDScript", -"path": "res://src/Steering/Behaviors/Seek.gd" +"path": "res://src/behaviors/GSTSeek.gd" }, { -"base": "AgentLocation", -"class": "SteeringAgent", +"base": "GSTAgentLocation", +"class": "GSTSteeringAgent", "language": "GDScript", -"path": "res://src/Steering/SteeringAgent.gd" +"path": "res://src/GSTSteeringAgent.gd" }, { "base": "Reference", -"class": "SteeringBehavior", +"class": "GSTSteeringBehavior", "language": "GDScript", -"path": "res://src/Steering/SteeringBehavior.gd" +"path": "res://src/GSTSteeringBehavior.gd" }, { "base": "Reference", -"class": "TargetAcceleration", +"class": "GSTTargetAcceleration", "language": "GDScript", -"path": "res://src/Steering/TargetAcceleration.gd" +"path": "res://src/GSTTargetAcceleration.gd" +}, { +"base": "Reference", +"class": "Utils", +"language": "GDScript", +"path": "res://src/Utils.gd" } ] _global_script_class_icons={ -"AgentLocation": "", -"Arrive": "", -"Evade": "", -"Face": "", -"Flee": "", -"MatchOrientation": "", -"Pursue": "", -"Seek": "", -"SteeringAgent": "", -"SteeringBehavior": "", -"TargetAcceleration": "" +"GSTAgentLocation": "", +"GSTArrive": "", +"GSTEvade": "", +"GSTFace": "", +"GSTFlee": "", +"GSTMatchOrientation": "", +"GSTPursue": "", +"GSTSeek": "", +"GSTSteeringAgent": "", +"GSTSteeringBehavior": "", +"GSTTargetAcceleration": "", +"Utils": "" } [application] -config/name="godot-steering-toolkit" +config/name="SteeringToolkit" config/icon="res://icon.png" [input] diff --git a/src/Steering/AgentLocation.gd b/project/src/GSTAgentLocation.gd similarity index 84% rename from src/Steering/AgentLocation.gd rename to project/src/GSTAgentLocation.gd index e0cea19..577e878 100644 --- a/src/Steering/AgentLocation.gd +++ b/project/src/GSTAgentLocation.gd @@ -1,5 +1,5 @@ extends Reference -class_name AgentLocation +class_name GSTAgentLocation """ Data type to represent an agent with a location and an orientation """ diff --git a/src/Steering/SteeringAgent.gd b/project/src/GSTSteeringAgent.gd similarity index 86% rename from src/Steering/SteeringAgent.gd rename to project/src/GSTSteeringAgent.gd index 3f9a06c..3a75d02 100644 --- a/src/Steering/SteeringAgent.gd +++ b/project/src/GSTSteeringAgent.gd @@ -1,5 +1,5 @@ -extends AgentLocation -class_name SteeringAgent +extends GSTAgentLocation +class_name GSTSteeringAgent """ Extended agent data type that adds velocity and speed data. """ diff --git a/project/src/GSTSteeringBehavior.gd b/project/src/GSTSteeringBehavior.gd new file mode 100644 index 0000000..9ba6f54 --- /dev/null +++ b/project/src/GSTSteeringBehavior.gd @@ -0,0 +1,26 @@ +extends Reference +class_name GSTSteeringBehavior +""" +Base class to calculate how an AI agent steers itself. +""" + + +var enabled: = true +var agent: GSTSteeringAgent + + +func _init(agent: GSTSteeringAgent) -> void: + self.agent = agent + + +func calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + if enabled: + return _calculate_steering(acceleration) + else: + acceleration.set_zero() + return acceleration + + +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + acceleration.set_zero() + return acceleration diff --git a/src/Steering/TargetAcceleration.gd b/project/src/GSTTargetAcceleration.gd similarity index 69% rename from src/Steering/TargetAcceleration.gd rename to project/src/GSTTargetAcceleration.gd index 2a2a937..6ce7259 100644 --- a/src/Steering/TargetAcceleration.gd +++ b/project/src/GSTTargetAcceleration.gd @@ -1,5 +1,5 @@ extends Reference -class_name TargetAcceleration +class_name GSTTargetAcceleration """ A linear and angular amount of acceleration. """ @@ -9,9 +9,8 @@ var linear: = Vector3.ZERO var angular: = 0.0 -func set_zero() -> TargetAcceleration: +func set_zero() -> void: linear.x = 0.0 linear.y = 0.0 linear.z = 0.0 angular = 0.0 - return self diff --git a/project/src/Utils.gd b/project/src/Utils.gd new file mode 100644 index 0000000..6fad795 --- /dev/null +++ b/project/src/Utils.gd @@ -0,0 +1,9 @@ +class_name Utils + + +static func clmapedv3(vector: Vector3, limit: float) -> Vector3: + var len2: = vector.length_squared() + var limit2: = limit * limit + if len2 > limit2: + vector *= sqrt(limit2 / len2) + return vector diff --git a/project/src/behaviors/GSTArrive.gd b/project/src/behaviors/GSTArrive.gd new file mode 100644 index 0000000..feedcc6 --- /dev/null +++ b/project/src/behaviors/GSTArrive.gd @@ -0,0 +1,42 @@ +extends GSTSteeringBehavior +class_name GSTArrive +""" +Calculates acceleration to take an agent to its target's location. +The calculation will attempt to arrive with zero remaining velocity. +""" + + +var target: GSTAgentLocation +var arrival_tolerance: float +var deceleration_radius: float +var time_to_reach: = 0.1 + + +func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: + self.target = target + + +func _arrive(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration: + var to_target: = target_position - agent.position + var distance: = to_target.length() + + if distance <= arrival_tolerance: + acceleration.set_zero() + else: + var desired_speed: = agent.max_linear_speed + + if distance <= deceleration_radius: + desired_speed *= distance / deceleration_radius + + var desired_velocity: = to_target * desired_speed/distance + + desired_velocity = (desired_velocity - agent.linear_velocity) * 1.0 / time_to_reach + + acceleration.linear = Utils.clampedv3(desired_velocity, agent.max_linear_acceleration) + acceleration.angular = 0 + + return acceleration + + +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + return _arrive(acceleration, target.position) diff --git a/src/Steering/Behaviors/Evade.gd b/project/src/behaviors/GSTEvade.gd similarity index 52% rename from src/Steering/Behaviors/Evade.gd rename to project/src/behaviors/GSTEvade.gd index 091d48d..001069c 100644 --- a/src/Steering/Behaviors/Evade.gd +++ b/project/src/behaviors/GSTEvade.gd @@ -1,5 +1,5 @@ -extends Pursue -class_name Evade +extends GSTPursue +class_name GSTEvade """ Calculates acceleration to take an agent away from where a target agent will be. @@ -7,9 +7,12 @@ The `max_predict_time` variable represents how far ahead to calculate the inters """ -func _init(agent: SteeringAgent, target: SteeringAgent, max_predict_time: = 1.0).(agent, target, max_predict_time): +func _init( + agent: GSTSteeringAgent, + target: GSTSteeringAgent, + max_predict_time: = 1.0).(agent, target, max_predict_time): pass -func get_max_linear_acceleration() -> float: +func _get_modified_acceleration() -> float: return -agent.max_linear_acceleration diff --git a/project/src/behaviors/GSTFace.gd b/project/src/behaviors/GSTFace.gd new file mode 100644 index 0000000..c467bcf --- /dev/null +++ b/project/src/behaviors/GSTFace.gd @@ -0,0 +1,26 @@ +extends GSTMatchOrientation +class_name GSTFace +""" +Calculates angular acceleration to rotate a target to face its target's position. +The acceleration will attempt to arrive with zero remaining angular velocity. +""" + + +func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent, target) -> void: + pass + + +func _face(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration: + var to_target: = target_position - agent.position + var distance_squared: = to_target.length_squared() + + if distance_squared < agent.zero_linear_speed_threshold: + acceleration.set_zero() + return acceleration + else: + var orientation = atan2(to_target.x, -to_target.y) + return _match_orientation(acceleration, orientation) + + +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + return _face(acceleration, target.position) diff --git a/project/src/behaviors/GSTFlee.gd b/project/src/behaviors/GSTFlee.gd new file mode 100644 index 0000000..73208b0 --- /dev/null +++ b/project/src/behaviors/GSTFlee.gd @@ -0,0 +1,17 @@ +extends GSTSeek +class_name GSTFlee +""" +Calculates acceleration to take an agent directly away from a target agent. +""" + + +func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent, target) -> void: + pass + + +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + acceleration.linear = ( + (agent.position - target.position).normalized() * agent.max_linear_acceleration) + acceleration.angular = 0 + + return acceleration diff --git a/src/Steering/Behaviors/MatchOrientation.gd b/project/src/behaviors/GSTMatchOrientation.gd similarity index 53% rename from src/Steering/Behaviors/MatchOrientation.gd rename to project/src/behaviors/GSTMatchOrientation.gd index fa7b6ca..90eaf03 100644 --- a/src/Steering/Behaviors/MatchOrientation.gd +++ b/project/src/behaviors/GSTMatchOrientation.gd @@ -1,37 +1,37 @@ -extends SteeringBehavior -class_name MatchOrientation +extends GSTSteeringBehavior +class_name GSTMatchOrientation """ Calculates an angular acceleration to match an agent's orientation to its target's. The calculation will attempt to arrive with zero remaining angular velocity. """ -var target: AgentLocation +var target: GSTAgentLocation var alignment_tolerance: float var deceleration_radius: float -var time_to_target: float = 0.1 +var time_to_reach: float = 0.1 -func _init(agent: SteeringAgent, target: AgentLocation).(agent) -> void: +func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: self.target = target -func _match_orientation(acceleration: TargetAcceleration, target_orientation: float) -> TargetAcceleration: - var rotation: = wrapf(target_orientation - agent.orientation, -PI, PI) +func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation: float) -> GSTTargetAcceleration: + var rotation: = wrapf(desired_orientation - agent.orientation, -PI, PI) var rotation_size: = -rotation if rotation < 0 else rotation if rotation_size <= alignment_tolerance: return acceleration.set_zero() - var target_rotation: = agent.max_angular_speed + var desired_rotation: = agent.max_angular_speed if rotation_size <= deceleration_radius: - target_rotation *= rotation_size / deceleration_radius + desired_rotation *= rotation_size / deceleration_radius - target_rotation *= rotation / rotation_size + desired_rotation *= rotation / rotation_size - acceleration.angular = (target_rotation - agent.angular_velocity) / time_to_target + acceleration.angular = (desired_rotation - agent.angular_velocity) / time_to_reach var limited_acceleration: = -acceleration.angular if acceleration.angular < 0 else acceleration.angular if limited_acceleration > agent.max_angular_acceleration: @@ -42,5 +42,5 @@ func _match_orientation(acceleration: TargetAcceleration, target_orientation: fl return acceleration -func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: return _match_orientation(acceleration, target.orientation) diff --git a/src/Steering/Behaviors/Pursue.gd b/project/src/behaviors/GSTPursue.gd similarity index 61% rename from src/Steering/Behaviors/Pursue.gd rename to project/src/behaviors/GSTPursue.gd index 9124c72..ccb45f2 100644 --- a/src/Steering/Behaviors/Pursue.gd +++ b/project/src/behaviors/GSTPursue.gd @@ -1,5 +1,5 @@ -extends SteeringBehavior -class_name Pursue +extends GSTSteeringBehavior +class_name GSTPursue """ Calculates acceleration to take an agent to intersect with where a target agent will be. @@ -7,20 +7,19 @@ The `max_predict_time` variable represents how far ahead to calculate the inters """ -var target: SteeringAgent +var target: GSTSteeringAgent var max_predict_time: float -func _init(agent: SteeringAgent, target: SteeringAgent, max_predict_time: = 1.0).(agent) -> void: +func _init( + agent: GSTSteeringAgent, + target: GSTSteeringAgent, + max_predict_time: = 1.0).(agent) -> void: self.target = target self.max_predict_time = max_predict_time -func get_max_linear_acceleration() -> float: - return agent.max_linear_acceleration - - -func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: var target_position: = target.position var distance_squared: = (target_position - agent.position).length_squared() @@ -32,9 +31,14 @@ func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcc if predict_time_squared < max_predict_time * max_predict_time: predict_time = sqrt(predict_time_squared) - acceleration.linear = ((target_position + (target.linear_velocity * predict_time))-agent.position).normalized() - acceleration.linear *= agent.max_linear_acceleration + acceleration.linear = (( + target_position + (target.linear_velocity * predict_time))-agent.position).normalized() + acceleration.linear *= _get_modified_acceleration() acceleration.angular = 0 return acceleration + + +func _get_modified_acceleration() -> float: + return agent.max_linear_acceleration diff --git a/project/src/behaviors/GSTSeek.gd b/project/src/behaviors/GSTSeek.gd new file mode 100644 index 0000000..89a0b3d --- /dev/null +++ b/project/src/behaviors/GSTSeek.gd @@ -0,0 +1,20 @@ +extends GSTSteeringBehavior +class_name GSTSeek +""" +Calculates acceleration to take an agent to a target agent's position as directly as possible +""" + + +var target: GSTAgentLocation + + +func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: + self.target = target + + +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + acceleration.linear = ( + (target.position - agent.position).normalized() * agent.max_linear_acceleration) + acceleration.angular = 0 + + return acceleration diff --git a/root.tscn b/root.tscn deleted file mode 100644 index b171e8d..0000000 --- a/root.tscn +++ /dev/null @@ -1,3 +0,0 @@ -[gd_scene format=2] - -[node name="Node2D" type="Node2D"] diff --git a/src/Steering/Behaviors/Arrive.gd b/src/Steering/Behaviors/Arrive.gd deleted file mode 100644 index e972990..0000000 --- a/src/Steering/Behaviors/Arrive.gd +++ /dev/null @@ -1,50 +0,0 @@ -extends SteeringBehavior -class_name Arrive -""" -Calculates acceleration to take an agent to its target's location. -The calculation will attempt to arrive with zero remaining velocity. -""" - - -var target: AgentLocation -var arrival_tolerance: float -var deceleration_radius: float -var time_to_target: = 0.1 - - -func _init(agent: SteeringAgent, target: AgentLocation).(agent) -> void: - self.target = target - - -func _arrive(acceleration: TargetAcceleration, target_position: Vector3) -> TargetAcceleration: - var to_target: = target_position - agent.position - var distance: = to_target.length() - - if distance <= arrival_tolerance: - return acceleration.set_zero() - - var target_speed: = agent.max_linear_speed - - if distance <= deceleration_radius: - target_speed *= distance / deceleration_radius - - var target_velocity: = to_target * target_speed/distance - - target_velocity = (target_velocity - agent.linear_velocity) * 1.0 / time_to_target - - acceleration.linear = limit_length(target_velocity, agent.max_linear_acceleration) - acceleration.angular = 0 - - return acceleration - - -func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: - return _arrive(acceleration, target.position) - - -static func limit_length(vector: Vector3, limit: float) -> Vector3: - var len2: = vector.length_squared() - var limit2: = limit * limit - if len2 > limit2: - vector *= sqrt(limit2 / len2) - return vector diff --git a/src/Steering/Behaviors/Face.gd b/src/Steering/Behaviors/Face.gd deleted file mode 100644 index e80ee5b..0000000 --- a/src/Steering/Behaviors/Face.gd +++ /dev/null @@ -1,26 +0,0 @@ -extends MatchOrientation -class_name Face -""" -Calculates angular acceleration to rotate a target to face its target's position. -The acceleration will attempt to arrive with zero remaining angular velocity. -""" - - -func _init(agent: SteeringAgent, target: AgentLocation).(agent, target) -> void: - pass - - -func _face(acceleration: TargetAcceleration, target_position: Vector3) -> TargetAcceleration: - var to_target: = target_position - agent.position - - var distance_squared: = to_target.length_squared() - if distance_squared < agent.zero_linear_speed_threshold: - return acceleration.set_zero() - - var orientation = Vector3.UP.angle_to(to_target) - - return _match_orientation(acceleration, orientation) - - -func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: - return _face(acceleration, target.position) diff --git a/src/Steering/Behaviors/Flee.gd b/src/Steering/Behaviors/Flee.gd deleted file mode 100644 index f3fba43..0000000 --- a/src/Steering/Behaviors/Flee.gd +++ /dev/null @@ -1,16 +0,0 @@ -extends Seek -class_name Flee -""" -Calculates acceleration to take an agent directly away from a target agent. -""" - - -func _init(agent: SteeringAgent, target: AgentLocation).(agent, target) -> void: - pass - - -func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: - acceleration.linear = (agent.position - target.position).normalized() * agent.max_linear_acceleration - acceleration.angular = 0 - - return acceleration diff --git a/src/Steering/Behaviors/Seek.gd b/src/Steering/Behaviors/Seek.gd deleted file mode 100644 index 610a6c1..0000000 --- a/src/Steering/Behaviors/Seek.gd +++ /dev/null @@ -1,19 +0,0 @@ -extends SteeringBehavior -class_name Seek -""" -Calculates acceleration to take an agent to a target agent's position as directly as possible -""" - - -var target: AgentLocation - - -func _init(agent: SteeringAgent, target: AgentLocation).(agent) -> void: - self.target = target - - -func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: - acceleration.linear = (target.position - agent.position).normalized() * agent.max_linear_acceleration - acceleration.angular = 0 - - return acceleration diff --git a/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd b/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd deleted file mode 100644 index 5f01a2c..0000000 --- a/src/Steering/Demos/SeekFlee/SeekFleeDemo.gd +++ /dev/null @@ -1,14 +0,0 @@ -extends Node2D -""" -Access helper class for children to access window boundaries. -""" - - -var camera_boundaries: Rect2 - - -func _init() -> void: - camera_boundaries = Rect2( - Vector2.ZERO, - Vector2(ProjectSettings["display/window/size/width"], ProjectSettings["display/window/size/height"]) - ) diff --git a/src/Steering/Demos/SeekFlee/Spawner.gd b/src/Steering/Demos/SeekFlee/Spawner.gd deleted file mode 100644 index e94c5df..0000000 --- a/src/Steering/Demos/SeekFlee/Spawner.gd +++ /dev/null @@ -1,30 +0,0 @@ -extends Node2D -""" -Instantiates and configures a number of agent scenes within the level boundaries. -""" - - -onready var player_agent: AgentLocation = owner.get_node("Player").player_agent - - -export(PackedScene) var agent_scene: PackedScene -export var agent_count: = 10 -export var min_speed: = 50.0 -export var max_speed: = 125.0 -export var agent_color: = Color.blue - - -func _ready() -> void: - var boundaries: Rect2 = owner.camera_boundaries - randomize() - for i in range(agent_count): - var new_pos: = Vector2( - rand_range(-boundaries.size.x/2, boundaries.size.x/2), - rand_range(-boundaries.size.y/2, boundaries.size.y/2) - ) - var agent: = agent_scene.instance() - agent.global_position = new_pos - agent.player_agent = player_agent - agent.speed = rand_range(min_speed, max_speed) - agent.color = agent_color - add_child(agent) diff --git a/src/Steering/SteeringBehavior.gd b/src/Steering/SteeringBehavior.gd deleted file mode 100644 index dfb8c54..0000000 --- a/src/Steering/SteeringBehavior.gd +++ /dev/null @@ -1,21 +0,0 @@ -extends Reference -class_name SteeringBehavior -""" -Base class to calculate how an AI agent steers itself. -""" - - -var enabled: = true -var agent: SteeringAgent - - -func _init(agent: SteeringAgent) -> void: - self.agent = agent - - -func calculate_steering(acceleration: TargetAcceleration) -> TargetAcceleration: - return _calculate_internal_steering(acceleration) if enabled else acceleration.zero() - - -func _calculate_internal_steering(acceleration: TargetAcceleration) -> TargetAcceleration: - return acceleration.set_zero() From f531e835fd75d26ec03ceb5515164a9adee6acf8 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Thu, 19 Dec 2019 15:24:40 -0500 Subject: [PATCH 06/23] Implement LookWhereYouGo, and demo for Pursue --- docs/mvp.md | 1 + .../demos/pursue_vs_seek/BoundaryManager.gd | 68 ++++++++++++ project/demos/pursue_vs_seek/Player.gd | 101 ++++++++++++++++++ .../demos/pursue_vs_seek/PursueVSSeek.tscn | 42 ++++++++ project/demos/pursue_vs_seek/Pursuer.gd | 68 ++++++++++++ project/demos/pursue_vs_seek/Ship.gd | 29 +++++ project/project.godot | 6 ++ project/src/GSTAgentLocation.gd | 1 - project/src/GSTSteeringBehavior.gd | 1 - project/src/GSTTargetAcceleration.gd | 1 - project/src/Utils.gd | 3 + project/src/behaviors/GSTLookWhereYouGo.gd | 18 ++++ project/src/behaviors/GSTMatchOrientation.gd | 28 ++--- 13 files changed, 350 insertions(+), 17 deletions(-) create mode 100644 project/demos/pursue_vs_seek/BoundaryManager.gd create mode 100644 project/demos/pursue_vs_seek/Player.gd create mode 100644 project/demos/pursue_vs_seek/PursueVSSeek.tscn create mode 100644 project/demos/pursue_vs_seek/Pursuer.gd create mode 100644 project/demos/pursue_vs_seek/Ship.gd create mode 100644 project/src/behaviors/GSTLookWhereYouGo.gd diff --git a/docs/mvp.md b/docs/mvp.md index 2e738ff..059d985 100644 --- a/docs/mvp.md +++ b/docs/mvp.md @@ -8,6 +8,7 @@ - Arrive - Pursue/Evade - Face +- LookWhereYouGo - FollowPath - Separation - AvoidCollisions diff --git a/project/demos/pursue_vs_seek/BoundaryManager.gd b/project/demos/pursue_vs_seek/BoundaryManager.gd new file mode 100644 index 0000000..a78469e --- /dev/null +++ b/project/demos/pursue_vs_seek/BoundaryManager.gd @@ -0,0 +1,68 @@ +extends Node2D +""" +Wraps the ships' positions around the world border, and controls their rendering clones. +""" + + +onready var _ships: = [$Player, $Pursuer, $Seeker] +onready var ShipType: = preload("res://demos/pursue_vs_seek/Ship.gd") + +var _clones: = {} +var _world_bounds: Vector2 + + +func _ready() -> void: + _world_bounds = Vector2( + ProjectSettings["display/window/size/width"], + ProjectSettings["display/window/size/height"] + ) + + for i in range(_ships.size()): + var ship: Node2D = _ships[i] + var world_pos: = ship.position + + for i in range(3): + var ship_clone: = ShipType.new($Player/CollisionPolygon2D.polygon) + + ship_clone.position.x = world_pos.x if i == 1 else (world_pos.x - _world_bounds.x) + ship_clone.position.y = world_pos.y if i == 0 else (world_pos.y - _world_bounds.y) + ship_clone.rotation = ship.rotation + ship_clone.color = ship.color + ship_clone.tag = i + + add_child(ship_clone) + _clones[ship_clone] = ship + + +func _physics_process(delta: float) -> void: + for clone in _clones.keys(): + var original: Node2D = _clones[clone] + var world_pos: Vector2 = original.position + + if world_pos.y < 0: + original.position.y = _world_bounds.y + world_pos.y + elif world_pos.y > _world_bounds.y: + original.position.y = (world_pos.y - _world_bounds.y) + + if world_pos.x < 0: + original.position.x = _world_bounds.x + world_pos.x + elif world_pos.x > _world_bounds.x: + original.position.x = (world_pos.x - _world_bounds.x) + + var tag: int = clone.tag + if tag != 2: + if world_pos.x < _world_bounds.x/2: + clone.position.x = world_pos.x + _world_bounds.x + else: + clone.position.x = world_pos.x - _world_bounds.x + else: + clone.position.x = world_pos.x + + if tag != 0: + if world_pos.y < _world_bounds.y/2: + clone.position.y = world_pos.y + _world_bounds.y + else: + clone.position.y = world_pos.y - _world_bounds.y + else: + clone.position.y = world_pos.y + clone.rotation = original.rotation diff --git a/project/demos/pursue_vs_seek/Player.gd b/project/demos/pursue_vs_seek/Player.gd new file mode 100644 index 0000000..111c013 --- /dev/null +++ b/project/demos/pursue_vs_seek/Player.gd @@ -0,0 +1,101 @@ +extends "res://demos/pursue_vs_seek/Ship.gd" +""" +Controls the player ship's movements based on player input. +""" + + +onready var agent: = GSTSteeringAgent.new() + +export var thruster_strength: = 150.0 +export var side_thruster_strength: = 10.0 +export var max_velocity: = 150.0 +export var max_angular_velocity: = 2.0 +export var angular_drag: = 5.0 +export var linear_drag: = 100.0 + +var _linear_velocity: = Vector2() +var _angular_velocity: = 0.0 + + +func _physics_process(delta: float) -> void: + var movement: = _get_movement() + _angular_velocity = _calculate_angular_velocity( + movement.x, + _angular_velocity, + side_thruster_strength, + max_angular_velocity, + angular_drag, + delta + ) + rotation += (_angular_velocity * delta) + + _linear_velocity = _calculate_linear_velocity( + movement.y, + _linear_velocity, + Vector2.UP.rotated(rotation), + linear_drag, + thruster_strength, + max_velocity, + delta + ) + + _linear_velocity = move_and_slide(_linear_velocity) + + _update_agent(_linear_velocity, rotation) + update() + + +func _calculate_angular_velocity( + horizontal_movement: float, + current_velocity: float, + thruster_strength: float, + max_velocity: float, + ship_drag: float, + delta: float) -> float: + + var velocity: = clamp( + current_velocity + thruster_strength * horizontal_movement * delta, + -max_velocity, + max_velocity + ) + + if velocity > 0: + velocity -= ship_drag * delta + elif velocity < 0: + velocity += ship_drag * delta + if abs(velocity) < 0.01: + velocity = 0 + + return velocity + + +func _calculate_linear_velocity( + vertical_movement: float, + current_velocity: Vector2, + facing_direction: Vector2, + ship_drag: float, + strength: float, + max_speed: float, + delta: float) -> Vector2: + + var actual_strength: = 0.0 + if vertical_movement > 0: + actual_strength = strength + elif vertical_movement < 0: + actual_strength = -strength/1.5 + + var velocity: = current_velocity + facing_direction * actual_strength * delta + velocity -= current_velocity.normalized() * (ship_drag * delta) + + return velocity.clamped(max_speed) + + +func _get_movement() -> Vector2: + return Vector2( Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"), + Input.get_action_strength("sf_up") - Input.get_action_strength("sf_down")) + + +func _update_agent(velocity: Vector2, orientation: float) -> void: + agent.position = Vector3(global_position.x, global_position.y, 0) + agent.linear_velocity = Vector3(velocity.x, velocity.y, 0) + agent.orientation = orientation diff --git a/project/demos/pursue_vs_seek/PursueVSSeek.tscn b/project/demos/pursue_vs_seek/PursueVSSeek.tscn new file mode 100644 index 0000000..7f3109b --- /dev/null +++ b/project/demos/pursue_vs_seek/PursueVSSeek.tscn @@ -0,0 +1,42 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://demos/pursue_vs_seek/Pursuer.gd" type="Script" id=1] +[ext_resource path="res://demos/pursue_vs_seek/BoundaryManager.gd" type="Script" id=2] +[ext_resource path="res://demos/pursue_vs_seek/Player.gd" type="Script" id=3] + +[node name="PursueVSSeek" type="Node2D"] +__meta__ = { +"_editor_description_": "Toy demo to demonstrate the use of the Pursue contrasted to the more naive Seek steering behavior." +} + +[node name="BoundaryManager" type="Node2D" parent="."] +script = ExtResource( 2 ) + +[node name="Player" type="KinematicBody2D" parent="BoundaryManager"] +position = Vector2( 49.2031, 556.936 ) +rotation = 1.5708 +collision_mask = 2 +script = ExtResource( 3 ) +color = Color( 1, 0, 0, 1 ) + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Player"] +polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) + +[node name="Pursuer" type="KinematicBody2D" parent="BoundaryManager"] +position = Vector2( 868.495, 87.9043 ) +collision_layer = 2 +script = ExtResource( 1 ) +color = Color( 0.811765, 0.909804, 0.113725, 1 ) + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Pursuer"] +polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) + +[node name="Seeker" type="KinematicBody2D" parent="BoundaryManager"] +position = Vector2( 821.24, 87.9043 ) +collision_layer = 2 +script = ExtResource( 1 ) +color = Color( 0.113725, 0.909804, 0.219608, 1 ) +use_seek = true + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Seeker"] +polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) diff --git a/project/demos/pursue_vs_seek/Pursuer.gd b/project/demos/pursue_vs_seek/Pursuer.gd new file mode 100644 index 0000000..dd4d01b --- /dev/null +++ b/project/demos/pursue_vs_seek/Pursuer.gd @@ -0,0 +1,68 @@ +extends "res://demos/pursue_vs_seek/Ship.gd" +""" +Represents a ship that chases after the player. +""" + + +onready var agent: = GSTSteeringAgent.new() +onready var accel: = GSTTargetAcceleration.new() +onready var player_agent: GSTSteeringAgent = owner.find_node("Player", true, false).agent + +export var use_seek: bool = false + +var _orient_behavior: GSTSteeringBehavior +var _behavior: GSTSteeringBehavior + +var _linear_velocity: = Vector2() +var _angular_velocity: = 0.0 +var _angular_drag: = 1.0 + + +func _ready() -> void: + _setup() + + +func _setup() -> void: + if use_seek: + _behavior = GSTSeek.new(agent, player_agent) + else: + _behavior = GSTPursue.new(agent, player_agent, 2) + + _orient_behavior = GSTLookWhereYouGo.new(agent) + _orient_behavior.alignment_tolerance = 0.001 + _orient_behavior.deceleration_radius = PI/2 + + agent.max_angular_acceleration = 2 + agent.max_angular_speed = 5 + agent.max_linear_acceleration = 120 + agent.max_linear_speed = 200 + _update_agent() + + +func _physics_process(delta: float) -> void: + accel = _orient_behavior.calculate_steering(accel) + _angular_velocity += accel.angular + + if _angular_velocity < 0: + _angular_velocity += _angular_drag * delta + elif _angular_velocity > 0: + _angular_velocity -= _angular_drag * delta + + rotation = rotation + _angular_velocity * delta + + accel = _behavior.calculate_steering(accel) + _linear_velocity = ( + _linear_velocity + Vector2(accel.linear.x, accel.linear.y) * delta).clamped(agent.max_linear_speed) + _linear_velocity -= _linear_velocity * 1 * delta + _linear_velocity = move_and_slide(_linear_velocity) + + _update_agent() + + +func _update_agent() -> void: + agent.position.x = global_position.x + agent.position.y = global_position.y + agent.orientation = rotation + agent.linear_velocity.x = _linear_velocity.x + agent.linear_velocity.y = _linear_velocity.y + agent.angular_velocity = _angular_velocity diff --git a/project/demos/pursue_vs_seek/Ship.gd b/project/demos/pursue_vs_seek/Ship.gd new file mode 100644 index 0000000..5ef0e9c --- /dev/null +++ b/project/demos/pursue_vs_seek/Ship.gd @@ -0,0 +1,29 @@ +extends KinematicBody2D +""" +Draws a notched triangle based on the vertices of the ship's polygon collider. +""" + + +export var color: = Color() + +var tag: int = 0 + +var _vertices: PoolVector2Array +var _colors: PoolColorArray + + +func _init(verts: = PoolVector2Array()) -> void: + _vertices = verts + + +func _ready() -> void: + if not _vertices: + _vertices = $CollisionPolygon2D.polygon + var centroid: = (_vertices[0] + _vertices[1] + _vertices[2])/3 + _vertices.insert(2, centroid) + for i in range(_vertices.size()): + _colors.append(color) + + +func _draw() -> void: + draw_polygon(_vertices, _colors) diff --git a/project/project.godot b/project/project.godot index 92be641..8531524 100644 --- a/project/project.godot +++ b/project/project.godot @@ -34,6 +34,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTFlee.gd" }, { +"base": "GSTMatchOrientation", +"class": "GSTLookWhereYouGo", +"language": "GDScript", +"path": "res://src/behaviors/GSTLookWhereYouGo.gd" +}, { "base": "GSTSteeringBehavior", "class": "GSTMatchOrientation", "language": "GDScript", @@ -75,6 +80,7 @@ _global_script_class_icons={ "GSTEvade": "", "GSTFace": "", "GSTFlee": "", +"GSTLookWhereYouGo": "", "GSTMatchOrientation": "", "GSTPursue": "", "GSTSeek": "", diff --git a/project/src/GSTAgentLocation.gd b/project/src/GSTAgentLocation.gd index 577e878..4e5720e 100644 --- a/project/src/GSTAgentLocation.gd +++ b/project/src/GSTAgentLocation.gd @@ -1,4 +1,3 @@ -extends Reference class_name GSTAgentLocation """ Data type to represent an agent with a location and an orientation diff --git a/project/src/GSTSteeringBehavior.gd b/project/src/GSTSteeringBehavior.gd index 9ba6f54..16177ae 100644 --- a/project/src/GSTSteeringBehavior.gd +++ b/project/src/GSTSteeringBehavior.gd @@ -1,4 +1,3 @@ -extends Reference class_name GSTSteeringBehavior """ Base class to calculate how an AI agent steers itself. diff --git a/project/src/GSTTargetAcceleration.gd b/project/src/GSTTargetAcceleration.gd index 6ce7259..82d7553 100644 --- a/project/src/GSTTargetAcceleration.gd +++ b/project/src/GSTTargetAcceleration.gd @@ -1,4 +1,3 @@ -extends Reference class_name GSTTargetAcceleration """ A linear and angular amount of acceleration. diff --git a/project/src/Utils.gd b/project/src/Utils.gd index 6fad795..07f0181 100644 --- a/project/src/Utils.gd +++ b/project/src/Utils.gd @@ -1,4 +1,7 @@ class_name Utils +""" +Useful math and utility functions to complement Godot's own. +""" static func clmapedv3(vector: Vector3, limit: float) -> Vector3: diff --git a/project/src/behaviors/GSTLookWhereYouGo.gd b/project/src/behaviors/GSTLookWhereYouGo.gd new file mode 100644 index 0000000..26a261b --- /dev/null +++ b/project/src/behaviors/GSTLookWhereYouGo.gd @@ -0,0 +1,18 @@ +extends GSTMatchOrientation +class_name GSTLookWhereYouGo +""" +Calculates an angular acceleration to match an agent's orientation to its direction of travel. +""" + + +func _init(agent: GSTSteeringAgent).(agent, null) -> void: + pass + + +func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration: + if agent.linear_velocity.length_squared() < agent.zero_linear_speed_threshold: + accel.set_zero() + return accel + else: + var orientation: = atan2(agent.linear_velocity.x, -agent.linear_velocity.y) + return _match_orientation(accel, orientation) diff --git a/project/src/behaviors/GSTMatchOrientation.gd b/project/src/behaviors/GSTMatchOrientation.gd index 90eaf03..182eefe 100644 --- a/project/src/behaviors/GSTMatchOrientation.gd +++ b/project/src/behaviors/GSTMatchOrientation.gd @@ -22,23 +22,23 @@ func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation var rotation_size: = -rotation if rotation < 0 else rotation if rotation_size <= alignment_tolerance: - return acceleration.set_zero() + acceleration.set_zero() + else: + var desired_rotation: = agent.max_angular_speed - var desired_rotation: = agent.max_angular_speed - - if rotation_size <= deceleration_radius: - desired_rotation *= rotation_size / deceleration_radius + if rotation_size <= deceleration_radius: + desired_rotation *= rotation_size / deceleration_radius + + desired_rotation *= rotation / rotation_size - desired_rotation *= rotation / rotation_size - - acceleration.angular = (desired_rotation - agent.angular_velocity) / time_to_reach - - var limited_acceleration: = -acceleration.angular if acceleration.angular < 0 else acceleration.angular - if limited_acceleration > agent.max_angular_acceleration: - acceleration.angular *= agent.max_angular_acceleration / limited_acceleration + acceleration.angular = (desired_rotation - agent.angular_velocity) / time_to_reach + + var limited_acceleration: = -acceleration.angular if acceleration.angular < 0 else acceleration.angular + if limited_acceleration > agent.max_angular_acceleration: + acceleration.angular *= agent.max_angular_acceleration / limited_acceleration + + acceleration.linear = Vector3.ZERO - acceleration.linear = Vector3.ZERO - return acceleration From 546d12b15bfd92a3e58d4b85fd3cf2526e97f7ca Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Fri, 20 Dec 2019 13:17:27 -0500 Subject: [PATCH 07/23] Implement demo for Face behavior --- project/demos/face/Face.tscn | 31 +++++++++++ project/demos/face/FaceDemo.gd | 4 ++ project/demos/face/Player.gd | 26 ++++++++++ project/demos/face/Turret.gd | 52 +++++++++++++++++++ .../demos/pursue_vs_seek/PursueVSSeek.tscn | 2 + .../seek_and_flee/{ => Agents}/Coward.tscn | 0 .../seek_and_flee/{ => Agents}/Seeker.tscn | 0 project/demos/seek_and_flee/SeekFlee.tscn | 4 +- project/src/behaviors/GSTMatchOrientation.gd | 4 +- 9 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 project/demos/face/Face.tscn create mode 100644 project/demos/face/FaceDemo.gd create mode 100644 project/demos/face/Player.gd create mode 100644 project/demos/face/Turret.gd rename project/demos/seek_and_flee/{ => Agents}/Coward.tscn (100%) rename project/demos/seek_and_flee/{ => Agents}/Seeker.tscn (100%) diff --git a/project/demos/face/Face.tscn b/project/demos/face/Face.tscn new file mode 100644 index 0000000..4099538 --- /dev/null +++ b/project/demos/face/Face.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=6 format=2] + +[ext_resource path="res://demos/face/Player.gd" type="Script" id=1] +[ext_resource path="res://demos/face/Turret.gd" type="Script" id=2] +[ext_resource path="res://demos/face/FaceDemo.gd" type="Script" id=3] + +[sub_resource type="CircleShape2D" id=1] +radius = 20.0 + +[sub_resource type="CircleShape2D" id=2] +radius = 30.0 + +[node name="Face" type="Node2D"] +script = ExtResource( 3 ) +__meta__ = { +"_editor_description_": "A demo showing the usage of the Face steering behavior." +} + +[node name="Player" type="KinematicBody2D" parent="."] +position = Vector2( 512, 450 ) +script = ExtResource( 1 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] +shape = SubResource( 1 ) + +[node name="Turret" type="KinematicBody2D" parent="."] +position = Vector2( 512, 150 ) +script = ExtResource( 2 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Turret"] +shape = SubResource( 2 ) diff --git a/project/demos/face/FaceDemo.gd b/project/demos/face/FaceDemo.gd new file mode 100644 index 0000000..28ac945 --- /dev/null +++ b/project/demos/face/FaceDemo.gd @@ -0,0 +1,4 @@ +extends Node2D + + +onready var player: = $Player diff --git a/project/demos/face/Player.gd b/project/demos/face/Player.gd new file mode 100644 index 0000000..a453ebb --- /dev/null +++ b/project/demos/face/Player.gd @@ -0,0 +1,26 @@ +extends KinematicBody2D + + +onready var _radius: float = ($CollisionShape2D.shape as CircleShape2D).radius +onready var agent: = GSTAgentLocation.new() + +export var speed: = 125.0 + + +func _draw() -> void: + draw_circle(Vector2.ZERO, _radius, Color.red) + + +func _physics_process(delta: float) -> void: + var movement: = _get_movement() + move_and_slide(movement * speed) + _update_agent() + + +func _get_movement() -> Vector2: + return Vector2( Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"), + Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up")) + + +func _update_agent() -> void: + agent.position = Vector3(global_position.x, global_position.y, 0) diff --git a/project/demos/face/Turret.gd b/project/demos/face/Turret.gd new file mode 100644 index 0000000..5c3760d --- /dev/null +++ b/project/demos/face/Turret.gd @@ -0,0 +1,52 @@ +extends KinematicBody2D + + +onready var _radius: float = ($CollisionShape2D.shape as CircleShape2D).radius +onready var _cannon: = Rect2(Vector2(-5, 0), Vector2(10, -_radius*2)) +onready var _agent: = GSTSteeringAgent.new() +onready var _accel: = GSTTargetAcceleration.new() + + +var _angular_velocity: = 0.0 +var _angular_drag: = 1.0 +var _face: GSTFace + + +func _draw() -> void: + draw_rect(_cannon, Color.blue) + draw_circle(Vector2.ZERO, _radius, Color.teal) + + +func _physics_process(delta: float) -> void: + if not _face: + _setup() + + _accel = _face.calculate_steering(_accel) + _angular_velocity += _accel.angular + + if _angular_velocity < 0: + _angular_velocity += _angular_drag * delta + elif _angular_velocity > 0: + _angular_velocity -= _angular_drag * delta + + rotation += _angular_velocity * delta + + _update_agent() + + +func _update_agent() -> void: + _agent.angular_velocity = _angular_velocity + _agent.orientation = rotation + + +func _setup() -> void: + _face = GSTFace.new(_agent, owner.player.agent) + + _face.alignment_tolerance = 0.1 + _face.deceleration_radius = PI/2 + + _agent.max_angular_acceleration = 0.5 + _agent.max_angular_speed = 5 + _agent.position = Vector3(global_position.x, global_position.y, 0) + + _update_agent() diff --git a/project/demos/pursue_vs_seek/PursueVSSeek.tscn b/project/demos/pursue_vs_seek/PursueVSSeek.tscn index 7f3109b..4942c38 100644 --- a/project/demos/pursue_vs_seek/PursueVSSeek.tscn +++ b/project/demos/pursue_vs_seek/PursueVSSeek.tscn @@ -29,6 +29,7 @@ script = ExtResource( 1 ) color = Color( 0.811765, 0.909804, 0.113725, 1 ) [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Pursuer"] +modulate = Color( 0.694118, 0.694118, 0.694118, 1 ) polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) [node name="Seeker" type="KinematicBody2D" parent="BoundaryManager"] @@ -39,4 +40,5 @@ color = Color( 0.113725, 0.909804, 0.219608, 1 ) use_seek = true [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Seeker"] +modulate = Color( 0.317647, 0.317647, 0.317647, 1 ) polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) diff --git a/project/demos/seek_and_flee/Coward.tscn b/project/demos/seek_and_flee/Agents/Coward.tscn similarity index 100% rename from project/demos/seek_and_flee/Coward.tscn rename to project/demos/seek_and_flee/Agents/Coward.tscn diff --git a/project/demos/seek_and_flee/Seeker.tscn b/project/demos/seek_and_flee/Agents/Seeker.tscn similarity index 100% rename from project/demos/seek_and_flee/Seeker.tscn rename to project/demos/seek_and_flee/Agents/Seeker.tscn diff --git a/project/demos/seek_and_flee/SeekFlee.tscn b/project/demos/seek_and_flee/SeekFlee.tscn index 7b9c9b7..5439a90 100644 --- a/project/demos/seek_and_flee/SeekFlee.tscn +++ b/project/demos/seek_and_flee/SeekFlee.tscn @@ -3,9 +3,9 @@ [ext_resource path="res://demos/seek_and_flee/Player.gd" type="Script" id=1] [ext_resource path="res://demos/seek_and_flee/Spawner.gd" type="Script" id=2] [ext_resource path="res://demos/seek_and_flee/SeekFleeDemo.gd" type="Script" id=3] -[ext_resource path="res://demos/seek_and_flee/Seeker.tscn" type="PackedScene" id=4] +[ext_resource path="res://demos/seek_and_flee/Agents/Seeker.tscn" type="PackedScene" id=4] [ext_resource path="res://demos/seek_and_flee/Boundary.gd" type="Script" id=5] -[ext_resource path="res://demos/seek_and_flee/Coward.tscn" type="PackedScene" id=6] +[ext_resource path="res://demos/seek_and_flee/Agents/Coward.tscn" type="PackedScene" id=6] [sub_resource type="CircleShape2D" id=1] radius = 30.0 diff --git a/project/src/behaviors/GSTMatchOrientation.gd b/project/src/behaviors/GSTMatchOrientation.gd index 182eefe..bf653cf 100644 --- a/project/src/behaviors/GSTMatchOrientation.gd +++ b/project/src/behaviors/GSTMatchOrientation.gd @@ -36,8 +36,8 @@ func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation var limited_acceleration: = -acceleration.angular if acceleration.angular < 0 else acceleration.angular if limited_acceleration > agent.max_angular_acceleration: acceleration.angular *= agent.max_angular_acceleration / limited_acceleration - - acceleration.linear = Vector3.ZERO + + acceleration.linear = Vector3.ZERO return acceleration From b32446217d939204cddf335402a21d406273dbee Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Fri, 20 Dec 2019 21:32:02 -0500 Subject: [PATCH 08/23] Implement demo for Arrive behavior --- project/demos/arrive/Arrive.tscn | 20 ++++++++++++++ project/demos/arrive/ArriveDemo.gd | 8 ++++++ project/demos/arrive/Arriver.gd | 44 ++++++++++++++++++++++++++++++ project/demos/arrive/Target.gd | 14 ++++++++++ project/demos/face/Turret.gd | 1 - project/project.godot | 12 ++++++++ 6 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 project/demos/arrive/Arrive.tscn create mode 100644 project/demos/arrive/ArriveDemo.gd create mode 100644 project/demos/arrive/Arriver.gd create mode 100644 project/demos/arrive/Target.gd diff --git a/project/demos/arrive/Arrive.tscn b/project/demos/arrive/Arrive.tscn new file mode 100644 index 0000000..1b5d194 --- /dev/null +++ b/project/demos/arrive/Arrive.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://demos/arrive/Arriver.gd" type="Script" id=1] +[ext_resource path="res://demos/arrive/ArriveDemo.gd" type="Script" id=2] +[ext_resource path="res://demos/arrive/Target.gd" type="Script" id=3] + +[sub_resource type="CircleShape2D" id=1] +radius = 15.0 + +[node name="Arrive" type="Node2D"] +script = ExtResource( 2 ) + +[node name="Arriver" type="KinematicBody2D" parent="."] +script = ExtResource( 1 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Arriver"] +shape = SubResource( 1 ) + +[node name="Target" type="Node2D" parent="."] +script = ExtResource( 3 ) diff --git a/project/demos/arrive/ArriveDemo.gd b/project/demos/arrive/ArriveDemo.gd new file mode 100644 index 0000000..ab3fe71 --- /dev/null +++ b/project/demos/arrive/ArriveDemo.gd @@ -0,0 +1,8 @@ +extends Node2D + + +onready var _target: = $Target + + +func draw(location: Vector2) -> void: + _target.draw(location) diff --git a/project/demos/arrive/Arriver.gd b/project/demos/arrive/Arriver.gd new file mode 100644 index 0000000..b38fee7 --- /dev/null +++ b/project/demos/arrive/Arriver.gd @@ -0,0 +1,44 @@ +extends KinematicBody2D + + +onready var _radius: float = ($CollisionShape2D.shape as CircleShape2D).radius + +onready var _agent: = GSTSteeringAgent.new() +onready var _target: = GSTAgentLocation.new() +onready var _arrive: = GSTArrive.new(_agent, _target) +onready var _accel: = GSTTargetAcceleration.new() + +var _velocity: = Vector2() +var _drag: = 1.0 + + +func _ready() -> void: + _agent.max_linear_acceleration = 10 + _agent.max_linear_speed = 200 + _arrive.arrival_tolerance = 25 + _arrive.deceleration_radius = 225 + + +func _draw() -> void: + draw_circle(Vector2.ZERO, _radius, Color.red) + + +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventMouseButton: + var mb: InputEventMouseButton = event + if mb.button_index == BUTTON_LEFT and mb.pressed: + _target.position = Vector3(mb.position.x, mb.position.y, 0) + owner.draw(Vector2(_target.position.x, _target.position.y)) + + +func _physics_process(delta: float) -> void: + _accel = _arrive.calculate_steering(_accel) + _velocity += Vector2(_accel.linear.x, _accel.linear.y) + _velocity -= _velocity * _drag * delta + _velocity = move_and_slide(_velocity) + _update_agent() + + +func _update_agent() -> void: + _agent.position = Vector3(global_position.x, global_position.y, 0) + _agent.linear_velocity = Vector3(_velocity.x, _velocity.y, 0) diff --git a/project/demos/arrive/Target.gd b/project/demos/arrive/Target.gd new file mode 100644 index 0000000..831df6c --- /dev/null +++ b/project/demos/arrive/Target.gd @@ -0,0 +1,14 @@ +extends Node2D + + +var target: = Vector2.ZERO + + +func _draw() -> void: + draw_circle(target, 20, Color(1, 1, 0, 0.25)) + draw_circle(target, 5, Color.yellow) + + +func draw(location: Vector2) -> void: + target = location + update() diff --git a/project/demos/face/Turret.gd b/project/demos/face/Turret.gd index 5c3760d..9306eae 100644 --- a/project/demos/face/Turret.gd +++ b/project/demos/face/Turret.gd @@ -6,7 +6,6 @@ onready var _cannon: = Rect2(Vector2(-5, 0), Vector2(10, -_radius*2)) onready var _agent: = GSTSteeringAgent.new() onready var _accel: = GSTTargetAcceleration.new() - var _angular_velocity: = 0.0 var _angular_drag: = 1.0 var _face: GSTFace diff --git a/project/project.godot b/project/project.godot index 8531524..45baf3a 100644 --- a/project/project.godot +++ b/project/project.godot @@ -19,6 +19,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTArrive.gd" }, { +"base": "GSTSteeringBehavior", +"class": "GSTBlend", +"language": "GDScript", +"path": "res://src/behaviors/GSTBlend.gd" +}, { "base": "GSTPursue", "class": "GSTEvade", "language": "GDScript", @@ -45,6 +50,11 @@ _global_script_classes=[ { "path": "res://src/behaviors/GSTMatchOrientation.gd" }, { "base": "GSTSteeringBehavior", +"class": "GSTPriority", +"language": "GDScript", +"path": "res://src/behaviors/GSTPriority.gd" +}, { +"base": "GSTSteeringBehavior", "class": "GSTPursue", "language": "GDScript", "path": "res://src/behaviors/GSTPursue.gd" @@ -77,11 +87,13 @@ _global_script_classes=[ { _global_script_class_icons={ "GSTAgentLocation": "", "GSTArrive": "", +"GSTBlend": "", "GSTEvade": "", "GSTFace": "", "GSTFlee": "", "GSTLookWhereYouGo": "", "GSTMatchOrientation": "", +"GSTPriority": "", "GSTPursue": "", "GSTSeek": "", "GSTSteeringAgent": "", From 3e9ce641fb9f4c8ae963aea9e49bfb3d30c17521 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Fri, 20 Dec 2019 21:32:21 -0500 Subject: [PATCH 09/23] Add Blend and Priority behaviors --- project/src/GSTTargetAcceleration.gd | 13 +++++++ project/src/Utils.gd | 2 +- project/src/behaviors/GSTBlend.gd | 53 ++++++++++++++++++++++++++++ project/src/behaviors/GSTPriority.gd | 48 +++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 project/src/behaviors/GSTBlend.gd create mode 100644 project/src/behaviors/GSTPriority.gd diff --git a/project/src/GSTTargetAcceleration.gd b/project/src/GSTTargetAcceleration.gd index 82d7553..180f7f7 100644 --- a/project/src/GSTTargetAcceleration.gd +++ b/project/src/GSTTargetAcceleration.gd @@ -13,3 +13,16 @@ func set_zero() -> void: linear.y = 0.0 linear.z = 0.0 angular = 0.0 + + +func add_scaled_accel(accel: GSTTargetAcceleration, scalar: float) -> void: + linear += accel.linear * scalar + angular += accel.angular * scalar + + +func get_squared_magnitude() -> float: + return linear.length_squared() + angular * angular + + +func get_magnitude() -> float: + return sqrt(get_squared_magnitude()) diff --git a/project/src/Utils.gd b/project/src/Utils.gd index 07f0181..fa2a4e5 100644 --- a/project/src/Utils.gd +++ b/project/src/Utils.gd @@ -4,7 +4,7 @@ Useful math and utility functions to complement Godot's own. """ -static func clmapedv3(vector: Vector3, limit: float) -> Vector3: +static func clampedv3(vector: Vector3, limit: float) -> Vector3: var len2: = vector.length_squared() var limit2: = limit * limit if len2 > limit2: diff --git a/project/src/behaviors/GSTBlend.gd b/project/src/behaviors/GSTBlend.gd new file mode 100644 index 0000000..de1783d --- /dev/null +++ b/project/src/behaviors/GSTBlend.gd @@ -0,0 +1,53 @@ +extends GSTSteeringBehavior +class_name GSTBlend +""" +Blends multiple steering behaviors into one, and returns acceleration combining all of them. + +Each behavior is associated with a weight - a modifier by which the result will be multiplied by, +then added to a total acceleration. +""" + + +onready var _behaviors: = [] +onready var _accel: = GSTTargetAcceleration.new() + + +func _init(agent: GSTSteeringAgent).(agent) -> void: + pass + + +func add(behavior: GSTSteeringBehavior, weight: float) -> void: + behavior.agent = agent + _behaviors.append(GSTBehaviorAndWeight.new(behavior, weight)) + + +func get_behavior_at(index: int) -> GSTBehaviorAndWeight: + if _behaviors.size() > index: + return _behaviors[index] + printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size())) + return null + + +func _calculate_steering(blended_accel: GSTTargetAcceleration) -> GSTTargetAcceleration: + blended_accel.set_zero() + + for i in range(_behaviors.size()): + var bw: GSTBehaviorAndWeight = _behaviors[i] + bw.behavior.calculate_steering(_accel) + + blended_accel.add_scaled_accel(_accel, bw.weight) + + blended_accel.linear = Utils.clampedv3(blended_accel.linear, agent.max_linear_acceleration) + if blended_accel.angular > agent.max_angular_acceleration: + blended_accel.angular = agent.max_angular_acceleration + + return blended_accel + + +class GSTBehaviorAndWeight: + var behavior: GSTSteeringBehavior + var weight: float + + func _init(behavior: GSTSteeringBehavior, weight: float) -> void: + self.behavior = behavior + self.weight = weight diff --git a/project/src/behaviors/GSTPriority.gd b/project/src/behaviors/GSTPriority.gd new file mode 100644 index 0000000..3f5a867 --- /dev/null +++ b/project/src/behaviors/GSTPriority.gd @@ -0,0 +1,48 @@ +extends GSTSteeringBehavior +class_name GSTPriority +""" +Contains multiple steering behaviors and returns only the result of the first that has a non-zero + acceleration. +""" + + +onready var _behaviors: = [] + +var last_selected_index: int +var threshold_for_zero: float + + +func _init(agent: GSTSteeringAgent, threshold_for_zero: = 0.001).(agent) -> void: + self.threshold_for_zero = threshold_for_zero + + +func add(behavior: GSTSteeringBehavior) -> void: + _behaviors.append(behavior) + + +func get_behavior_at(index: int) -> GSTSteeringBehavior: + if _behaviors.size() > index: + return _behaviors[index] + printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size())) + return null + + +func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration: + var threshold_squared: = threshold_for_zero * threshold_for_zero + + last_selected_index = -1 + + var size: = _behaviors.size() + + if size > 0: + for i in range(size): + last_selected_index = i + var behavior: GSTSteeringBehavior = _behaviors[i] + behavior.calculate_steering(accel) + + if accel.get_squared_magnitude() > threshold_squared: + break + else: + accel.set_zero() + + return accel From 3d50dcdb9cca497c11868b36a609bd583150b623 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Sat, 21 Dec 2019 13:07:43 -0500 Subject: [PATCH 10/23] Add GUI controls to seek/flee demo Being toy demos, they should be easily tweakable and modifiable by the user to get a feel for what the parameters of the behaviors do. --- .../demos/seek_and_flee/Agents/Coward.tscn | 13 --- project/demos/seek_and_flee/Coward.gd | 42 -------- project/demos/seek_and_flee/GUI.gd | 28 ++++++ project/demos/seek_and_flee/GUI.tscn | 95 +++++++++++++++++++ project/demos/seek_and_flee/SeekFlee.tscn | 19 ++-- project/demos/seek_and_flee/SeekFleeDemo.gd | 28 +++--- project/demos/seek_and_flee/Seeker.gd | 11 ++- .../seek_and_flee/{Agents => }/Seeker.tscn | 2 + 8 files changed, 159 insertions(+), 79 deletions(-) delete mode 100644 project/demos/seek_and_flee/Agents/Coward.tscn delete mode 100644 project/demos/seek_and_flee/Coward.gd create mode 100644 project/demos/seek_and_flee/GUI.gd create mode 100644 project/demos/seek_and_flee/GUI.tscn rename project/demos/seek_and_flee/{Agents => }/Seeker.tscn (99%) diff --git a/project/demos/seek_and_flee/Agents/Coward.tscn b/project/demos/seek_and_flee/Agents/Coward.tscn deleted file mode 100644 index b0a2c84..0000000 --- a/project/demos/seek_and_flee/Agents/Coward.tscn +++ /dev/null @@ -1,13 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://demos/seek_and_flee/Coward.gd" type="Script" id=1] - -[sub_resource type="CircleShape2D" id=1] - -[node name="Coward" type="KinematicBody2D"] -collision_layer = 4 -collision_mask = 6 -script = ExtResource( 1 ) - -[node name="CollisionShape2D" type="CollisionShape2D" parent="."] -shape = SubResource( 1 ) diff --git a/project/demos/seek_and_flee/Coward.gd b/project/demos/seek_and_flee/Coward.gd deleted file mode 100644 index 5434234..0000000 --- a/project/demos/seek_and_flee/Coward.gd +++ /dev/null @@ -1,42 +0,0 @@ -extends KinematicBody2D -""" -AI agent that seeks to move away from the player's location as directly as possible. -""" - - -onready var radius: = ($CollisionShape2D.shape as CircleShape2D).radius - -onready var agent: = GSTSteeringAgent.new() -onready var accel: = GSTTargetAcceleration.new() -onready var flee: = GSTFlee.new(agent, player_agent) - -var player_agent: GSTAgentLocation -var velocity: = Vector2.ZERO -var speed: float -var color: Color - - -func _ready() -> void: - agent.max_linear_acceleration = speed/10 - agent.max_linear_speed = speed - - -func _draw() -> void: - draw_circle(Vector2.ZERO, radius, color) - - -func _physics_process(delta: float) -> void: - if not player_agent: - return - - _update_agent() - accel = flee.calculate_steering(accel) - - velocity = (velocity + Vector2(accel.linear.x, accel.linear.y)).clamped(agent.max_linear_speed) - velocity = move_and_slide(velocity) - if velocity.length_squared() > 0: - update() - - -func _update_agent() -> void: - agent.position = Vector3(global_position.x, global_position.y, 0) diff --git a/project/demos/seek_and_flee/GUI.gd b/project/demos/seek_and_flee/GUI.gd new file mode 100644 index 0000000..ae83330 --- /dev/null +++ b/project/demos/seek_and_flee/GUI.gd @@ -0,0 +1,28 @@ +extends MarginContainer + + +enum BehaviorMode { SEEK, FLEE } + +signal mode_changed(behavior_mode) + +onready var seek: CheckBox = $BehaviorControls/Seek +onready var flee: CheckBox = $BehaviorControls/Flee + + +func _ready() -> void: + seek.connect("pressed", self, "_on_Seek_pressed") + flee.connect("pressed", self, "_on_Flee_pressed") + + +func _on_Seek_pressed() -> void: + flee.pressed = false + flee.button_mask = BUTTON_MASK_LEFT + seek.button_mask = 0 + emit_signal("mode_changed", BehaviorMode.SEEK) + + +func _on_Flee_pressed() -> void: + seek.pressed = false + seek.button_mask = BUTTON_MASK_LEFT + flee.button_mask = 0 + emit_signal("mode_changed", BehaviorMode.FLEE) diff --git a/project/demos/seek_and_flee/GUI.tscn b/project/demos/seek_and_flee/GUI.tscn new file mode 100644 index 0000000..9ad06ae --- /dev/null +++ b/project/demos/seek_and_flee/GUI.tscn @@ -0,0 +1,95 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://demos/seek_and_flee/GUI.gd" type="Script" id=3] + +[node name="GUI" type="MarginContainer"] +anchor_bottom = 1.0 +margin_right = 116.0 +custom_constants/margin_right = 20 +custom_constants/margin_top = 20 +custom_constants/margin_left = 20 +custom_constants/margin_bottom = 20 +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="BehaviorControls" type="VBoxContainer" parent="."] +margin_left = 20.0 +margin_top = 20.0 +margin_right = 102.0 +margin_bottom = 580.0 + +[node name="Seek" type="CheckBox" parent="BehaviorControls"] +margin_right = 82.0 +margin_bottom = 24.0 +focus_mode = 0 +pressed = true +enabled_focus_mode = 0 +text = "Seek" + +[node name="Flee" type="CheckBox" parent="BehaviorControls"] +margin_top = 28.0 +margin_right = 82.0 +margin_bottom = 52.0 +focus_mode = 0 +enabled_focus_mode = 0 +text = "Flee" + +[node name="Help" type="VBoxContainer" parent="BehaviorControls"] +margin_top = 56.0 +margin_right = 82.0 +margin_bottom = 108.0 + +[node name="Controls" type="Label" parent="BehaviorControls/Help"] +margin_right = 82.0 +margin_bottom = 14.0 +text = "Controls" + +[node name="GridContainer" type="GridContainer" parent="BehaviorControls/Help"] +margin_top = 18.0 +margin_right = 82.0 +margin_bottom = 52.0 +columns = 3 + +[node name="Sep" type="Control" parent="BehaviorControls/Help/GridContainer"] +margin_right = 15.0 +margin_bottom = 15.0 +rect_min_size = Vector2( 15, 15 ) + +[node name="W" type="Label" parent="BehaviorControls/Help/GridContainer"] +margin_left = 19.0 +margin_top = -1.0 +margin_right = 34.0 +margin_bottom = 14.0 +rect_min_size = Vector2( 15, 15 ) +text = "W" + +[node name="Sep2" type="Control" parent="BehaviorControls/Help/GridContainer"] +margin_left = 38.0 +margin_right = 53.0 +margin_bottom = 15.0 +rect_min_size = Vector2( 15, 15 ) + +[node name="A" type="Label" parent="BehaviorControls/Help/GridContainer"] +margin_top = 18.0 +margin_right = 15.0 +margin_bottom = 33.0 +rect_min_size = Vector2( 15, 15 ) +text = "A" + +[node name="S" type="Label" parent="BehaviorControls/Help/GridContainer"] +margin_left = 19.0 +margin_top = 18.0 +margin_right = 34.0 +margin_bottom = 33.0 +rect_min_size = Vector2( 15, 15 ) +text = "S" + +[node name="D" type="Label" parent="BehaviorControls/Help/GridContainer"] +margin_left = 38.0 +margin_top = 18.0 +margin_right = 53.0 +margin_bottom = 33.0 +rect_min_size = Vector2( 15, 15 ) +text = "D" diff --git a/project/demos/seek_and_flee/SeekFlee.tscn b/project/demos/seek_and_flee/SeekFlee.tscn index 5439a90..7183345 100644 --- a/project/demos/seek_and_flee/SeekFlee.tscn +++ b/project/demos/seek_and_flee/SeekFlee.tscn @@ -3,9 +3,9 @@ [ext_resource path="res://demos/seek_and_flee/Player.gd" type="Script" id=1] [ext_resource path="res://demos/seek_and_flee/Spawner.gd" type="Script" id=2] [ext_resource path="res://demos/seek_and_flee/SeekFleeDemo.gd" type="Script" id=3] -[ext_resource path="res://demos/seek_and_flee/Agents/Seeker.tscn" type="PackedScene" id=4] +[ext_resource path="res://demos/seek_and_flee/Seeker.tscn" type="PackedScene" id=4] [ext_resource path="res://demos/seek_and_flee/Boundary.gd" type="Script" id=5] -[ext_resource path="res://demos/seek_and_flee/Agents/Coward.tscn" type="PackedScene" id=6] +[ext_resource path="res://demos/seek_and_flee/GUI.tscn" type="PackedScene" id=7] [sub_resource type="CircleShape2D" id=1] radius = 30.0 @@ -22,6 +22,12 @@ __meta__ = { "_editor_description_": "A toy demo to demonstrate the usage for the Seek and Flee steering behaviors." } +[node name="GUI" parent="." instance=ExtResource( 7 )] +margin_left = -512.0 +margin_top = -300.0 +margin_right = -414.0 +margin_bottom = -208.0 + [node name="Camera2D" type="Camera2D" parent="."] current = true @@ -68,13 +74,6 @@ script = ExtResource( 5 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="BottomBoundary"] shape = SubResource( 3 ) -[node name="Spawners" type="Node2D" parent="."] - -[node name="SeekerSpawner" type="Node2D" parent="Spawners"] +[node name="Spawner" type="Node2D" parent="."] script = ExtResource( 2 ) Entity = ExtResource( 4 ) - -[node name="CowardSpawner" type="Node2D" parent="Spawners"] -script = ExtResource( 2 ) -Entity = ExtResource( 6 ) -entity_color = Color( 0, 1, 0.741176, 1 ) diff --git a/project/demos/seek_and_flee/SeekFleeDemo.gd b/project/demos/seek_and_flee/SeekFleeDemo.gd index 6f589cb..c1965f5 100644 --- a/project/demos/seek_and_flee/SeekFleeDemo.gd +++ b/project/demos/seek_and_flee/SeekFleeDemo.gd @@ -3,8 +3,10 @@ extends Node2D Access helper class for children to access window boundaries. """ + onready var player: KinematicBody2D = $Player -onready var spawners: Node2D = $Spawners +onready var spawner: Node2D = $Spawner +onready var _gui: = $GUI var camera_boundaries: Rect2 @@ -23,15 +25,15 @@ func _ready() -> void: var rng: = RandomNumberGenerator.new() rng.randomize() - for spawner in spawners.get_children(): - for i in range(spawner.entity_count): - var new_pos: = Vector2( - rng.randf_range(-camera_boundaries.size.x/2, camera_boundaries.size.x/2), - rng.randf_range(-camera_boundaries.size.y/2, camera_boundaries.size.y/2) - ) - var entity: KinematicBody2D = spawner.Entity.instance() - entity.global_position = new_pos - entity.player_agent = player.agent - entity.speed = rng.randf_range(spawner.min_speed, spawner.max_speed) - entity.color = spawner.entity_color - spawner.add_child(entity) + for i in range(spawner.entity_count): + var new_pos: = Vector2( + rng.randf_range(-camera_boundaries.size.x/2, camera_boundaries.size.x/2), + rng.randf_range(-camera_boundaries.size.y/2, camera_boundaries.size.y/2) + ) + var entity: KinematicBody2D = spawner.Entity.instance() + entity.global_position = new_pos + entity.player_agent = player.agent + entity.speed = rng.randf_range(spawner.min_speed, spawner.max_speed) + entity.color = spawner.entity_color + _gui.connect("mode_changed", entity, "_on_GUI_mode_changed") + spawner.add_child(entity) diff --git a/project/demos/seek_and_flee/Seeker.gd b/project/demos/seek_and_flee/Seeker.gd index 22598a3..8c8b2a0 100644 --- a/project/demos/seek_and_flee/Seeker.gd +++ b/project/demos/seek_and_flee/Seeker.gd @@ -9,6 +9,8 @@ onready var radius: = ($CollisionShape2D.shape as CircleShape2D).radius onready var agent: = GSTSteeringAgent.new() onready var accel: = GSTTargetAcceleration.new() onready var seek: = GSTSeek.new(agent, player_agent) +onready var flee: = GSTFlee.new(agent, player_agent) +onready var _active_behavior: = seek var player_agent: GSTAgentLocation var velocity: = Vector2.ZERO @@ -30,7 +32,7 @@ func _physics_process(delta: float) -> void: return _update_agent() - accel = seek.calculate_steering(accel) + accel = _active_behavior.calculate_steering(accel) velocity = (velocity + Vector2(accel.linear.x, accel.linear.y)).clamped(agent.max_linear_speed) velocity = move_and_slide(velocity) @@ -40,3 +42,10 @@ func _physics_process(delta: float) -> void: func _update_agent() -> void: agent.position = Vector3(global_position.x, global_position.y, 0) + + +func _on_GUI_mode_changed(mode: int) -> void: + if mode == 0: + _active_behavior = seek + else: + _active_behavior = flee diff --git a/project/demos/seek_and_flee/Agents/Seeker.tscn b/project/demos/seek_and_flee/Seeker.tscn similarity index 99% rename from project/demos/seek_and_flee/Agents/Seeker.tscn rename to project/demos/seek_and_flee/Seeker.tscn index 511241e..804897a 100644 --- a/project/demos/seek_and_flee/Agents/Seeker.tscn +++ b/project/demos/seek_and_flee/Seeker.tscn @@ -2,6 +2,8 @@ [ext_resource path="res://demos/seek_and_flee/Seeker.gd" type="Script" id=1] + + [sub_resource type="CircleShape2D" id=1] [node name="Seeker" type="KinematicBody2D"] From fc0b36ff224020847aa5ecb30f56ad2e5777447f Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Sat, 21 Dec 2019 15:20:06 -0500 Subject: [PATCH 11/23] Add GUI to Pursue demo --- project/demos/pursue_vs_seek/GUI.gd | 30 ++++ project/demos/pursue_vs_seek/GUI.tscn | 132 ++++++++++++++++++ .../demos/pursue_vs_seek/PursueVSSeek.tscn | 7 +- .../demos/pursue_vs_seek/PursueVSSeekDemo.gd | 23 +++ project/demos/pursue_vs_seek/Pursuer.gd | 10 +- project/demos/seek_and_flee/GUI.tscn | 31 ++-- 6 files changed, 213 insertions(+), 20 deletions(-) create mode 100644 project/demos/pursue_vs_seek/GUI.gd create mode 100644 project/demos/pursue_vs_seek/GUI.tscn create mode 100644 project/demos/pursue_vs_seek/PursueVSSeekDemo.gd diff --git a/project/demos/pursue_vs_seek/GUI.gd b/project/demos/pursue_vs_seek/GUI.gd new file mode 100644 index 0000000..77c06e3 --- /dev/null +++ b/project/demos/pursue_vs_seek/GUI.gd @@ -0,0 +1,30 @@ +extends MarginContainer + + +signal linear_speed_changed(value) +signal linear_accel_changed(value) + + +onready var linear_speed: = $Controls/LinSpeed/LineEdit +onready var linear_accel: = $Controls/LinAccel/LineEdit + + +func _ready() -> void: + linear_speed.connect("text_changed", self, "_on_LineText_linear_speed_changed") + linear_accel.connect("text_changed", self, "_on_LineText_linear_accel_changed") + + +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventMouseButton: + linear_speed.release_focus() + linear_accel.release_focus() + + +func _on_LineText_linear_speed_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("linear_speed_changed", int(float(new_text))) + + +func _on_LineText_linear_accel_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("linear_accel_changed", int(float(new_text))) diff --git a/project/demos/pursue_vs_seek/GUI.tscn b/project/demos/pursue_vs_seek/GUI.tscn new file mode 100644 index 0000000..f339484 --- /dev/null +++ b/project/demos/pursue_vs_seek/GUI.tscn @@ -0,0 +1,132 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://demos/pursue_vs_seek/GUI.gd" type="Script" id=1] + +[node name="GUI" type="MarginContainer"] +anchor_bottom = 1.0 +custom_constants/margin_right = 20 +custom_constants/margin_top = 20 +custom_constants/margin_left = 20 +custom_constants/margin_bottom = 20 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Controls" type="VBoxContainer" parent="."] +margin_left = 20.0 +margin_top = 20.0 +margin_right = 241.0 +margin_bottom = 580.0 + +[node name="LinSpeed" type="HBoxContainer" parent="Controls"] +margin_right = 221.0 +margin_bottom = 25.0 +custom_constants/separation = 10 + +[node name="Label" type="Label" parent="Controls/LinSpeed"] +margin_right = 153.0 +margin_bottom = 25.0 +rect_min_size = Vector2( 153, 25 ) +text = "Max Linear Speed" +valign = 1 + +[node name="LineEdit" type="LineEdit" parent="Controls/LinSpeed"] +margin_left = 163.0 +margin_right = 221.0 +margin_bottom = 25.0 +rect_min_size = Vector2( 0, 25 ) +focus_mode = 1 +text = "200" +context_menu_enabled = false +shortcut_keys_enabled = false +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="LinAccel" type="HBoxContainer" parent="Controls"] +margin_top = 29.0 +margin_right = 221.0 +margin_bottom = 54.0 +custom_constants/separation = 10 + +[node name="Label" type="Label" parent="Controls/LinAccel"] +margin_right = 153.0 +margin_bottom = 25.0 +rect_min_size = Vector2( 153, 25 ) +text = "Max Linear Acceleration" +valign = 1 + +[node name="LineEdit" type="LineEdit" parent="Controls/LinAccel"] +margin_left = 163.0 +margin_right = 221.0 +margin_bottom = 25.0 +rect_min_size = Vector2( 0, 25 ) +focus_mode = 1 +text = "120" +context_menu_enabled = false +shortcut_keys_enabled = false +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Help" type="VBoxContainer" parent="Controls"] +margin_top = 58.0 +margin_right = 221.0 +margin_bottom = 110.0 + +[node name="Controls" type="Label" parent="Controls/Help"] +margin_right = 221.0 +margin_bottom = 14.0 +text = "Controls" + +[node name="GridContainer" type="GridContainer" parent="Controls/Help"] +margin_top = 18.0 +margin_right = 221.0 +margin_bottom = 52.0 +columns = 3 + +[node name="Sep" type="Control" parent="Controls/Help/GridContainer"] +margin_right = 15.0 +margin_bottom = 15.0 +rect_min_size = Vector2( 15, 15 ) + +[node name="W" type="Label" parent="Controls/Help/GridContainer"] +margin_left = 19.0 +margin_right = 34.0 +margin_bottom = 15.0 +rect_min_size = Vector2( 15, 15 ) +text = "W" +align = 1 + +[node name="Sep2" type="Control" parent="Controls/Help/GridContainer"] +margin_left = 38.0 +margin_right = 53.0 +margin_bottom = 15.0 +rect_min_size = Vector2( 15, 15 ) + +[node name="A" type="Label" parent="Controls/Help/GridContainer"] +margin_top = 19.0 +margin_right = 15.0 +margin_bottom = 34.0 +rect_min_size = Vector2( 15, 15 ) +text = "A" +align = 1 + +[node name="S" type="Label" parent="Controls/Help/GridContainer"] +margin_left = 19.0 +margin_top = 19.0 +margin_right = 34.0 +margin_bottom = 34.0 +rect_min_size = Vector2( 15, 15 ) +text = "S" +align = 1 + +[node name="D" type="Label" parent="Controls/Help/GridContainer"] +margin_left = 38.0 +margin_top = 19.0 +margin_right = 53.0 +margin_bottom = 34.0 +rect_min_size = Vector2( 15, 15 ) +text = "D" +align = 1 diff --git a/project/demos/pursue_vs_seek/PursueVSSeek.tscn b/project/demos/pursue_vs_seek/PursueVSSeek.tscn index 4942c38..c60f216 100644 --- a/project/demos/pursue_vs_seek/PursueVSSeek.tscn +++ b/project/demos/pursue_vs_seek/PursueVSSeek.tscn @@ -1,14 +1,19 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://demos/pursue_vs_seek/Pursuer.gd" type="Script" id=1] [ext_resource path="res://demos/pursue_vs_seek/BoundaryManager.gd" type="Script" id=2] [ext_resource path="res://demos/pursue_vs_seek/Player.gd" type="Script" id=3] +[ext_resource path="res://demos/pursue_vs_seek/GUI.tscn" type="PackedScene" id=4] +[ext_resource path="res://demos/pursue_vs_seek/PursueVSSeekDemo.gd" type="Script" id=5] [node name="PursueVSSeek" type="Node2D"] +script = ExtResource( 5 ) __meta__ = { "_editor_description_": "Toy demo to demonstrate the use of the Pursue contrasted to the more naive Seek steering behavior." } +[node name="GUI" parent="." instance=ExtResource( 4 )] + [node name="BoundaryManager" type="Node2D" parent="."] script = ExtResource( 2 ) diff --git a/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd b/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd new file mode 100644 index 0000000..5683ea3 --- /dev/null +++ b/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd @@ -0,0 +1,23 @@ +extends Node2D + + +onready var _gui: = $GUI +onready var _pursuer: = $BoundaryManager/Pursuer +onready var _seeker: = $BoundaryManager/Seeker + + +func _ready() -> void: + _gui.linear_speed.text = str(_pursuer.agent.max_linear_speed) + _gui.linear_accel.text = str(_pursuer.agent.max_linear_acceleration) + _gui.connect("linear_accel_changed", self, "_on_GUI_linear_accel_changed") + _gui.connect("linear_speed_changed", self, "_on_GUI_linear_speed_changed") + + +func _on_GUI_linear_accel_changed(value: int) -> void: + _pursuer.agent.max_linear_acceleration = float(value) + _seeker.agent.max_linear_acceleration = float(value) + + +func _on_GUI_linear_speed_changed(value: int) -> void: + _pursuer.agent.max_linear_speed = float(value) + _seeker.agent.max_linear_speed = float(value) diff --git a/project/demos/pursue_vs_seek/Pursuer.gd b/project/demos/pursue_vs_seek/Pursuer.gd index dd4d01b..52ea2a6 100644 --- a/project/demos/pursue_vs_seek/Pursuer.gd +++ b/project/demos/pursue_vs_seek/Pursuer.gd @@ -34,8 +34,8 @@ func _setup() -> void: agent.max_angular_acceleration = 2 agent.max_angular_speed = 5 - agent.max_linear_acceleration = 120 - agent.max_linear_speed = 200 + agent.max_linear_acceleration = 75 + agent.max_linear_speed = 125 _update_agent() @@ -51,9 +51,9 @@ func _physics_process(delta: float) -> void: rotation = rotation + _angular_velocity * delta accel = _behavior.calculate_steering(accel) - _linear_velocity = ( - _linear_velocity + Vector2(accel.linear.x, accel.linear.y) * delta).clamped(agent.max_linear_speed) - _linear_velocity -= _linear_velocity * 1 * delta + _linear_velocity += Vector2(accel.linear.x, accel.linear.y) * delta + _linear_velocity -= _linear_velocity.normalized() * 10 * delta + _linear_velocity = _linear_velocity.clamped(agent.max_linear_speed) _linear_velocity = move_and_slide(_linear_velocity) _update_agent() diff --git a/project/demos/seek_and_flee/GUI.tscn b/project/demos/seek_and_flee/GUI.tscn index 9ad06ae..06917bd 100644 --- a/project/demos/seek_and_flee/GUI.tscn +++ b/project/demos/seek_and_flee/GUI.tscn @@ -17,11 +17,11 @@ __meta__ = { [node name="BehaviorControls" type="VBoxContainer" parent="."] margin_left = 20.0 margin_top = 20.0 -margin_right = 102.0 +margin_right = 96.0 margin_bottom = 580.0 [node name="Seek" type="CheckBox" parent="BehaviorControls"] -margin_right = 82.0 +margin_right = 76.0 margin_bottom = 24.0 focus_mode = 0 pressed = true @@ -30,7 +30,7 @@ text = "Seek" [node name="Flee" type="CheckBox" parent="BehaviorControls"] margin_top = 28.0 -margin_right = 82.0 +margin_right = 76.0 margin_bottom = 52.0 focus_mode = 0 enabled_focus_mode = 0 @@ -38,17 +38,17 @@ text = "Flee" [node name="Help" type="VBoxContainer" parent="BehaviorControls"] margin_top = 56.0 -margin_right = 82.0 +margin_right = 76.0 margin_bottom = 108.0 [node name="Controls" type="Label" parent="BehaviorControls/Help"] -margin_right = 82.0 +margin_right = 76.0 margin_bottom = 14.0 text = "Controls" [node name="GridContainer" type="GridContainer" parent="BehaviorControls/Help"] margin_top = 18.0 -margin_right = 82.0 +margin_right = 76.0 margin_bottom = 52.0 columns = 3 @@ -59,11 +59,11 @@ rect_min_size = Vector2( 15, 15 ) [node name="W" type="Label" parent="BehaviorControls/Help/GridContainer"] margin_left = 19.0 -margin_top = -1.0 margin_right = 34.0 -margin_bottom = 14.0 +margin_bottom = 15.0 rect_min_size = Vector2( 15, 15 ) text = "W" +align = 1 [node name="Sep2" type="Control" parent="BehaviorControls/Help/GridContainer"] margin_left = 38.0 @@ -72,24 +72,27 @@ margin_bottom = 15.0 rect_min_size = Vector2( 15, 15 ) [node name="A" type="Label" parent="BehaviorControls/Help/GridContainer"] -margin_top = 18.0 +margin_top = 19.0 margin_right = 15.0 -margin_bottom = 33.0 +margin_bottom = 34.0 rect_min_size = Vector2( 15, 15 ) text = "A" +align = 1 [node name="S" type="Label" parent="BehaviorControls/Help/GridContainer"] margin_left = 19.0 -margin_top = 18.0 +margin_top = 19.0 margin_right = 34.0 -margin_bottom = 33.0 +margin_bottom = 34.0 rect_min_size = Vector2( 15, 15 ) text = "S" +align = 1 [node name="D" type="Label" parent="BehaviorControls/Help/GridContainer"] margin_left = 38.0 -margin_top = 18.0 +margin_top = 19.0 margin_right = 53.0 -margin_bottom = 33.0 +margin_bottom = 34.0 rect_min_size = Vector2( 15, 15 ) text = "D" +align = 1 From 87aef4825128b611a29d7d7ace10f89263ec5aee Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Sun, 22 Dec 2019 14:08:53 -0500 Subject: [PATCH 12/23] Add GUI to Face demo --- project/demos/face/Face.tscn | 5 +- project/demos/face/FaceDemo.gd | 30 +++++++ project/demos/face/GUI.gd | 47 ++++++++++ project/demos/face/GUI.tscn | 153 +++++++++++++++++++++++++++++++++ project/demos/face/Turret.gd | 15 ++-- 5 files changed, 242 insertions(+), 8 deletions(-) create mode 100644 project/demos/face/GUI.gd create mode 100644 project/demos/face/GUI.tscn diff --git a/project/demos/face/Face.tscn b/project/demos/face/Face.tscn index 4099538..16f3a08 100644 --- a/project/demos/face/Face.tscn +++ b/project/demos/face/Face.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=6 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://demos/face/Player.gd" type="Script" id=1] [ext_resource path="res://demos/face/Turret.gd" type="Script" id=2] [ext_resource path="res://demos/face/FaceDemo.gd" type="Script" id=3] +[ext_resource path="res://demos/face/GUI.tscn" type="PackedScene" id=4] [sub_resource type="CircleShape2D" id=1] radius = 20.0 @@ -16,6 +17,8 @@ __meta__ = { "_editor_description_": "A demo showing the usage of the Face steering behavior." } +[node name="GUI" parent="." instance=ExtResource( 4 )] + [node name="Player" type="KinematicBody2D" parent="."] position = Vector2( 512, 450 ) script = ExtResource( 1 ) diff --git a/project/demos/face/FaceDemo.gd b/project/demos/face/FaceDemo.gd index 28ac945..c85ff14 100644 --- a/project/demos/face/FaceDemo.gd +++ b/project/demos/face/FaceDemo.gd @@ -2,3 +2,33 @@ extends Node2D onready var player: = $Player +onready var _gui: = $GUI +onready var _turret: = $Turret + + +func _ready() -> void: + _gui.connect("align_tolerance_changed", self, "_on_GUI_align_tolerance_changed") + _gui.connect("decel_radius_changed", self, "_on_GUI_decel_radius_changed") + _gui.connect("max_accel_changed", self, "_on_GUI_max_accel_changed") + _gui.connect("max_speed_changed", self, "_on_GUI_max_speed_changed") + _turret.setup() + _gui.align_tolerance.text = str(int(rad2deg(_turret._face.alignment_tolerance))) + _gui.decel_radius.text = str(int(rad2deg(_turret._face.deceleration_radius))) + _gui.max_speed.text = str(int(rad2deg(_turret._agent.max_angular_speed))) + _gui.max_accel.text = str(int(rad2deg(_turret._agent.max_angular_acceleration))) + + +func _on_GUI_align_tolerance_changed(value: int) -> void: + _turret._face.alignment_tolerance = deg2rad(value) + + +func _on_GUI_decel_radius_changed(value: int) -> void: + _turret._face.deceleration_radius = deg2rad(value) + + +func _on_GUI_max_accel_changed(value: int) -> void: + _turret._agent.max_angular_acceleration = deg2rad(value) + + +func _on_GUI_max_speed_changed(value: int) -> void: + _turret._agent.max_angular_speed = deg2rad(value) diff --git a/project/demos/face/GUI.gd b/project/demos/face/GUI.gd new file mode 100644 index 0000000..4284c41 --- /dev/null +++ b/project/demos/face/GUI.gd @@ -0,0 +1,47 @@ +extends MarginContainer + + +signal max_speed_changed(value) +signal max_accel_changed(value) +signal align_tolerance_changed(value) +signal decel_radius_changed(value) + +onready var max_speed: = $Controls/MaxSpeed/LineEdit +onready var max_accel: = $Controls/MaxAccel/LineEdit +onready var align_tolerance: = $Controls/AlignmentTolerance/LineEdit +onready var decel_radius: = $Controls/DecelerationRadius/LineEdit + + +func _ready() -> void: + max_speed.connect("text_changed", self, "_on_MaxSpeed_text_changed") + max_accel.connect("text_changed", self, "_on_MaxAccel_text_changed") + align_tolerance.connect("text_changed", self, "_on_AlignTolerance_text_changed") + decel_radius.connect("text_changed", self, "_on_DecelRadius_text_changed") + + +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventMouseButton: + max_speed.release_focus() + max_accel.release_focus() + align_tolerance.release_focus() + decel_radius.release_focus() + + +func _on_MaxSpeed_text_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("max_speed_changed", int(float(new_text))) + + +func _on_MaxAccel_text_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("max_accel_changed", int(float(new_text))) + + +func _on_AlignTolerance_text_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("align_tolerance_changed", int(float(new_text))) + + +func _on_DecelRadius_text_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("decel_radius_changed", int(float(new_text))) diff --git a/project/demos/face/GUI.tscn b/project/demos/face/GUI.tscn new file mode 100644 index 0000000..09eef08 --- /dev/null +++ b/project/demos/face/GUI.tscn @@ -0,0 +1,153 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://demos/face/GUI.gd" type="Script" id=1] + +[node name="GUI" type="MarginContainer"] +anchor_bottom = 1.0 +margin_right = 40.0 +custom_constants/margin_right = 20 +custom_constants/margin_top = 20 +custom_constants/margin_left = 20 +custom_constants/margin_bottom = 20 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Controls" type="VBoxContainer" parent="."] +margin_left = 20.0 +margin_top = 20.0 +margin_right = 212.0 +margin_bottom = 580.0 + +[node name="MaxSpeed" type="HBoxContainer" parent="Controls"] +margin_right = 192.0 +margin_bottom = 24.0 + +[node name="Label" type="Label" parent="Controls/MaxSpeed"] +margin_top = 4.0 +margin_right = 130.0 +margin_bottom = 19.0 +rect_min_size = Vector2( 130, 15 ) +text = "Max speed" + +[node name="LineEdit" type="LineEdit" parent="Controls/MaxSpeed"] +margin_left = 134.0 +margin_right = 192.0 +margin_bottom = 24.0 +focus_mode = 1 + +[node name="MaxAccel" type="HBoxContainer" parent="Controls"] +margin_top = 28.0 +margin_right = 192.0 +margin_bottom = 52.0 + +[node name="Label" type="Label" parent="Controls/MaxAccel"] +margin_top = 4.0 +margin_right = 130.0 +margin_bottom = 19.0 +rect_min_size = Vector2( 130, 15 ) +text = "Max acceleration" + +[node name="LineEdit" type="LineEdit" parent="Controls/MaxAccel"] +margin_left = 134.0 +margin_right = 192.0 +margin_bottom = 24.0 +focus_mode = 1 + +[node name="AlignmentTolerance" type="HBoxContainer" parent="Controls"] +margin_top = 56.0 +margin_right = 192.0 +margin_bottom = 80.0 + +[node name="Label" type="Label" parent="Controls/AlignmentTolerance"] +margin_top = 4.0 +margin_right = 130.0 +margin_bottom = 19.0 +rect_min_size = Vector2( 130, 15 ) +text = "Alignment tolerance" + +[node name="LineEdit" type="LineEdit" parent="Controls/AlignmentTolerance"] +margin_left = 134.0 +margin_right = 192.0 +margin_bottom = 24.0 +focus_mode = 1 + +[node name="DecelerationRadius" type="HBoxContainer" parent="Controls"] +margin_top = 84.0 +margin_right = 192.0 +margin_bottom = 108.0 + +[node name="Label" type="Label" parent="Controls/DecelerationRadius"] +margin_top = 4.0 +margin_right = 130.0 +margin_bottom = 19.0 +rect_min_size = Vector2( 130, 15 ) +text = "Deceleration radius" + +[node name="LineEdit" type="LineEdit" parent="Controls/DecelerationRadius"] +margin_left = 134.0 +margin_right = 192.0 +margin_bottom = 24.0 +focus_mode = 1 + +[node name="Help" type="VBoxContainer" parent="Controls"] +margin_top = 112.0 +margin_right = 192.0 +margin_bottom = 164.0 + +[node name="Controls" type="Label" parent="Controls/Help"] +margin_right = 192.0 +margin_bottom = 14.0 +text = "Controls" + +[node name="GridContainer" type="GridContainer" parent="Controls/Help"] +margin_top = 18.0 +margin_right = 192.0 +margin_bottom = 52.0 +columns = 3 + +[node name="Sep" type="Control" parent="Controls/Help/GridContainer"] +margin_right = 15.0 +margin_bottom = 15.0 +rect_min_size = Vector2( 15, 15 ) + +[node name="W" type="Label" parent="Controls/Help/GridContainer"] +margin_left = 19.0 +margin_right = 34.0 +margin_bottom = 15.0 +rect_min_size = Vector2( 15, 15 ) +text = "W" +align = 1 + +[node name="Sep2" type="Control" parent="Controls/Help/GridContainer"] +margin_left = 38.0 +margin_right = 53.0 +margin_bottom = 15.0 +rect_min_size = Vector2( 15, 15 ) + +[node name="A" type="Label" parent="Controls/Help/GridContainer"] +margin_top = 19.0 +margin_right = 15.0 +margin_bottom = 34.0 +rect_min_size = Vector2( 15, 15 ) +text = "A" +align = 1 + +[node name="S" type="Label" parent="Controls/Help/GridContainer"] +margin_left = 19.0 +margin_top = 19.0 +margin_right = 34.0 +margin_bottom = 34.0 +rect_min_size = Vector2( 15, 15 ) +text = "S" +align = 1 + +[node name="D" type="Label" parent="Controls/Help/GridContainer"] +margin_left = 38.0 +margin_top = 19.0 +margin_right = 53.0 +margin_bottom = 34.0 +rect_min_size = Vector2( 15, 15 ) +text = "D" +align = 1 diff --git a/project/demos/face/Turret.gd b/project/demos/face/Turret.gd index 9306eae..2573e6d 100644 --- a/project/demos/face/Turret.gd +++ b/project/demos/face/Turret.gd @@ -16,9 +16,10 @@ func _draw() -> void: draw_circle(Vector2.ZERO, _radius, Color.teal) + func _physics_process(delta: float) -> void: if not _face: - _setup() + return _accel = _face.calculate_steering(_accel) _angular_velocity += _accel.angular @@ -33,12 +34,7 @@ func _physics_process(delta: float) -> void: _update_agent() -func _update_agent() -> void: - _agent.angular_velocity = _angular_velocity - _agent.orientation = rotation - - -func _setup() -> void: +func setup() -> void: _face = GSTFace.new(_agent, owner.player.agent) _face.alignment_tolerance = 0.1 @@ -49,3 +45,8 @@ func _setup() -> void: _agent.position = Vector3(global_position.x, global_position.y, 0) _update_agent() + + +func _update_agent() -> void: + _agent.angular_velocity = _angular_velocity + _agent.orientation = rotation From 35d9b2e1a69c23b9b4020a20580a8c441357e4e2 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Sun, 22 Dec 2019 14:23:25 -0500 Subject: [PATCH 13/23] Add GUI to Arrive demo --- project/demos/arrive/Arrive.tscn | 7 +- project/demos/arrive/ArriveDemo.gd | 29 +++++ project/demos/arrive/GUI.gd | 47 ++++++++ project/demos/arrive/GUI.tscn | 108 ++++++++++++++++++ project/demos/face/Face.tscn | 6 +- .../demos/pursue_vs_seek/PursueVSSeek.tscn | 6 +- project/demos/seek_and_flee/SeekFlee.tscn | 12 +- 7 files changed, 204 insertions(+), 11 deletions(-) create mode 100644 project/demos/arrive/GUI.gd create mode 100644 project/demos/arrive/GUI.tscn diff --git a/project/demos/arrive/Arrive.tscn b/project/demos/arrive/Arrive.tscn index 1b5d194..144bd97 100644 --- a/project/demos/arrive/Arrive.tscn +++ b/project/demos/arrive/Arrive.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://demos/arrive/Arriver.gd" type="Script" id=1] [ext_resource path="res://demos/arrive/ArriveDemo.gd" type="Script" id=2] [ext_resource path="res://demos/arrive/Target.gd" type="Script" id=3] +[ext_resource path="res://demos/arrive/GUI.tscn" type="PackedScene" id=4] [sub_resource type="CircleShape2D" id=1] radius = 15.0 @@ -18,3 +19,7 @@ shape = SubResource( 1 ) [node name="Target" type="Node2D" parent="."] script = ExtResource( 3 ) + +[node name="GUI" parent="." instance=ExtResource( 4 )] +margin_right = 227.0 +margin_bottom = 184.0 diff --git a/project/demos/arrive/ArriveDemo.gd b/project/demos/arrive/ArriveDemo.gd index ab3fe71..a60cc04 100644 --- a/project/demos/arrive/ArriveDemo.gd +++ b/project/demos/arrive/ArriveDemo.gd @@ -2,7 +2,36 @@ extends Node2D onready var _target: = $Target +onready var _arriver: = $Arriver +onready var _gui: = $GUI + + +func _ready() -> void: + _gui.connect("align_tolerance_changed", self, "_on_GUI_align_tolerance_changed") + _gui.connect("decel_radius_changed", self, "_on_GUI_decel_radius_changed") + _gui.connect("max_speed_changed", self, "_on_GUI_max_speed_changed") + _gui.connect("max_accel_changed", self, "_on_GUI_max_accel_changed") + _gui.max_speed.text = str(_arriver._agent.max_linear_speed) + _gui.max_accel.text = str(_arriver._agent.max_linear_acceleration) + _gui.arrival_tolerance.text = str(_arriver._arrive.arrival_tolerance) + _gui.deceleration_radius.text = str(_arriver._arrive.deceleration_radius) func draw(location: Vector2) -> void: _target.draw(location) + + +func _on_GUI_align_tolerance_changed(value: int) -> void: + _arriver._arrive.arrival_tolerance = value + + +func _on_GUI_decel_radius_changed(value: int) -> void: + _arriver._arrive.deceleration_radius = value + + +func _on_GUI_max_speed_changed(value: int) -> void: + _arriver._agent.max_linear_speed = value + + +func _on_GUI_max_accel_changed(value: int) -> void: + _arriver._agent.max_linear_acceleration = value diff --git a/project/demos/arrive/GUI.gd b/project/demos/arrive/GUI.gd new file mode 100644 index 0000000..3ed6a03 --- /dev/null +++ b/project/demos/arrive/GUI.gd @@ -0,0 +1,47 @@ +extends MarginContainer + + +signal max_speed_changed(value) +signal max_accel_changed(value) +signal align_tolerance_changed(value) +signal decel_radius_changed(value) + +onready var max_speed: = $Controls/MaxSpeed/LineEdit +onready var max_accel: = $Controls/MaxAccel/LineEdit +onready var arrival_tolerance: = $Controls/ArrivalTolerance/LineEdit +onready var deceleration_radius: = $Controls/DecelRadius/LineEdit + + +func _ready() -> void: + max_speed.connect("text_changed", self, "_on_MaxSpeed_text_changed") + max_accel.connect("text_changed", self, "_on_MaxAccel_text_changed") + arrival_tolerance.connect("text_changed", self, "_on_ArrivalTolerance_text_changed") + deceleration_radius.connect("text_changed", self, "_on_DecelerationRadius_text_changed") + + +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventMouseButton: + max_speed.release_focus() + max_accel.release_focus() + arrival_tolerance.release_focus() + deceleration_radius.release_focus() + + +func _on_MaxSpeed_text_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("max_speed_changed", int(float(new_text))) + + +func _on_MaxAccel_text_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("max_accel_changed", int(float(new_text))) + + +func _on_ArrivalTolerance_text_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("align_tolerance_changed", int(float(new_text))) + + +func _on_DecelerationRadius_text_changed(new_text: String) -> void: + if new_text.is_valid_integer(): + emit_signal("decel_radius_changed", int(float(new_text))) diff --git a/project/demos/arrive/GUI.tscn b/project/demos/arrive/GUI.tscn new file mode 100644 index 0000000..d870e56 --- /dev/null +++ b/project/demos/arrive/GUI.tscn @@ -0,0 +1,108 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://demos/arrive/GUI.gd" type="Script" id=1] + +[node name="GUI" type="MarginContainer"] +anchor_bottom = 1.0 +margin_right = 40.0 +custom_constants/margin_right = 20 +custom_constants/margin_top = 20 +custom_constants/margin_left = 20 +custom_constants/margin_bottom = 20 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Controls" type="VBoxContainer" parent="."] +margin_left = 20.0 +margin_top = 20.0 +margin_right = 207.0 +margin_bottom = 580.0 + +[node name="MaxSpeed" type="HBoxContainer" parent="Controls"] +margin_right = 187.0 +margin_bottom = 24.0 + +[node name="Label" type="Label" parent="Controls/MaxSpeed"] +margin_top = 4.0 +margin_right = 125.0 +margin_bottom = 19.0 +rect_min_size = Vector2( 125, 15 ) +text = "Max speed" + +[node name="LineEdit" type="LineEdit" parent="Controls/MaxSpeed"] +margin_left = 129.0 +margin_right = 187.0 +margin_bottom = 24.0 +focus_mode = 1 + +[node name="MaxAccel" type="HBoxContainer" parent="Controls"] +margin_top = 28.0 +margin_right = 187.0 +margin_bottom = 52.0 + +[node name="Label" type="Label" parent="Controls/MaxAccel"] +margin_top = 4.0 +margin_right = 125.0 +margin_bottom = 19.0 +rect_min_size = Vector2( 125, 15 ) +text = "Max acceleration" + +[node name="LineEdit" type="LineEdit" parent="Controls/MaxAccel"] +margin_left = 129.0 +margin_right = 187.0 +margin_bottom = 24.0 +focus_mode = 1 + +[node name="ArrivalTolerance" type="HBoxContainer" parent="Controls"] +margin_top = 56.0 +margin_right = 187.0 +margin_bottom = 80.0 + +[node name="Label" type="Label" parent="Controls/ArrivalTolerance"] +margin_top = 4.0 +margin_right = 125.0 +margin_bottom = 19.0 +rect_min_size = Vector2( 125, 15 ) +text = "Arrival tolerance" + +[node name="LineEdit" type="LineEdit" parent="Controls/ArrivalTolerance"] +margin_left = 129.0 +margin_right = 187.0 +margin_bottom = 24.0 +focus_mode = 1 + +[node name="DecelRadius" type="HBoxContainer" parent="Controls"] +margin_top = 84.0 +margin_right = 187.0 +margin_bottom = 108.0 + +[node name="Label" type="Label" parent="Controls/DecelRadius"] +margin_top = 4.0 +margin_right = 125.0 +margin_bottom = 19.0 +rect_min_size = Vector2( 125, 15 ) +text = "Deceleration radius" + +[node name="LineEdit" type="LineEdit" parent="Controls/DecelRadius"] +margin_left = 129.0 +margin_right = 187.0 +margin_bottom = 24.0 +focus_mode = 1 + +[node name="Help" type="VBoxContainer" parent="Controls"] +margin_top = 112.0 +margin_right = 187.0 +margin_bottom = 144.0 + +[node name="Controls" type="Label" parent="Controls/Help"] +margin_right = 187.0 +margin_bottom = 14.0 +text = "Controls" + +[node name="Label" type="Label" parent="Controls/Help"] +margin_top = 18.0 +margin_right = 187.0 +margin_bottom = 32.0 +text = "Mouse click" diff --git a/project/demos/face/Face.tscn b/project/demos/face/Face.tscn index 16f3a08..42b34d0 100644 --- a/project/demos/face/Face.tscn +++ b/project/demos/face/Face.tscn @@ -17,8 +17,6 @@ __meta__ = { "_editor_description_": "A demo showing the usage of the Face steering behavior." } -[node name="GUI" parent="." instance=ExtResource( 4 )] - [node name="Player" type="KinematicBody2D" parent="."] position = Vector2( 512, 450 ) script = ExtResource( 1 ) @@ -32,3 +30,7 @@ script = ExtResource( 2 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="Turret"] shape = SubResource( 2 ) + +[node name="GUI" parent="." instance=ExtResource( 4 )] +margin_right = 232.0 +margin_bottom = 204.0 diff --git a/project/demos/pursue_vs_seek/PursueVSSeek.tscn b/project/demos/pursue_vs_seek/PursueVSSeek.tscn index c60f216..3545a89 100644 --- a/project/demos/pursue_vs_seek/PursueVSSeek.tscn +++ b/project/demos/pursue_vs_seek/PursueVSSeek.tscn @@ -12,8 +12,6 @@ __meta__ = { "_editor_description_": "Toy demo to demonstrate the use of the Pursue contrasted to the more naive Seek steering behavior." } -[node name="GUI" parent="." instance=ExtResource( 4 )] - [node name="BoundaryManager" type="Node2D" parent="."] script = ExtResource( 2 ) @@ -47,3 +45,7 @@ use_seek = true [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Seeker"] modulate = Color( 0.317647, 0.317647, 0.317647, 1 ) polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) + +[node name="GUI" parent="." instance=ExtResource( 4 )] +margin_right = 261.0 +margin_bottom = 150.0 diff --git a/project/demos/seek_and_flee/SeekFlee.tscn b/project/demos/seek_and_flee/SeekFlee.tscn index 7183345..dce36b1 100644 --- a/project/demos/seek_and_flee/SeekFlee.tscn +++ b/project/demos/seek_and_flee/SeekFlee.tscn @@ -22,12 +22,6 @@ __meta__ = { "_editor_description_": "A toy demo to demonstrate the usage for the Seek and Flee steering behaviors." } -[node name="GUI" parent="." instance=ExtResource( 7 )] -margin_left = -512.0 -margin_top = -300.0 -margin_right = -414.0 -margin_bottom = -208.0 - [node name="Camera2D" type="Camera2D" parent="."] current = true @@ -77,3 +71,9 @@ shape = SubResource( 3 ) [node name="Spawner" type="Node2D" parent="."] script = ExtResource( 2 ) Entity = ExtResource( 4 ) + +[node name="GUI" parent="." instance=ExtResource( 7 )] +margin_left = -512.0 +margin_top = -300.0 +margin_right = -414.0 +margin_bottom = -152.0 From 9f945cbf85a87b93e9433ffd1df71f996898b56b Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Mon, 23 Dec 2019 11:38:27 -0500 Subject: [PATCH 14/23] Implement review suggestions to code Razvan reviewed the code and suggested a number of changes to improve readability and make facets of the code more explicit and consistent. --- project/demos/arrive/ArriveDemo.gd | 32 +++++++++---------- .../arrive/{Arrive.tscn => ArriveDemo.tscn} | 2 +- project/demos/arrive/Arriver.gd | 12 ++++--- project/demos/face/FaceDemo.gd | 30 ++++++++--------- .../demos/face/{Face.tscn => FaceDemo.tscn} | 14 ++++---- project/demos/face/Player.gd | 8 ++++- project/demos/face/Turret.gd | 17 +++++++--- .../demos/pursue_vs_seek/BoundaryManager.gd | 6 ++-- .../demos/pursue_vs_seek/PursueVSSeekDemo.gd | 22 ++++++------- ...ursueVSSeek.tscn => PursueVSSeekDemo.tscn} | 18 +++++------ project/demos/seek_and_flee/Player.gd | 8 ++++- project/demos/seek_and_flee/SeekFleeDemo.gd | 4 +-- .../{SeekFlee.tscn => SeekFleeDemo.tscn} | 26 +++++++-------- project/demos/seek_and_flee/Seeker.gd | 4 ++- project/src/GSTTargetAcceleration.gd | 4 +-- project/src/Utils.gd | 8 ++--- project/src/behaviors/GSTBlend.gd | 23 +++++-------- project/src/behaviors/GSTMatchOrientation.gd | 4 +-- 18 files changed, 129 insertions(+), 113 deletions(-) rename project/demos/arrive/{Arrive.tscn => ArriveDemo.tscn} (95%) rename project/demos/face/{Face.tscn => FaceDemo.tscn} (95%) rename project/demos/pursue_vs_seek/{PursueVSSeek.tscn => PursueVSSeekDemo.tscn} (89%) rename project/demos/seek_and_flee/{SeekFlee.tscn => SeekFleeDemo.tscn} (89%) diff --git a/project/demos/arrive/ArriveDemo.gd b/project/demos/arrive/ArriveDemo.gd index a60cc04..3df302c 100644 --- a/project/demos/arrive/ArriveDemo.gd +++ b/project/demos/arrive/ArriveDemo.gd @@ -1,37 +1,37 @@ extends Node2D -onready var _target: = $Target -onready var _arriver: = $Arriver -onready var _gui: = $GUI +onready var target: = $Target +onready var arriver: = $Arriver +onready var gui: = $GUI func _ready() -> void: - _gui.connect("align_tolerance_changed", self, "_on_GUI_align_tolerance_changed") - _gui.connect("decel_radius_changed", self, "_on_GUI_decel_radius_changed") - _gui.connect("max_speed_changed", self, "_on_GUI_max_speed_changed") - _gui.connect("max_accel_changed", self, "_on_GUI_max_accel_changed") - _gui.max_speed.text = str(_arriver._agent.max_linear_speed) - _gui.max_accel.text = str(_arriver._agent.max_linear_acceleration) - _gui.arrival_tolerance.text = str(_arriver._arrive.arrival_tolerance) - _gui.deceleration_radius.text = str(_arriver._arrive.deceleration_radius) + gui.connect("align_tolerance_changed", self, "_on_GUI_align_tolerance_changed") + gui.connect("decel_radius_changed", self, "_on_GUI_decel_radius_changed") + gui.connect("max_speed_changed", self, "_on_GUI_max_speed_changed") + gui.connect("max_accel_changed", self, "_on_GUI_max_accel_changed") + gui.max_speed.text = str(arriver._agent.max_linear_speed) + gui.max_accel.text = str(arriver._agent.max_linear_acceleration) + gui.arrival_tolerance.text = str(arriver._arrive.arrival_tolerance) + gui.deceleration_radius.text = str(arriver._arrive.deceleration_radius) func draw(location: Vector2) -> void: - _target.draw(location) + target.draw(location) func _on_GUI_align_tolerance_changed(value: int) -> void: - _arriver._arrive.arrival_tolerance = value + arriver._arrive.arrival_tolerance = value func _on_GUI_decel_radius_changed(value: int) -> void: - _arriver._arrive.deceleration_radius = value + arriver._arrive.deceleration_radius = value func _on_GUI_max_speed_changed(value: int) -> void: - _arriver._agent.max_linear_speed = value + arriver._agent.max_linear_speed = value func _on_GUI_max_accel_changed(value: int) -> void: - _arriver._agent.max_linear_acceleration = value + arriver._agent.max_linear_acceleration = value diff --git a/project/demos/arrive/Arrive.tscn b/project/demos/arrive/ArriveDemo.tscn similarity index 95% rename from project/demos/arrive/Arrive.tscn rename to project/demos/arrive/ArriveDemo.tscn index 144bd97..23a18f5 100644 --- a/project/demos/arrive/Arrive.tscn +++ b/project/demos/arrive/ArriveDemo.tscn @@ -8,7 +8,7 @@ [sub_resource type="CircleShape2D" id=1] radius = 15.0 -[node name="Arrive" type="Node2D"] +[node name="ArriveDemo" type="Node2D"] script = ExtResource( 2 ) [node name="Arriver" type="KinematicBody2D" parent="."] diff --git a/project/demos/arrive/Arriver.gd b/project/demos/arrive/Arriver.gd index b38fee7..f582263 100644 --- a/project/demos/arrive/Arriver.gd +++ b/project/demos/arrive/Arriver.gd @@ -1,18 +1,20 @@ extends KinematicBody2D -onready var _radius: float = ($CollisionShape2D.shape as CircleShape2D).radius +onready var collision_shape: = $CollisionShape2D -onready var _agent: = GSTSteeringAgent.new() -onready var _target: = GSTAgentLocation.new() -onready var _arrive: = GSTArrive.new(_agent, _target) -onready var _accel: = GSTTargetAcceleration.new() +var _radius: = 0.0 +var _agent: = GSTSteeringAgent.new() +var _target: = GSTAgentLocation.new() +var _arrive: = GSTArrive.new(_agent, _target) +var _accel: = GSTTargetAcceleration.new() var _velocity: = Vector2() var _drag: = 1.0 func _ready() -> void: + _radius = collision_shape.shape.radius _agent.max_linear_acceleration = 10 _agent.max_linear_speed = 200 _arrive.arrival_tolerance = 25 diff --git a/project/demos/face/FaceDemo.gd b/project/demos/face/FaceDemo.gd index c85ff14..df51ca2 100644 --- a/project/demos/face/FaceDemo.gd +++ b/project/demos/face/FaceDemo.gd @@ -2,33 +2,33 @@ extends Node2D onready var player: = $Player -onready var _gui: = $GUI -onready var _turret: = $Turret +onready var gui: = $GUI +onready var turret: = $Turret func _ready() -> void: - _gui.connect("align_tolerance_changed", self, "_on_GUI_align_tolerance_changed") - _gui.connect("decel_radius_changed", self, "_on_GUI_decel_radius_changed") - _gui.connect("max_accel_changed", self, "_on_GUI_max_accel_changed") - _gui.connect("max_speed_changed", self, "_on_GUI_max_speed_changed") - _turret.setup() - _gui.align_tolerance.text = str(int(rad2deg(_turret._face.alignment_tolerance))) - _gui.decel_radius.text = str(int(rad2deg(_turret._face.deceleration_radius))) - _gui.max_speed.text = str(int(rad2deg(_turret._agent.max_angular_speed))) - _gui.max_accel.text = str(int(rad2deg(_turret._agent.max_angular_acceleration))) + gui.connect("align_tolerance_changed", self, "_on_GUI_align_tolerance_changed") + gui.connect("decel_radius_changed", self, "_on_GUI_decel_radius_changed") + gui.connect("max_accel_changed", self, "_on_GUI_max_accel_changed") + gui.connect("max_speed_changed", self, "_on_GUI_max_speed_changed") + turret.setup() + gui.align_tolerance.text = str(int(rad2deg(turret._face.alignment_tolerance))) + gui.decel_radius.text = str(int(rad2deg(turret._face.deceleration_radius))) + gui.max_speed.text = str(int(rad2deg(turret._agent.max_angular_speed))) + gui.max_accel.text = str(int(rad2deg(turret._agent.max_angular_acceleration))) func _on_GUI_align_tolerance_changed(value: int) -> void: - _turret._face.alignment_tolerance = deg2rad(value) + turret._face.alignment_tolerance = deg2rad(value) func _on_GUI_decel_radius_changed(value: int) -> void: - _turret._face.deceleration_radius = deg2rad(value) + turret._face.deceleration_radius = deg2rad(value) func _on_GUI_max_accel_changed(value: int) -> void: - _turret._agent.max_angular_acceleration = deg2rad(value) + turret._agent.max_angular_acceleration = deg2rad(value) func _on_GUI_max_speed_changed(value: int) -> void: - _turret._agent.max_angular_speed = deg2rad(value) + turret._agent.max_angular_speed = deg2rad(value) diff --git a/project/demos/face/Face.tscn b/project/demos/face/FaceDemo.tscn similarity index 95% rename from project/demos/face/Face.tscn rename to project/demos/face/FaceDemo.tscn index 42b34d0..8960aed 100644 --- a/project/demos/face/Face.tscn +++ b/project/demos/face/FaceDemo.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=7 format=2] -[ext_resource path="res://demos/face/Player.gd" type="Script" id=1] -[ext_resource path="res://demos/face/Turret.gd" type="Script" id=2] -[ext_resource path="res://demos/face/FaceDemo.gd" type="Script" id=3] +[ext_resource path="res://demos/face/Turret.gd" type="Script" id=1] +[ext_resource path="res://demos/face/FaceDemo.gd" type="Script" id=2] +[ext_resource path="res://demos/face/Player.gd" type="Script" id=3] [ext_resource path="res://demos/face/GUI.tscn" type="PackedScene" id=4] [sub_resource type="CircleShape2D" id=1] @@ -11,22 +11,22 @@ radius = 20.0 [sub_resource type="CircleShape2D" id=2] radius = 30.0 -[node name="Face" type="Node2D"] -script = ExtResource( 3 ) +[node name="FaceDemo" type="Node2D"] +script = ExtResource( 2 ) __meta__ = { "_editor_description_": "A demo showing the usage of the Face steering behavior." } [node name="Player" type="KinematicBody2D" parent="."] position = Vector2( 512, 450 ) -script = ExtResource( 1 ) +script = ExtResource( 3 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] shape = SubResource( 1 ) [node name="Turret" type="KinematicBody2D" parent="."] position = Vector2( 512, 150 ) -script = ExtResource( 2 ) +script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="Turret"] shape = SubResource( 2 ) diff --git a/project/demos/face/Player.gd b/project/demos/face/Player.gd index a453ebb..d5fa879 100644 --- a/project/demos/face/Player.gd +++ b/project/demos/face/Player.gd @@ -1,11 +1,17 @@ extends KinematicBody2D -onready var _radius: float = ($CollisionShape2D.shape as CircleShape2D).radius +onready var collision_shape: = $CollisionShape2D onready var agent: = GSTAgentLocation.new() export var speed: = 125.0 +var _radius: = 0.0 + + +func _ready() -> void: + _radius = collision_shape.shape.radius + func _draw() -> void: draw_circle(Vector2.ZERO, _radius, Color.red) diff --git a/project/demos/face/Turret.gd b/project/demos/face/Turret.gd index 2573e6d..9209af4 100644 --- a/project/demos/face/Turret.gd +++ b/project/demos/face/Turret.gd @@ -1,22 +1,29 @@ extends KinematicBody2D -onready var _radius: float = ($CollisionShape2D.shape as CircleShape2D).radius -onready var _cannon: = Rect2(Vector2(-5, 0), Vector2(10, -_radius*2)) -onready var _agent: = GSTSteeringAgent.new() -onready var _accel: = GSTTargetAcceleration.new() +onready var collision_shape: = $CollisionShape2D + +var _radius: = 0.0 +var _cannon: Rect2 + +var _agent: = GSTSteeringAgent.new() +var _accel: = GSTTargetAcceleration.new() var _angular_velocity: = 0.0 var _angular_drag: = 1.0 var _face: GSTFace +func _ready() -> void: + _radius = collision_shape.shape.radius + _cannon = Rect2(Vector2(-5, 0), Vector2(10, -_radius*2)) + + func _draw() -> void: draw_rect(_cannon, Color.blue) draw_circle(Vector2.ZERO, _radius, Color.teal) - func _physics_process(delta: float) -> void: if not _face: return diff --git a/project/demos/pursue_vs_seek/BoundaryManager.gd b/project/demos/pursue_vs_seek/BoundaryManager.gd index a78469e..ea5bb00 100644 --- a/project/demos/pursue_vs_seek/BoundaryManager.gd +++ b/project/demos/pursue_vs_seek/BoundaryManager.gd @@ -4,8 +4,8 @@ Wraps the ships' positions around the world border, and controls their rendering """ -onready var _ships: = [$Player, $Pursuer, $Seeker] onready var ShipType: = preload("res://demos/pursue_vs_seek/Ship.gd") +onready var ships: = [$Player, $Pursuer, $Seeker] var _clones: = {} var _world_bounds: Vector2 @@ -17,8 +17,8 @@ func _ready() -> void: ProjectSettings["display/window/size/height"] ) - for i in range(_ships.size()): - var ship: Node2D = _ships[i] + for i in range(ships.size()): + var ship: Node2D = ships[i] var world_pos: = ship.position for i in range(3): diff --git a/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd b/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd index 5683ea3..5f1dbb1 100644 --- a/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd +++ b/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd @@ -1,23 +1,23 @@ extends Node2D -onready var _gui: = $GUI -onready var _pursuer: = $BoundaryManager/Pursuer -onready var _seeker: = $BoundaryManager/Seeker +onready var gui: = $GUI +onready var pursuer: = $BoundaryManager/Pursuer +onready var seeker: = $BoundaryManager/Seeker func _ready() -> void: - _gui.linear_speed.text = str(_pursuer.agent.max_linear_speed) - _gui.linear_accel.text = str(_pursuer.agent.max_linear_acceleration) - _gui.connect("linear_accel_changed", self, "_on_GUI_linear_accel_changed") - _gui.connect("linear_speed_changed", self, "_on_GUI_linear_speed_changed") + gui.linear_speed.text = str(pursuer.agent.max_linear_speed) + gui.linear_accel.text = str(pursuer.agent.max_linear_acceleration) + gui.connect("linear_accel_changed", self, "_on_GUI_linear_accel_changed") + gui.connect("linear_speed_changed", self, "_on_GUI_linear_speed_changed") func _on_GUI_linear_accel_changed(value: int) -> void: - _pursuer.agent.max_linear_acceleration = float(value) - _seeker.agent.max_linear_acceleration = float(value) + pursuer.agent.max_linear_acceleration = float(value) + seeker.agent.max_linear_acceleration = float(value) func _on_GUI_linear_speed_changed(value: int) -> void: - _pursuer.agent.max_linear_speed = float(value) - _seeker.agent.max_linear_speed = float(value) + pursuer.agent.max_linear_speed = float(value) + seeker.agent.max_linear_speed = float(value) diff --git a/project/demos/pursue_vs_seek/PursueVSSeek.tscn b/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn similarity index 89% rename from project/demos/pursue_vs_seek/PursueVSSeek.tscn rename to project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn index 3545a89..2691452 100644 --- a/project/demos/pursue_vs_seek/PursueVSSeek.tscn +++ b/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn @@ -1,25 +1,25 @@ [gd_scene load_steps=6 format=2] [ext_resource path="res://demos/pursue_vs_seek/Pursuer.gd" type="Script" id=1] -[ext_resource path="res://demos/pursue_vs_seek/BoundaryManager.gd" type="Script" id=2] -[ext_resource path="res://demos/pursue_vs_seek/Player.gd" type="Script" id=3] -[ext_resource path="res://demos/pursue_vs_seek/GUI.tscn" type="PackedScene" id=4] -[ext_resource path="res://demos/pursue_vs_seek/PursueVSSeekDemo.gd" type="Script" id=5] +[ext_resource path="res://demos/pursue_vs_seek/Player.gd" type="Script" id=2] +[ext_resource path="res://demos/pursue_vs_seek/BoundaryManager.gd" type="Script" id=3] +[ext_resource path="res://demos/pursue_vs_seek/PursueVSSeekDemo.gd" type="Script" id=4] +[ext_resource path="res://demos/pursue_vs_seek/GUI.tscn" type="PackedScene" id=5] -[node name="PursueVSSeek" type="Node2D"] -script = ExtResource( 5 ) +[node name="PursueVSSeekDemo" type="Node2D"] +script = ExtResource( 4 ) __meta__ = { "_editor_description_": "Toy demo to demonstrate the use of the Pursue contrasted to the more naive Seek steering behavior." } [node name="BoundaryManager" type="Node2D" parent="."] -script = ExtResource( 2 ) +script = ExtResource( 3 ) [node name="Player" type="KinematicBody2D" parent="BoundaryManager"] position = Vector2( 49.2031, 556.936 ) rotation = 1.5708 collision_mask = 2 -script = ExtResource( 3 ) +script = ExtResource( 2 ) color = Color( 1, 0, 0, 1 ) [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Player"] @@ -46,6 +46,6 @@ use_seek = true modulate = Color( 0.317647, 0.317647, 0.317647, 1 ) polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) -[node name="GUI" parent="." instance=ExtResource( 4 )] +[node name="GUI" parent="." instance=ExtResource( 5 )] margin_right = 261.0 margin_bottom = 150.0 diff --git a/project/demos/seek_and_flee/Player.gd b/project/demos/seek_and_flee/Player.gd index 4be9822..bc943b6 100644 --- a/project/demos/seek_and_flee/Player.gd +++ b/project/demos/seek_and_flee/Player.gd @@ -4,11 +4,17 @@ Class to control the player in basic left/right up/down movement. """ -onready var _radius: = ($CollisionShape2D.shape as CircleShape2D).radius +onready var collision_shape: = $CollisionShape2D onready var agent: = GSTAgentLocation.new() export var speed: = 150.0 +var _radius: = 0.0 + + +func _ready() -> void: + _radius = collision_shape.shape.radius + func _draw() -> void: draw_circle(Vector2.ZERO, _radius, Color.red) diff --git a/project/demos/seek_and_flee/SeekFleeDemo.gd b/project/demos/seek_and_flee/SeekFleeDemo.gd index c1965f5..d5a26d8 100644 --- a/project/demos/seek_and_flee/SeekFleeDemo.gd +++ b/project/demos/seek_and_flee/SeekFleeDemo.gd @@ -6,7 +6,7 @@ Access helper class for children to access window boundaries. onready var player: KinematicBody2D = $Player onready var spawner: Node2D = $Spawner -onready var _gui: = $GUI +onready var gui: = $GUI var camera_boundaries: Rect2 @@ -35,5 +35,5 @@ func _ready() -> void: entity.player_agent = player.agent entity.speed = rng.randf_range(spawner.min_speed, spawner.max_speed) entity.color = spawner.entity_color - _gui.connect("mode_changed", entity, "_on_GUI_mode_changed") + gui.connect("mode_changed", entity, "_on_GUI_mode_changed") spawner.add_child(entity) diff --git a/project/demos/seek_and_flee/SeekFlee.tscn b/project/demos/seek_and_flee/SeekFleeDemo.tscn similarity index 89% rename from project/demos/seek_and_flee/SeekFlee.tscn rename to project/demos/seek_and_flee/SeekFleeDemo.tscn index dce36b1..cb19392 100644 --- a/project/demos/seek_and_flee/SeekFlee.tscn +++ b/project/demos/seek_and_flee/SeekFleeDemo.tscn @@ -1,11 +1,11 @@ [gd_scene load_steps=10 format=2] -[ext_resource path="res://demos/seek_and_flee/Player.gd" type="Script" id=1] -[ext_resource path="res://demos/seek_and_flee/Spawner.gd" type="Script" id=2] +[ext_resource path="res://demos/seek_and_flee/Boundary.gd" type="Script" id=1] +[ext_resource path="res://demos/seek_and_flee/Player.gd" type="Script" id=2] [ext_resource path="res://demos/seek_and_flee/SeekFleeDemo.gd" type="Script" id=3] -[ext_resource path="res://demos/seek_and_flee/Seeker.tscn" type="PackedScene" id=4] -[ext_resource path="res://demos/seek_and_flee/Boundary.gd" type="Script" id=5] -[ext_resource path="res://demos/seek_and_flee/GUI.tscn" type="PackedScene" id=7] +[ext_resource path="res://demos/seek_and_flee/Spawner.gd" type="Script" id=4] +[ext_resource path="res://demos/seek_and_flee/GUI.tscn" type="PackedScene" id=5] +[ext_resource path="res://demos/seek_and_flee/Seeker.tscn" type="PackedScene" id=6] [sub_resource type="CircleShape2D" id=1] radius = 30.0 @@ -27,7 +27,7 @@ current = true [node name="Player" type="KinematicBody2D" parent="."] collision_mask = 2 -script = ExtResource( 1 ) +script = ExtResource( 2 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] shape = SubResource( 1 ) @@ -36,7 +36,7 @@ shape = SubResource( 1 ) position = Vector2( -512, 0 ) collision_layer = 2 collision_mask = 5 -script = ExtResource( 5 ) +script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="LeftBoundary"] shape = SubResource( 2 ) @@ -45,7 +45,7 @@ shape = SubResource( 2 ) position = Vector2( 512, 0 ) collision_layer = 2 collision_mask = 5 -script = ExtResource( 5 ) +script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="RightBoundary"] shape = SubResource( 2 ) @@ -54,7 +54,7 @@ shape = SubResource( 2 ) position = Vector2( 0, -300 ) collision_layer = 2 collision_mask = 5 -script = ExtResource( 5 ) +script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="TopBoundary"] shape = SubResource( 3 ) @@ -63,16 +63,16 @@ shape = SubResource( 3 ) position = Vector2( 0, 300 ) collision_layer = 2 collision_mask = 5 -script = ExtResource( 5 ) +script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="BottomBoundary"] shape = SubResource( 3 ) [node name="Spawner" type="Node2D" parent="."] -script = ExtResource( 2 ) -Entity = ExtResource( 4 ) +script = ExtResource( 4 ) +Entity = ExtResource( 6 ) -[node name="GUI" parent="." instance=ExtResource( 7 )] +[node name="GUI" parent="." instance=ExtResource( 5 )] margin_left = -512.0 margin_top = -300.0 margin_right = -414.0 diff --git a/project/demos/seek_and_flee/Seeker.gd b/project/demos/seek_and_flee/Seeker.gd index 8c8b2a0..3dcc860 100644 --- a/project/demos/seek_and_flee/Seeker.gd +++ b/project/demos/seek_and_flee/Seeker.gd @@ -4,7 +4,7 @@ AI agent that uses the Seek behavior to hone in on the player's location as dire """ -onready var radius: = ($CollisionShape2D.shape as CircleShape2D).radius +onready var collision_shape: = $CollisionShape2D onready var agent: = GSTSteeringAgent.new() onready var accel: = GSTTargetAcceleration.new() @@ -16,11 +16,13 @@ var player_agent: GSTAgentLocation var velocity: = Vector2.ZERO var speed: float var color: Color +var radius: = 0.0 func _ready() -> void: agent.max_linear_acceleration = speed/10 agent.max_linear_speed = speed + radius = collision_shape.shape.radius func _draw() -> void: diff --git a/project/src/GSTTargetAcceleration.gd b/project/src/GSTTargetAcceleration.gd index 180f7f7..8445262 100644 --- a/project/src/GSTTargetAcceleration.gd +++ b/project/src/GSTTargetAcceleration.gd @@ -20,9 +20,9 @@ func add_scaled_accel(accel: GSTTargetAcceleration, scalar: float) -> void: angular += accel.angular * scalar -func get_squared_magnitude() -> float: +func get_magnitude_squared() -> float: return linear.length_squared() + angular * angular func get_magnitude() -> float: - return sqrt(get_squared_magnitude()) + return sqrt(get_magnitude_squared()) diff --git a/project/src/Utils.gd b/project/src/Utils.gd index fa2a4e5..bed6dd3 100644 --- a/project/src/Utils.gd +++ b/project/src/Utils.gd @@ -5,8 +5,8 @@ Useful math and utility functions to complement Godot's own. static func clampedv3(vector: Vector3, limit: float) -> Vector3: - var len2: = vector.length_squared() - var limit2: = limit * limit - if len2 > limit2: - vector *= sqrt(limit2 / len2) + var length_squared: = vector.length_squared() + var limit_squared: = limit * limit + if length_squared > limit_squared: + vector *= sqrt(limit_squared / length_squared) return vector diff --git a/project/src/behaviors/GSTBlend.gd b/project/src/behaviors/GSTBlend.gd index de1783d..1705553 100644 --- a/project/src/behaviors/GSTBlend.gd +++ b/project/src/behaviors/GSTBlend.gd @@ -5,6 +5,9 @@ Blends multiple steering behaviors into one, and returns acceleration combining Each behavior is associated with a weight - a modifier by which the result will be multiplied by, then added to a total acceleration. + +Each behavior is stored internally as a `Dictionary` with a `behavior` key with a value of type +`GSTSteeringBehavior` and a `weight` key with a value of type float. """ @@ -18,36 +21,26 @@ func _init(agent: GSTSteeringAgent).(agent) -> void: func add(behavior: GSTSteeringBehavior, weight: float) -> void: behavior.agent = agent - _behaviors.append(GSTBehaviorAndWeight.new(behavior, weight)) + _behaviors.append({behavior = behavior, weight = weight}) -func get_behavior_at(index: int) -> GSTBehaviorAndWeight: +func get_behavior_at(index: int) -> Dictionary: if _behaviors.size() > index: return _behaviors[index] printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size())) - return null + return {} func _calculate_steering(blended_accel: GSTTargetAcceleration) -> GSTTargetAcceleration: blended_accel.set_zero() for i in range(_behaviors.size()): - var bw: GSTBehaviorAndWeight = _behaviors[i] + var bw: Dictionary = _behaviors[i] bw.behavior.calculate_steering(_accel) blended_accel.add_scaled_accel(_accel, bw.weight) blended_accel.linear = Utils.clampedv3(blended_accel.linear, agent.max_linear_acceleration) - if blended_accel.angular > agent.max_angular_acceleration: - blended_accel.angular = agent.max_angular_acceleration + blended_accel.angular = min(blended_accel.angular, agent.max_angular_acceleration) return blended_accel - - -class GSTBehaviorAndWeight: - var behavior: GSTSteeringBehavior - var weight: float - - func _init(behavior: GSTSteeringBehavior, weight: float) -> void: - self.behavior = behavior - self.weight = weight diff --git a/project/src/behaviors/GSTMatchOrientation.gd b/project/src/behaviors/GSTMatchOrientation.gd index bf653cf..cce5055 100644 --- a/project/src/behaviors/GSTMatchOrientation.gd +++ b/project/src/behaviors/GSTMatchOrientation.gd @@ -19,7 +19,7 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation: float) -> GSTTargetAcceleration: var rotation: = wrapf(desired_orientation - agent.orientation, -PI, PI) - var rotation_size: = -rotation if rotation < 0 else rotation + var rotation_size: = abs(rotation) if rotation_size <= alignment_tolerance: acceleration.set_zero() @@ -33,7 +33,7 @@ func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation acceleration.angular = (desired_rotation - agent.angular_velocity) / time_to_reach - var limited_acceleration: = -acceleration.angular if acceleration.angular < 0 else acceleration.angular + var limited_acceleration: = abs(acceleration.angular) if limited_acceleration > agent.max_angular_acceleration: acceleration.angular *= agent.max_angular_acceleration / limited_acceleration From 8fb4f4c51a37737cd98c9f4b3c7987e29e2500a2 Mon Sep 17 00:00:00 2001 From: Nathan Lovato Date: Thu, 2 Jan 2020 23:42:41 +0100 Subject: [PATCH 15/23] Replace multiline comments with comment blocks The use of multiline blocks in GDSCript for comments leaves them in the final compiled file, increasing size and potentially processing for no end-user gain. --- project/demos/pursue_vs_seek/BoundaryManager.gd | 4 +--- project/demos/pursue_vs_seek/Player.gd | 4 +--- project/demos/pursue_vs_seek/Pursuer.gd | 4 +--- project/demos/pursue_vs_seek/Ship.gd | 4 +--- project/demos/seek_and_flee/Boundary.gd | 4 +--- project/demos/seek_and_flee/Player.gd | 4 +--- project/demos/seek_and_flee/SeekFleeDemo.gd | 4 +--- project/demos/seek_and_flee/Seeker.gd | 4 +--- project/demos/seek_and_flee/Spawner.gd | 4 +--- project/src/GSTAgentLocation.gd | 4 +--- project/src/GSTSteeringAgent.gd | 4 +--- project/src/GSTSteeringBehavior.gd | 4 +--- project/src/GSTTargetAcceleration.gd | 4 +--- project/src/Utils.gd | 4 +--- project/src/behaviors/GSTArrive.gd | 6 ++---- project/src/behaviors/GSTBlend.gd | 12 +++++------- project/src/behaviors/GSTEvade.gd | 6 ++---- project/src/behaviors/GSTFace.gd | 6 ++---- project/src/behaviors/GSTFlee.gd | 4 +--- project/src/behaviors/GSTLookWhereYouGo.gd | 4 +--- project/src/behaviors/GSTMatchOrientation.gd | 6 ++---- project/src/behaviors/GSTPriority.gd | 6 ++---- project/src/behaviors/GSTPursue.gd | 6 ++---- project/src/behaviors/GSTSeek.gd | 4 +--- 24 files changed, 34 insertions(+), 82 deletions(-) diff --git a/project/demos/pursue_vs_seek/BoundaryManager.gd b/project/demos/pursue_vs_seek/BoundaryManager.gd index ea5bb00..8cb79f4 100644 --- a/project/demos/pursue_vs_seek/BoundaryManager.gd +++ b/project/demos/pursue_vs_seek/BoundaryManager.gd @@ -1,7 +1,5 @@ extends Node2D -""" -Wraps the ships' positions around the world border, and controls their rendering clones. -""" +# Wraps the ships' positions around the world border, and controls their rendering clones. onready var ShipType: = preload("res://demos/pursue_vs_seek/Ship.gd") diff --git a/project/demos/pursue_vs_seek/Player.gd b/project/demos/pursue_vs_seek/Player.gd index 111c013..b0b7762 100644 --- a/project/demos/pursue_vs_seek/Player.gd +++ b/project/demos/pursue_vs_seek/Player.gd @@ -1,7 +1,5 @@ extends "res://demos/pursue_vs_seek/Ship.gd" -""" -Controls the player ship's movements based on player input. -""" +# Controls the player ship's movements based on player input. onready var agent: = GSTSteeringAgent.new() diff --git a/project/demos/pursue_vs_seek/Pursuer.gd b/project/demos/pursue_vs_seek/Pursuer.gd index 52ea2a6..12ea4a6 100644 --- a/project/demos/pursue_vs_seek/Pursuer.gd +++ b/project/demos/pursue_vs_seek/Pursuer.gd @@ -1,7 +1,5 @@ extends "res://demos/pursue_vs_seek/Ship.gd" -""" -Represents a ship that chases after the player. -""" +# Represents a ship that chases after the player. onready var agent: = GSTSteeringAgent.new() diff --git a/project/demos/pursue_vs_seek/Ship.gd b/project/demos/pursue_vs_seek/Ship.gd index 5ef0e9c..7d9d770 100644 --- a/project/demos/pursue_vs_seek/Ship.gd +++ b/project/demos/pursue_vs_seek/Ship.gd @@ -1,7 +1,5 @@ extends KinematicBody2D -""" -Draws a notched triangle based on the vertices of the ship's polygon collider. -""" +# Draws a notched triangle based on the vertices of the ship's polygon collider. export var color: = Color() diff --git a/project/demos/seek_and_flee/Boundary.gd b/project/demos/seek_and_flee/Boundary.gd index 7bef08e..b5a9c03 100644 --- a/project/demos/seek_and_flee/Boundary.gd +++ b/project/demos/seek_and_flee/Boundary.gd @@ -1,7 +1,5 @@ extends StaticBody2D -""" -Draws the bounding box of the static body wall. -""" +# Draws the bounding box of the static body wall. var rect: Rect2 diff --git a/project/demos/seek_and_flee/Player.gd b/project/demos/seek_and_flee/Player.gd index bc943b6..037b73d 100644 --- a/project/demos/seek_and_flee/Player.gd +++ b/project/demos/seek_and_flee/Player.gd @@ -1,7 +1,5 @@ extends KinematicBody2D -""" -Class to control the player in basic left/right up/down movement. -""" +# Class to control the player in basic left/right up/down movement. onready var collision_shape: = $CollisionShape2D diff --git a/project/demos/seek_and_flee/SeekFleeDemo.gd b/project/demos/seek_and_flee/SeekFleeDemo.gd index d5a26d8..bf3bbc2 100644 --- a/project/demos/seek_and_flee/SeekFleeDemo.gd +++ b/project/demos/seek_and_flee/SeekFleeDemo.gd @@ -1,7 +1,5 @@ extends Node2D -""" -Access helper class for children to access window boundaries. -""" +# Access helper class for children to access window boundaries. onready var player: KinematicBody2D = $Player diff --git a/project/demos/seek_and_flee/Seeker.gd b/project/demos/seek_and_flee/Seeker.gd index 3dcc860..58473fd 100644 --- a/project/demos/seek_and_flee/Seeker.gd +++ b/project/demos/seek_and_flee/Seeker.gd @@ -1,7 +1,5 @@ extends KinematicBody2D -""" -AI agent that uses the Seek behavior to hone in on the player's location as directly as possible. -""" +# AI agent that uses the Seek behavior to hone in on the player's location as directly as possible. onready var collision_shape: = $CollisionShape2D diff --git a/project/demos/seek_and_flee/Spawner.gd b/project/demos/seek_and_flee/Spawner.gd index 6caa254..9d6cbc2 100644 --- a/project/demos/seek_and_flee/Spawner.gd +++ b/project/demos/seek_and_flee/Spawner.gd @@ -1,7 +1,5 @@ extends Node2D -""" -Holds data to instantiate and configure a number of agent entities. -""" +# Holds data to instantiate and configure a number of agent entities. export(PackedScene) var Entity: PackedScene diff --git a/project/src/GSTAgentLocation.gd b/project/src/GSTAgentLocation.gd index 4e5720e..df804c5 100644 --- a/project/src/GSTAgentLocation.gd +++ b/project/src/GSTAgentLocation.gd @@ -1,7 +1,5 @@ class_name GSTAgentLocation -""" -Data type to represent an agent with a location and an orientation -""" +# Data type to represent an agent with a location and an orientation var position: = Vector3.ZERO diff --git a/project/src/GSTSteeringAgent.gd b/project/src/GSTSteeringAgent.gd index 3a75d02..17b34b6 100644 --- a/project/src/GSTSteeringAgent.gd +++ b/project/src/GSTSteeringAgent.gd @@ -1,8 +1,6 @@ extends GSTAgentLocation class_name GSTSteeringAgent -""" -Extended agent data type that adds velocity and speed data. -""" +# Extended agent data type that adds velocity and speed data. var zero_linear_speed_threshold: = 0.01 diff --git a/project/src/GSTSteeringBehavior.gd b/project/src/GSTSteeringBehavior.gd index 16177ae..961c49a 100644 --- a/project/src/GSTSteeringBehavior.gd +++ b/project/src/GSTSteeringBehavior.gd @@ -1,7 +1,5 @@ class_name GSTSteeringBehavior -""" -Base class to calculate how an AI agent steers itself. -""" +# Base class to calculate how an AI agent steers itself. var enabled: = true diff --git a/project/src/GSTTargetAcceleration.gd b/project/src/GSTTargetAcceleration.gd index 8445262..a9caccf 100644 --- a/project/src/GSTTargetAcceleration.gd +++ b/project/src/GSTTargetAcceleration.gd @@ -1,7 +1,5 @@ class_name GSTTargetAcceleration -""" -A linear and angular amount of acceleration. -""" +# A linear and angular amount of acceleration. var linear: = Vector3.ZERO diff --git a/project/src/Utils.gd b/project/src/Utils.gd index bed6dd3..9433861 100644 --- a/project/src/Utils.gd +++ b/project/src/Utils.gd @@ -1,7 +1,5 @@ class_name Utils -""" -Useful math and utility functions to complement Godot's own. -""" +# Useful math and utility functions to complement Godot's own. static func clampedv3(vector: Vector3, limit: float) -> Vector3: diff --git a/project/src/behaviors/GSTArrive.gd b/project/src/behaviors/GSTArrive.gd index feedcc6..5d5ab59 100644 --- a/project/src/behaviors/GSTArrive.gd +++ b/project/src/behaviors/GSTArrive.gd @@ -1,9 +1,7 @@ extends GSTSteeringBehavior class_name GSTArrive -""" -Calculates acceleration to take an agent to its target's location. -The calculation will attempt to arrive with zero remaining velocity. -""" +# Calculates acceleration to take an agent to its target's location. +# The calculation will attempt to arrive with zero remaining velocity. var target: GSTAgentLocation diff --git a/project/src/behaviors/GSTBlend.gd b/project/src/behaviors/GSTBlend.gd index 1705553..7c76308 100644 --- a/project/src/behaviors/GSTBlend.gd +++ b/project/src/behaviors/GSTBlend.gd @@ -1,14 +1,12 @@ extends GSTSteeringBehavior class_name GSTBlend -""" -Blends multiple steering behaviors into one, and returns acceleration combining all of them. +# Blends multiple steering behaviors into one, and returns acceleration combining all of them. -Each behavior is associated with a weight - a modifier by which the result will be multiplied by, -then added to a total acceleration. +# # Each behavior is associated with a weight - a modifier by which the result will be multiplied by, +# then added to a total acceleration. -Each behavior is stored internally as a `Dictionary` with a `behavior` key with a value of type -`GSTSteeringBehavior` and a `weight` key with a value of type float. -""" +# # Each behavior is stored internally as a `Dictionary` with a `behavior` key with a value of type +# `GSTSteeringBehavior` and a `weight` key with a value of type float. onready var _behaviors: = [] diff --git a/project/src/behaviors/GSTEvade.gd b/project/src/behaviors/GSTEvade.gd index 001069c..ce89767 100644 --- a/project/src/behaviors/GSTEvade.gd +++ b/project/src/behaviors/GSTEvade.gd @@ -1,10 +1,8 @@ extends GSTPursue class_name GSTEvade -""" -Calculates acceleration to take an agent away from where a target agent will be. +# Calculates acceleration to take an agent away from where a target agent will be. -The `max_predict_time` variable represents how far ahead to calculate the intersection point. -""" +# # The `max_predict_time` variable represents how far ahead to calculate the intersection point. func _init( diff --git a/project/src/behaviors/GSTFace.gd b/project/src/behaviors/GSTFace.gd index c467bcf..7a5c3dd 100644 --- a/project/src/behaviors/GSTFace.gd +++ b/project/src/behaviors/GSTFace.gd @@ -1,9 +1,7 @@ extends GSTMatchOrientation class_name GSTFace -""" -Calculates angular acceleration to rotate a target to face its target's position. -The acceleration will attempt to arrive with zero remaining angular velocity. -""" +# Calculates angular acceleration to rotate a target to face its target's position. +# The acceleration will attempt to arrive with zero remaining angular velocity. func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent, target) -> void: diff --git a/project/src/behaviors/GSTFlee.gd b/project/src/behaviors/GSTFlee.gd index 73208b0..021ed24 100644 --- a/project/src/behaviors/GSTFlee.gd +++ b/project/src/behaviors/GSTFlee.gd @@ -1,8 +1,6 @@ extends GSTSeek class_name GSTFlee -""" -Calculates acceleration to take an agent directly away from a target agent. -""" +# Calculates acceleration to take an agent directly away from a target agent. func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent, target) -> void: diff --git a/project/src/behaviors/GSTLookWhereYouGo.gd b/project/src/behaviors/GSTLookWhereYouGo.gd index 26a261b..058becf 100644 --- a/project/src/behaviors/GSTLookWhereYouGo.gd +++ b/project/src/behaviors/GSTLookWhereYouGo.gd @@ -1,8 +1,6 @@ extends GSTMatchOrientation class_name GSTLookWhereYouGo -""" -Calculates an angular acceleration to match an agent's orientation to its direction of travel. -""" +# Calculates an angular acceleration to match an agent's orientation to its direction of travel. func _init(agent: GSTSteeringAgent).(agent, null) -> void: diff --git a/project/src/behaviors/GSTMatchOrientation.gd b/project/src/behaviors/GSTMatchOrientation.gd index cce5055..8185dc9 100644 --- a/project/src/behaviors/GSTMatchOrientation.gd +++ b/project/src/behaviors/GSTMatchOrientation.gd @@ -1,9 +1,7 @@ extends GSTSteeringBehavior class_name GSTMatchOrientation -""" -Calculates an angular acceleration to match an agent's orientation to its target's. -The calculation will attempt to arrive with zero remaining angular velocity. -""" +# Calculates an angular acceleration to match an agent's orientation to its target's. +# The calculation will attempt to arrive with zero remaining angular velocity. var target: GSTAgentLocation diff --git a/project/src/behaviors/GSTPriority.gd b/project/src/behaviors/GSTPriority.gd index 3f5a867..3c8dfa7 100644 --- a/project/src/behaviors/GSTPriority.gd +++ b/project/src/behaviors/GSTPriority.gd @@ -1,9 +1,7 @@ extends GSTSteeringBehavior class_name GSTPriority -""" -Contains multiple steering behaviors and returns only the result of the first that has a non-zero - acceleration. -""" +# Contains multiple steering behaviors and returns only the result of the first that has a non-zero + # acceleration. onready var _behaviors: = [] diff --git a/project/src/behaviors/GSTPursue.gd b/project/src/behaviors/GSTPursue.gd index ccb45f2..84b2efd 100644 --- a/project/src/behaviors/GSTPursue.gd +++ b/project/src/behaviors/GSTPursue.gd @@ -1,10 +1,8 @@ extends GSTSteeringBehavior class_name GSTPursue -""" -Calculates acceleration to take an agent to intersect with where a target agent will be. +# Calculates acceleration to take an agent to intersect with where a target agent will be. -The `max_predict_time` variable represents how far ahead to calculate the intersection point. -""" +# # The `max_predict_time` variable represents how far ahead to calculate the intersection point. var target: GSTSteeringAgent diff --git a/project/src/behaviors/GSTSeek.gd b/project/src/behaviors/GSTSeek.gd index 89a0b3d..7d9ee30 100644 --- a/project/src/behaviors/GSTSeek.gd +++ b/project/src/behaviors/GSTSeek.gd @@ -1,8 +1,6 @@ extends GSTSteeringBehavior class_name GSTSeek -""" -Calculates acceleration to take an agent to a target agent's position as directly as possible -""" +# Calculates acceleration to take an agent to a target agent's position as directly as possible var target: GSTAgentLocation From ac9934463366eac3eff203bcbafd005aba6e5cf0 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Wed, 8 Jan 2020 12:46:42 -0500 Subject: [PATCH 16/23] Implement Separation behavior and add Proximity --- project/project.godot | 24 +++++++++++ project/src/behaviors/GSTSeparation.gd | 40 +++++++++++++++++++ .../src/proximities/GSTInfiniteProximity.gd | 20 ++++++++++ project/src/proximities/GSTProximity.gd | 16 ++++++++ project/src/proximities/GSTRadiusProximity.gd | 33 +++++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 project/src/behaviors/GSTSeparation.gd create mode 100644 project/src/proximities/GSTInfiniteProximity.gd create mode 100644 project/src/proximities/GSTProximity.gd create mode 100644 project/src/proximities/GSTRadiusProximity.gd diff --git a/project/project.godot b/project/project.godot index 45baf3a..173cce5 100644 --- a/project/project.godot +++ b/project/project.godot @@ -39,6 +39,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTFlee.gd" }, { +"base": "GSTProximity", +"class": "GSTInfiniteProximity", +"language": "GDScript", +"path": "res://src/proximities/GSTInfiniteProximity.gd" +}, { "base": "GSTMatchOrientation", "class": "GSTLookWhereYouGo", "language": "GDScript", @@ -54,16 +59,31 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTPriority.gd" }, { +"base": "Reference", +"class": "GSTProximity", +"language": "GDScript", +"path": "res://src/proximities/GSTProximity.gd" +}, { "base": "GSTSteeringBehavior", "class": "GSTPursue", "language": "GDScript", "path": "res://src/behaviors/GSTPursue.gd" }, { +"base": "GSTProximity", +"class": "GSTRadiusProximity", +"language": "GDScript", +"path": "res://src/proximities/GSTRadiusProximity.gd" +}, { "base": "GSTSteeringBehavior", "class": "GSTSeek", "language": "GDScript", "path": "res://src/behaviors/GSTSeek.gd" }, { +"base": "GSTSteeringBehavior", +"class": "GSTSeparation", +"language": "GDScript", +"path": "res://src/behaviors/GSTSeparation.gd" +}, { "base": "GSTAgentLocation", "class": "GSTSteeringAgent", "language": "GDScript", @@ -91,11 +111,15 @@ _global_script_class_icons={ "GSTEvade": "", "GSTFace": "", "GSTFlee": "", +"GSTInfiniteProximity": "", "GSTLookWhereYouGo": "", "GSTMatchOrientation": "", "GSTPriority": "", +"GSTProximity": "", "GSTPursue": "", +"GSTRadiusProximity": "", "GSTSeek": "", +"GSTSeparation": "", "GSTSteeringAgent": "", "GSTSteeringBehavior": "", "GSTTargetAcceleration": "", diff --git a/project/src/behaviors/GSTSeparation.gd b/project/src/behaviors/GSTSeparation.gd new file mode 100644 index 0000000..f7fcf67 --- /dev/null +++ b/project/src/behaviors/GSTSeparation.gd @@ -0,0 +1,40 @@ +extends GSTSteeringBehavior +class_name GSTSeparation +# Group behavior that produces acceleration repelling from the other neighbors that are in the +# immediate area defined by the given `GSTProximity`. + +# # The produced acceleration is an average of all agents under consideration, multiplied by a +# # strength decreasing by the inverse square law in relation to distance, and accumulated. +# # In effect, all neighbors produce a single repelling force. + + +var decay_coefficient: = 1.0 + +var acceleration: GSTTargetAcceleration +var proximity: GSTProximity + + +func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void: + self.proximity = proximity + + +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + acceleration.set_zero() + self.acceleration = acceleration + proximity.find_neighbors(funcref(self, "_report_neighbor")) + return acceleration + + +func _report_neighbor(neighbor: GSTSteeringAgent) -> bool: + var to_agent: = agent.position - neighbor.position + + var distance_squared: = to_agent.length_squared() + var max_acceleration: = agent.max_linear_acceleration + + var strength: = decay_coefficient / distance_squared + if strength > max_acceleration: + strength = max_acceleration + + acceleration.linear += to_agent * (strength / sqrt(distance_squared)) + + return true diff --git a/project/src/proximities/GSTInfiniteProximity.gd b/project/src/proximities/GSTInfiniteProximity.gd new file mode 100644 index 0000000..07ffbfd --- /dev/null +++ b/project/src/proximities/GSTInfiniteProximity.gd @@ -0,0 +1,20 @@ +extends GSTProximity +class_name GSTInfiniteProximity +# Specifies any agent that is in the specified list as being neighbors with the owner agent. + + +func _init(agent: GSTSteeringAgent, agents: Array).(agent, agents) -> void: + pass + + +func find_neighbors(callback: FuncRef) -> int: + var neighbor_count: = 0 + var agent_count: = agents.size() + for i in range(agent_count): + var current_agent: = agents[i] as GSTSteeringAgent + + if current_agent != agent: + if callback.call_func(current_agent): + neighbor_count += 1 + + return neighbor_count diff --git a/project/src/proximities/GSTProximity.gd b/project/src/proximities/GSTProximity.gd new file mode 100644 index 0000000..36410ee --- /dev/null +++ b/project/src/proximities/GSTProximity.gd @@ -0,0 +1,16 @@ +extends Reference +class_name GSTProximity +# Defines an area that is used by group behaviors to find and process the owner's neighbors. + + +var agent: GSTSteeringAgent +var agents: = [] + + +func _init(agent: GSTSteeringAgent, agents: Array) -> void: + self.agent = agent + self.agents = agents + + +func find_neighbors(callback: FuncRef) -> int: + return 0 \ No newline at end of file diff --git a/project/src/proximities/GSTRadiusProximity.gd b/project/src/proximities/GSTRadiusProximity.gd new file mode 100644 index 0000000..3014399 --- /dev/null +++ b/project/src/proximities/GSTRadiusProximity.gd @@ -0,0 +1,33 @@ +extends GSTProximity +class_name GSTRadiusProximity +# Specifies any agent that is in the specified list as being neighbors with the owner agent if they +# lie within the specified radius. + + +var radius: = 0.0 + + +func _init(agent: GSTSteeringAgent, agents: Array, radius: float).(agent, agents) -> void: + self.radius = radius + + +func find_neighbors(callback: FuncRef) -> int: + var agent_count: = agents.size() + var neighbor_count: = 0 + + var owner_position: = agent.position + + for i in range(agent_count): + var current_agent: = agents[i] as GSTSteeringAgent + + if current_agent != agent: + var distance_squared: = owner_position.distance_squared_to(current_agent.position) + + var range_to: = radius + current_agent.bounding_radius + + if distance_squared < range_to * range_to: + if callback.call_func(current_agent) == true: + neighbor_count += 1 + continue + + return neighbor_count From 34b58a6bba98c3a8e0700e2312f023a793e7a561 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Thu, 9 Jan 2020 12:24:55 -0500 Subject: [PATCH 17/23] Add Cohesion behavior and RadiusProximity caching --- project/project.godot | 24 +++++++++++ project/src/GSTSteeringAgent.gd | 1 + project/src/behaviors/GSTCohesion.gd | 27 ++++++++++++ project/src/proximities/GSTProximity.gd | 32 +++++++------- project/src/proximities/GSTRadiusProximity.gd | 42 +++++++++++++------ 5 files changed, 98 insertions(+), 28 deletions(-) create mode 100644 project/src/behaviors/GSTCohesion.gd diff --git a/project/project.godot b/project/project.godot index 173cce5..c5b5251 100644 --- a/project/project.godot +++ b/project/project.godot @@ -20,10 +20,20 @@ _global_script_classes=[ { "path": "res://src/behaviors/GSTArrive.gd" }, { "base": "GSTSteeringBehavior", +"class": "GSTAvoidCollisions", +"language": "GDScript", +"path": "res://src/behaviors/GSTAvoidCollisions.gd" +}, { +"base": "GSTSteeringBehavior", "class": "GSTBlend", "language": "GDScript", "path": "res://src/behaviors/GSTBlend.gd" }, { +"base": "GSTSteeringBehavior", +"class": "GSTCohesion", +"language": "GDScript", +"path": "res://src/behaviors/GSTCohesion.gd" +}, { "base": "GSTPursue", "class": "GSTEvade", "language": "GDScript", @@ -39,6 +49,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTFlee.gd" }, { +"base": "GSTArrive", +"class": "GSTFollowPath", +"language": "GDScript", +"path": "res://src/behaviors/GSTFollowPath.gd" +}, { "base": "GSTProximity", "class": "GSTInfiniteProximity", "language": "GDScript", @@ -54,6 +69,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTMatchOrientation.gd" }, { +"base": "Reference", +"class": "GSTPath", +"language": "GDScript", +"path": "res://src/GSTPath.gd" +}, { "base": "GSTSteeringBehavior", "class": "GSTPriority", "language": "GDScript", @@ -107,13 +127,17 @@ _global_script_classes=[ { _global_script_class_icons={ "GSTAgentLocation": "", "GSTArrive": "", +"GSTAvoidCollisions": "", "GSTBlend": "", +"GSTCohesion": "", "GSTEvade": "", "GSTFace": "", "GSTFlee": "", +"GSTFollowPath": "", "GSTInfiniteProximity": "", "GSTLookWhereYouGo": "", "GSTMatchOrientation": "", +"GSTPath": "", "GSTPriority": "", "GSTProximity": "", "GSTPursue": "", diff --git a/project/src/GSTSteeringAgent.gd b/project/src/GSTSteeringAgent.gd index 17b34b6..c8a17b9 100644 --- a/project/src/GSTSteeringAgent.gd +++ b/project/src/GSTSteeringAgent.gd @@ -11,3 +11,4 @@ var max_angular_acceleration: = 0.0 var linear_velocity: = Vector3.ZERO var angular_velocity: = 0.0 var bounding_radius: = 0.0 +var tagged: = false diff --git a/project/src/behaviors/GSTCohesion.gd b/project/src/behaviors/GSTCohesion.gd new file mode 100644 index 0000000..08cecee --- /dev/null +++ b/project/src/behaviors/GSTCohesion.gd @@ -0,0 +1,27 @@ +extends GSTSteeringBehavior +class_name GSTCohesion +# Group behavior that produces linear acceleration that attempts to move the agent towards the +# center of mass of the agents in the area defined by the defined Proximity. + + +var center_of_mass: Vector3 +var proximity: GSTProximity + + +func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void: + self.proximity = proximity + + +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + acceleration.set_zero() + center_of_mass = Vector3.ZERO + var neighbor_count = proximity.find_neighbors(funcref(self, "_report_neighbor")) + if neighbor_count > 0: + center_of_mass *= 1.0 / neighbor_count + acceleration.linear = (center_of_mass - agent.position).normalized() * agent.max_linear_acceleration + return acceleration + + +func _report_neighbor(neighbor: GSTSteeringAgent) -> bool: + center_of_mass += neighbor.position + return true diff --git a/project/src/proximities/GSTProximity.gd b/project/src/proximities/GSTProximity.gd index 36410ee..9eb5f9d 100644 --- a/project/src/proximities/GSTProximity.gd +++ b/project/src/proximities/GSTProximity.gd @@ -1,16 +1,16 @@ -extends Reference -class_name GSTProximity -# Defines an area that is used by group behaviors to find and process the owner's neighbors. - - -var agent: GSTSteeringAgent -var agents: = [] - - -func _init(agent: GSTSteeringAgent, agents: Array) -> void: - self.agent = agent - self.agents = agents - - -func find_neighbors(callback: FuncRef) -> int: - return 0 \ No newline at end of file +extends Reference +class_name GSTProximity +# Defines an area that is used by group behaviors to find and process the owner's neighbors. + + +var agent: GSTSteeringAgent +var agents: = [] + + +func _init(agent: GSTSteeringAgent, agents: Array) -> void: + self.agent = agent + self.agents = agents + + +func find_neighbors(callback: FuncRef) -> int: + return 0 diff --git a/project/src/proximities/GSTRadiusProximity.gd b/project/src/proximities/GSTRadiusProximity.gd index 3014399..2e5bbd8 100644 --- a/project/src/proximities/GSTRadiusProximity.gd +++ b/project/src/proximities/GSTRadiusProximity.gd @@ -6,28 +6,46 @@ class_name GSTRadiusProximity var radius: = 0.0 +var _last_frame: = 0 +var _scene_tree: SceneTree + func _init(agent: GSTSteeringAgent, agents: Array, radius: float).(agent, agents) -> void: self.radius = radius + _scene_tree = Engine.get_main_loop() func find_neighbors(callback: FuncRef) -> int: var agent_count: = agents.size() var neighbor_count: = 0 - - var owner_position: = agent.position - for i in range(agent_count): - var current_agent: = agents[i] as GSTSteeringAgent - - if current_agent != agent: - var distance_squared: = owner_position.distance_squared_to(current_agent.position) - - var range_to: = radius + current_agent.bounding_radius - - if distance_squared < range_to * range_to: + var current_frame: = _scene_tree.get_frame() if _scene_tree else -_last_frame + if current_frame != _last_frame: + _last_frame = current_frame + + var owner_position: = agent.position + + for i in range(agent_count): + var current_agent: = agents[i] as GSTSteeringAgent + + if current_agent != agent: + var distance_squared: = owner_position.distance_squared_to(current_agent.position) + + var range_to: = radius + current_agent.bounding_radius + + if distance_squared < range_to * range_to: + if callback.call_func(current_agent) == true: + current_agent.tagged = true + neighbor_count += 1 + continue + + current_agent.tagged = false + else: + for i in range(agent_count): + var current_agent = agents[i] as GSTSteeringAgent + + if current_agent != agent and current_agent.tagged: if callback.call_func(current_agent) == true: neighbor_count += 1 - continue return neighbor_count From 84f0465b88e3c8a6e57a72705629669a0d313bfd Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Thu, 9 Jan 2020 12:25:48 -0500 Subject: [PATCH 18/23] Add AvoidCollision behavior --- project/src/behaviors/GSTAvoidCollisions.gd | 66 +++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 project/src/behaviors/GSTAvoidCollisions.gd diff --git a/project/src/behaviors/GSTAvoidCollisions.gd b/project/src/behaviors/GSTAvoidCollisions.gd new file mode 100644 index 0000000..3dad94c --- /dev/null +++ b/project/src/behaviors/GSTAvoidCollisions.gd @@ -0,0 +1,66 @@ +extends GSTSteeringBehavior +class_name GSTAvoidCollisions +# Behavior that steers the agent to avoid obstacles lying in its path, approximated by a sphere. + + +var proximity: GSTProximity +var first_neighbor: GSTSteeringAgent +var shortest_time: float +var first_minimum_separation: float +var first_distance: float +var first_relative_position: Vector3 +var first_relative_velocity: Vector3 + + +func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void: + self.proximity = proximity + + +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + shortest_time = INF + first_neighbor = null + first_minimum_separation = 0 + first_distance = 0 + + var neighbor_count: = proximity.find_neighbors(funcref(self, "_report_neighbor")) + + if neighbor_count == 0 or not first_neighbor: + acceleration.set_zero() + else: + if( + first_minimum_separation <= 0 or + first_distance < agent.bounding_radius + first_neighbor.bounding_radius): + acceleration.linear = first_neighbor.position - agent.position + else: + acceleration.linear = first_relative_position + (first_relative_velocity * shortest_time) + acceleration.linear = acceleration.linear.normalized() * -agent.max_linear_acceleration + acceleration.angular = 0 + + return acceleration + + +func _report_neighbor(neighbor: GSTSteeringAgent) -> bool: + var relative_position: = neighbor.position - agent.position + var relative_velocity: = neighbor.linear_velocity - agent.linear_velocity + var relative_speed_squared: = relative_velocity.length_squared() + + if relative_speed_squared == 0: + return false + else: + var time_to_collision = -relative_position.dot(relative_velocity) / relative_speed_squared + + if time_to_collision <= 0 or time_to_collision >= shortest_time: + return false + else: + var distance = relative_position.length() + var minimum_separation: float = distance - sqrt(relative_speed_squared) * time_to_collision + if minimum_separation > agent.bounding_radius + neighbor.bounding_radius: + return false + else: + shortest_time = time_to_collision + first_neighbor = neighbor + first_minimum_separation = minimum_separation + first_distance = distance + first_relative_position = relative_position + first_relative_velocity = relative_velocity + return true From 780e6038b81bcb961463977f02b0338bd83ed1e0 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Thu, 9 Jan 2020 12:26:35 -0500 Subject: [PATCH 19/23] Add FollowPath behavior --- project/src/GSTPath.gd | 120 +++++++++++++++++++++++++ project/src/behaviors/GSTFollowPath.gd | 47 ++++++++++ 2 files changed, 167 insertions(+) create mode 100644 project/src/GSTPath.gd create mode 100644 project/src/behaviors/GSTFollowPath.gd diff --git a/project/src/GSTPath.gd b/project/src/GSTPath.gd new file mode 100644 index 0000000..7fbb733 --- /dev/null +++ b/project/src/GSTPath.gd @@ -0,0 +1,120 @@ +extends Reference +class_name GSTPath + + +var segments: Array +var is_open: bool +var path_length: float + +var nearest_point_on_segment: Vector3 +var nearest_point_on_path: Vector3 + + +func _init(waypoints: Array, is_open: = false) -> void: + self.is_open = is_open + _create_path(waypoints) + nearest_point_on_segment = waypoints[0] + nearest_point_on_path = waypoints[0] + + +func get_start_point() -> Vector3: + return segments.front().begin + + +func get_end_point() -> Vector3: + return segments.back().end + + +func calculate_point_segment_distance_squared(a: Vector3, b: Vector3, c: Vector3) -> float: + nearest_point_on_segment = a + var ab: = b - a + var ab_length_squared: = ab.length_squared() + if ab_length_squared != 0: + var t = (c - a).dot(ab) / ab_length_squared + nearest_point_on_segment += ab * clamp(t, 0, 1) + + return nearest_point_on_segment.distance_squared_to(c) + + +func calculate_distance(agent_current_position: Vector3, path_parameter: Dictionary) -> float: + var smallest_distance_squared: float = INF + var nearest_segment: GSTSegment + for i in range(segments.size()): + var segment: GSTSegment = segments[i] + var distance_squared: = calculate_point_segment_distance_squared( + segment.begin, + segment.end, + agent_current_position) + + if distance_squared < smallest_distance_squared: + nearest_point_on_path = nearest_point_on_segment + smallest_distance_squared = distance_squared + nearest_segment = segment + path_parameter.segment_index = i + + var length_on_path: = ( + nearest_segment.cumulative_length - + nearest_point_on_path.distance_to(nearest_segment.end)) + + path_parameter.distance = length_on_path + + return length_on_path + + +func calculate_target_position(param: Dictionary, target_distance: float) -> Vector3: + if is_open: + target_distance = clamp(target_distance, 0, path_length) + else: + if target_distance < 0: + target_distance = path_length + fmod(target_distance, path_length) + elif target_distance > path_length: + target_distance = fmod(target_distance, path_length) + + var desired_segment: GSTSegment + for i in range(segments.size()): + var segment: GSTSegment = segments[i] + if segment.cumulative_length >= target_distance: + desired_segment = segment + break + + var distance: = desired_segment.cumulative_length - target_distance + + return ( + (desired_segment.begin - desired_segment.end) * + (distance / desired_segment.length) + desired_segment.end) + + +func _create_path(waypoints: Array) -> void: + if not waypoints or waypoints.size() < 2: + printerr("Waypoints cannot be null and must contain at least two (2) waypoints.") + + segments = [] + path_length = 0 + var current: Vector3 = segments[0] + var previous: Vector3 + + for i in range(1, waypoints.size(), 1): + previous = current + if i < waypoints.size(): + current = waypoints[i] + elif is_open: + break + else: + current = waypoints[0] + var segment: = GSTSegment.new(previous, current) + path_length += segment.length + segment.cumulative_length = path_length + segments.append(segment) + + +class GSTSegment: + var begin: Vector3 + var end: Vector3 + var length: float + var cumulative_length: float + + + func _init(begin: Vector3, end: Vector3) -> void: + self.begin = begin + self.end = end + length = begin.distance_to(end) diff --git a/project/src/behaviors/GSTFollowPath.gd b/project/src/behaviors/GSTFollowPath.gd new file mode 100644 index 0000000..49699a3 --- /dev/null +++ b/project/src/behaviors/GSTFollowPath.gd @@ -0,0 +1,47 @@ +extends GSTArrive +class_name GSTFollowPath +# Produces a linear acceleration that moves the agent along the specified path. + + +var path: GSTPath +var path_offset: = 0.0 + +var path_param: = {} + +var arrive_enabled: = true +var prediction_time: = 0.0 + + +func _init( + agent: GSTSteeringAgent, + path: GSTPath, + path_offset: = 0.0, + prediction_time: = 0.0).(agent, null) -> void: + self.path = path + self.path_offset = path_offset + self.prediction_time = prediction_time + + +func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: + var location: = ( + agent.position if prediction_time == 0 + else agent.position + (agent.linear_velocity * prediction_time)) + + var distance: = path.calculate_distance(location, path_param) + var target_distance: = distance + path_offset + + var target_position: = path.calculate_target_position(path_param, target_distance) + + if arrive_enabled and path.is_open: + if path_offset >= 0: + if target_distance > path.length - deceleration_radius: + return _arrive(acceleration, target_position) + else: + if target_distance < deceleration_radius: + return _arrive(acceleration, target_position) + + acceleration.linear = (target_position - agent.position).normalized() + acceleration.linear *= agent.max_linear_acceleration + acceleration.angular = 0 + + return acceleration From a01f5d5b2e3bc469ae1fbea2f2977c1d38f57e7e Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Fri, 10 Jan 2020 12:15:50 -0500 Subject: [PATCH 20/23] Clean up and improve group behaviors' code The first pass was somewhat obtuse and lacked a common class that differentiated them from behaviors that didn't use Proximities. --- project/project.godot | 18 ++- project/src/GSTGroupBehavior.gd | 16 +++ project/src/GSTPath.gd | 107 +++++++++--------- project/src/GSTSteeringAgent.gd | 2 +- project/src/{Utils.gd => GSTUtils.gd} | 2 +- project/src/behaviors/GSTArrive.gd | 2 +- project/src/behaviors/GSTAvoidCollisions.gd | 11 +- project/src/behaviors/GSTBlend.gd | 2 +- project/src/behaviors/GSTCohesion.gd | 11 +- project/src/behaviors/GSTSeparation.gd | 11 +- .../src/proximities/GSTInfiniteProximity.gd | 2 +- project/src/proximities/GSTProximity.gd | 3 +- project/src/proximities/GSTRadiusProximity.gd | 8 +- 13 files changed, 110 insertions(+), 85 deletions(-) create mode 100644 project/src/GSTGroupBehavior.gd rename project/src/{Utils.gd => GSTUtils.gd} (93%) diff --git a/project/project.godot b/project/project.godot index c5b5251..fc258be 100644 --- a/project/project.godot +++ b/project/project.godot @@ -19,7 +19,7 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTArrive.gd" }, { -"base": "GSTSteeringBehavior", +"base": "GSTGroupBehavior", "class": "GSTAvoidCollisions", "language": "GDScript", "path": "res://src/behaviors/GSTAvoidCollisions.gd" @@ -29,7 +29,7 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTBlend.gd" }, { -"base": "GSTSteeringBehavior", +"base": "GSTGroupBehavior", "class": "GSTCohesion", "language": "GDScript", "path": "res://src/behaviors/GSTCohesion.gd" @@ -54,6 +54,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTFollowPath.gd" }, { +"base": "GSTSteeringBehavior", +"class": "GSTGroupBehavior", +"language": "GDScript", +"path": "res://src/GSTGroupBehavior.gd" +}, { "base": "GSTProximity", "class": "GSTInfiniteProximity", "language": "GDScript", @@ -99,7 +104,7 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/behaviors/GSTSeek.gd" }, { -"base": "GSTSteeringBehavior", +"base": "GSTGroupBehavior", "class": "GSTSeparation", "language": "GDScript", "path": "res://src/behaviors/GSTSeparation.gd" @@ -120,9 +125,9 @@ _global_script_classes=[ { "path": "res://src/GSTTargetAcceleration.gd" }, { "base": "Reference", -"class": "Utils", +"class": "GSTUtils", "language": "GDScript", -"path": "res://src/Utils.gd" +"path": "res://src/GSTUtils.gd" } ] _global_script_class_icons={ "GSTAgentLocation": "", @@ -134,6 +139,7 @@ _global_script_class_icons={ "GSTFace": "", "GSTFlee": "", "GSTFollowPath": "", +"GSTGroupBehavior": "", "GSTInfiniteProximity": "", "GSTLookWhereYouGo": "", "GSTMatchOrientation": "", @@ -147,7 +153,7 @@ _global_script_class_icons={ "GSTSteeringAgent": "", "GSTSteeringBehavior": "", "GSTTargetAcceleration": "", -"Utils": "" +"GSTUtils": "" } [application] diff --git a/project/src/GSTGroupBehavior.gd b/project/src/GSTGroupBehavior.gd new file mode 100644 index 0000000..5a38843 --- /dev/null +++ b/project/src/GSTGroupBehavior.gd @@ -0,0 +1,16 @@ +extends GSTSteeringBehavior +class_name GSTGroupBehavior +# Extended behavior that features a Proximity group for group-based behaviors. + + +var proximity: GSTProximity + +var _callback: = funcref(self, "report_neighbor") + + +func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void: + self.proximity = proximity + + +func report_neighbor(neighbor: GSTSteeringAgent) -> bool: + return false diff --git a/project/src/GSTPath.gd b/project/src/GSTPath.gd index 7fbb733..4277025 100644 --- a/project/src/GSTPath.gd +++ b/project/src/GSTPath.gd @@ -1,60 +1,69 @@ extends Reference class_name GSTPath +# Represents a path made up of Vector3 waypoints, split into path segments for use by path +# following algorithms. + +# # Keeping it updated requires calling `create_path` to update the path. -var segments: Array -var is_open: bool +var open: bool var path_length: float -var nearest_point_on_segment: Vector3 -var nearest_point_on_path: Vector3 +var _segments: Array + +var _nearest_point_on_segment: Vector3 +var _nearest_point_on_path: Vector3 func _init(waypoints: Array, is_open: = false) -> void: self.is_open = is_open - _create_path(waypoints) - nearest_point_on_segment = waypoints[0] - nearest_point_on_path = waypoints[0] + create_path(waypoints) + _nearest_point_on_segment = waypoints[0] + _nearest_point_on_path = waypoints[0] -func get_start_point() -> Vector3: - return segments.front().begin - - -func get_end_point() -> Vector3: - return segments.back().end - - -func calculate_point_segment_distance_squared(a: Vector3, b: Vector3, c: Vector3) -> float: - nearest_point_on_segment = a - var ab: = b - a - var ab_length_squared: = ab.length_squared() - if ab_length_squared != 0: - var t = (c - a).dot(ab) / ab_length_squared - nearest_point_on_segment += ab * clamp(t, 0, 1) +func create_path(waypoints: Array) -> void: + if not waypoints or waypoints.size() < 2: + printerr("Waypoints cannot be null and must contain at least two (2) waypoints.") - return nearest_point_on_segment.distance_squared_to(c) + _segments = [] + path_length = 0 + var current: Vector3 = _segments[0] + var previous: Vector3 + + for i in range(1, waypoints.size(), 1): + previous = current + if i < waypoints.size(): + current = waypoints[i] + elif open: + break + else: + current = waypoints[0] + var segment: = GSTSegment.new(previous, current) + path_length += segment.length + segment.cumulative_length = path_length + _segments.append(segment) func calculate_distance(agent_current_position: Vector3, path_parameter: Dictionary) -> float: var smallest_distance_squared: float = INF var nearest_segment: GSTSegment - for i in range(segments.size()): - var segment: GSTSegment = segments[i] - var distance_squared: = calculate_point_segment_distance_squared( + for i in range(_segments.size()): + var segment: GSTSegment = _segments[i] + var distance_squared: = _calculate_point_segment_distance_squared( segment.begin, segment.end, agent_current_position) if distance_squared < smallest_distance_squared: - nearest_point_on_path = nearest_point_on_segment + _nearest_point_on_path = _nearest_point_on_segment smallest_distance_squared = distance_squared nearest_segment = segment path_parameter.segment_index = i var length_on_path: = ( nearest_segment.cumulative_length - - nearest_point_on_path.distance_to(nearest_segment.end)) + _nearest_point_on_path.distance_to(nearest_segment.end)) path_parameter.distance = length_on_path @@ -62,7 +71,7 @@ func calculate_distance(agent_current_position: Vector3, path_parameter: Diction func calculate_target_position(param: Dictionary, target_distance: float) -> Vector3: - if is_open: + if open: target_distance = clamp(target_distance, 0, path_length) else: if target_distance < 0: @@ -71,8 +80,8 @@ func calculate_target_position(param: Dictionary, target_distance: float) -> Vec target_distance = fmod(target_distance, path_length) var desired_segment: GSTSegment - for i in range(segments.size()): - var segment: GSTSegment = segments[i] + for i in range(_segments.size()): + var segment: GSTSegment = _segments[i] if segment.cumulative_length >= target_distance: desired_segment = segment break @@ -84,27 +93,23 @@ func calculate_target_position(param: Dictionary, target_distance: float) -> Vec (distance / desired_segment.length) + desired_segment.end) -func _create_path(waypoints: Array) -> void: - if not waypoints or waypoints.size() < 2: - printerr("Waypoints cannot be null and must contain at least two (2) waypoints.") +func get_start_point() -> Vector3: + return _segments.front().begin + + +func get_end_point() -> Vector3: + return _segments.back().end + + +func _calculate_point_segment_distance_squared(start: Vector3, end: Vector3, position: Vector3) -> float: + _nearest_point_on_segment = start + var start_end: = end - start + var start_end_length_squared: = start_end.length_squared() + if start_end_length_squared != 0: + var t = (position - start).dot(start_end) / start_end_length_squared + _nearest_point_on_segment += start_end * clamp(t, 0, 1) - segments = [] - path_length = 0 - var current: Vector3 = segments[0] - var previous: Vector3 - - for i in range(1, waypoints.size(), 1): - previous = current - if i < waypoints.size(): - current = waypoints[i] - elif is_open: - break - else: - current = waypoints[0] - var segment: = GSTSegment.new(previous, current) - path_length += segment.length - segment.cumulative_length = path_length - segments.append(segment) + return _nearest_point_on_segment.distance_squared_to(position) class GSTSegment: diff --git a/project/src/GSTSteeringAgent.gd b/project/src/GSTSteeringAgent.gd index c8a17b9..68c787a 100644 --- a/project/src/GSTSteeringAgent.gd +++ b/project/src/GSTSteeringAgent.gd @@ -1,6 +1,6 @@ extends GSTAgentLocation class_name GSTSteeringAgent -# Extended agent data type that adds velocity and speed data. +# Extended agent data type that adds velocity, speed, and size data var zero_linear_speed_threshold: = 0.01 diff --git a/project/src/Utils.gd b/project/src/GSTUtils.gd similarity index 93% rename from project/src/Utils.gd rename to project/src/GSTUtils.gd index 9433861..b366ff5 100644 --- a/project/src/Utils.gd +++ b/project/src/GSTUtils.gd @@ -1,4 +1,4 @@ -class_name Utils +class_name GSTUtils # Useful math and utility functions to complement Godot's own. diff --git a/project/src/behaviors/GSTArrive.gd b/project/src/behaviors/GSTArrive.gd index 5d5ab59..eeb84c0 100644 --- a/project/src/behaviors/GSTArrive.gd +++ b/project/src/behaviors/GSTArrive.gd @@ -30,7 +30,7 @@ func _arrive(acceleration: GSTTargetAcceleration, target_position: Vector3) -> G desired_velocity = (desired_velocity - agent.linear_velocity) * 1.0 / time_to_reach - acceleration.linear = Utils.clampedv3(desired_velocity, agent.max_linear_acceleration) + acceleration.linear = GSTUtils.clampedv3(desired_velocity, agent.max_linear_acceleration) acceleration.angular = 0 return acceleration diff --git a/project/src/behaviors/GSTAvoidCollisions.gd b/project/src/behaviors/GSTAvoidCollisions.gd index 3dad94c..d4ed8d2 100644 --- a/project/src/behaviors/GSTAvoidCollisions.gd +++ b/project/src/behaviors/GSTAvoidCollisions.gd @@ -1,9 +1,8 @@ -extends GSTSteeringBehavior +extends GSTGroupBehavior class_name GSTAvoidCollisions # Behavior that steers the agent to avoid obstacles lying in its path, approximated by a sphere. -var proximity: GSTProximity var first_neighbor: GSTSteeringAgent var shortest_time: float var first_minimum_separation: float @@ -12,8 +11,8 @@ var first_relative_position: Vector3 var first_relative_velocity: Vector3 -func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void: - self.proximity = proximity +func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) -> void: + pass func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: @@ -22,7 +21,7 @@ func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAccele first_minimum_separation = 0 first_distance = 0 - var neighbor_count: = proximity.find_neighbors(funcref(self, "_report_neighbor")) + var neighbor_count: = proximity.find_neighbors(_callback) if neighbor_count == 0 or not first_neighbor: acceleration.set_zero() @@ -39,7 +38,7 @@ func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAccele return acceleration -func _report_neighbor(neighbor: GSTSteeringAgent) -> bool: +func report_neighbor(neighbor: GSTSteeringAgent) -> bool: var relative_position: = neighbor.position - agent.position var relative_velocity: = neighbor.linear_velocity - agent.linear_velocity var relative_speed_squared: = relative_velocity.length_squared() diff --git a/project/src/behaviors/GSTBlend.gd b/project/src/behaviors/GSTBlend.gd index 7c76308..33f0699 100644 --- a/project/src/behaviors/GSTBlend.gd +++ b/project/src/behaviors/GSTBlend.gd @@ -38,7 +38,7 @@ func _calculate_steering(blended_accel: GSTTargetAcceleration) -> GSTTargetAccel blended_accel.add_scaled_accel(_accel, bw.weight) - blended_accel.linear = Utils.clampedv3(blended_accel.linear, agent.max_linear_acceleration) + blended_accel.linear = GSTUtils.clampedv3(blended_accel.linear, agent.max_linear_acceleration) blended_accel.angular = min(blended_accel.angular, agent.max_angular_acceleration) return blended_accel diff --git a/project/src/behaviors/GSTCohesion.gd b/project/src/behaviors/GSTCohesion.gd index 08cecee..12fe0ac 100644 --- a/project/src/behaviors/GSTCohesion.gd +++ b/project/src/behaviors/GSTCohesion.gd @@ -1,27 +1,26 @@ -extends GSTSteeringBehavior +extends GSTGroupBehavior class_name GSTCohesion # Group behavior that produces linear acceleration that attempts to move the agent towards the # center of mass of the agents in the area defined by the defined Proximity. var center_of_mass: Vector3 -var proximity: GSTProximity -func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void: - self.proximity = proximity +func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) -> void: + pass func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: acceleration.set_zero() center_of_mass = Vector3.ZERO - var neighbor_count = proximity.find_neighbors(funcref(self, "_report_neighbor")) + var neighbor_count = proximity.find_neighbors(_callback) if neighbor_count > 0: center_of_mass *= 1.0 / neighbor_count acceleration.linear = (center_of_mass - agent.position).normalized() * agent.max_linear_acceleration return acceleration -func _report_neighbor(neighbor: GSTSteeringAgent) -> bool: +func report_neighbor(neighbor: GSTSteeringAgent) -> bool: center_of_mass += neighbor.position return true diff --git a/project/src/behaviors/GSTSeparation.gd b/project/src/behaviors/GSTSeparation.gd index f7fcf67..9d9a573 100644 --- a/project/src/behaviors/GSTSeparation.gd +++ b/project/src/behaviors/GSTSeparation.gd @@ -1,4 +1,4 @@ -extends GSTSteeringBehavior +extends GSTGroupBehavior class_name GSTSeparation # Group behavior that produces acceleration repelling from the other neighbors that are in the # immediate area defined by the given `GSTProximity`. @@ -11,21 +11,20 @@ class_name GSTSeparation var decay_coefficient: = 1.0 var acceleration: GSTTargetAcceleration -var proximity: GSTProximity -func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void: - self.proximity = proximity +func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) -> void: + pass func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: acceleration.set_zero() self.acceleration = acceleration - proximity.find_neighbors(funcref(self, "_report_neighbor")) + proximity.find_neighbors(_callback) return acceleration -func _report_neighbor(neighbor: GSTSteeringAgent) -> bool: +func report_neighbor(neighbor: GSTSteeringAgent) -> bool: var to_agent: = agent.position - neighbor.position var distance_squared: = to_agent.length_squared() diff --git a/project/src/proximities/GSTInfiniteProximity.gd b/project/src/proximities/GSTInfiniteProximity.gd index 07ffbfd..0dd9b17 100644 --- a/project/src/proximities/GSTInfiniteProximity.gd +++ b/project/src/proximities/GSTInfiniteProximity.gd @@ -1,6 +1,6 @@ extends GSTProximity class_name GSTInfiniteProximity -# Specifies any agent that is in the specified list as being neighbors with the owner agent. +# Determines any agent that is in the specified list as being neighbors with the owner agent. func _init(agent: GSTSteeringAgent, agents: Array).(agent, agents) -> void: diff --git a/project/src/proximities/GSTProximity.gd b/project/src/proximities/GSTProximity.gd index 9eb5f9d..f746410 100644 --- a/project/src/proximities/GSTProximity.gd +++ b/project/src/proximities/GSTProximity.gd @@ -1,6 +1,7 @@ extends Reference class_name GSTProximity -# Defines an area that is used by group behaviors to find and process the owner's neighbors. +# Defines a way to determine any agent that is in the specified list as being neighbors with the +# owner agent. var agent: GSTSteeringAgent diff --git a/project/src/proximities/GSTRadiusProximity.gd b/project/src/proximities/GSTRadiusProximity.gd index 2e5bbd8..300fd11 100644 --- a/project/src/proximities/GSTRadiusProximity.gd +++ b/project/src/proximities/GSTRadiusProximity.gd @@ -1,7 +1,7 @@ extends GSTProximity class_name GSTRadiusProximity -# Specifies any agent that is in the specified list as being neighbors with the owner agent if they -# lie within the specified radius. +# Determines any agent that is in the specified list as being neighbors with the owner agent if +# they lie within the specified radius. var radius: = 0.0 @@ -34,7 +34,7 @@ func find_neighbors(callback: FuncRef) -> int: var range_to: = radius + current_agent.bounding_radius if distance_squared < range_to * range_to: - if callback.call_func(current_agent) == true: + if callback.call_func(current_agent): current_agent.tagged = true neighbor_count += 1 continue @@ -45,7 +45,7 @@ func find_neighbors(callback: FuncRef) -> int: var current_agent = agents[i] as GSTSteeringAgent if current_agent != agent and current_agent.tagged: - if callback.call_func(current_agent) == true: + if callback.call_func(current_agent): neighbor_count += 1 return neighbor_count From b0442982d096cb46e275955c7579603b791f93a9 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Fri, 10 Jan 2020 14:38:12 -0500 Subject: [PATCH 21/23] Implement demo for separation and cohesion --- .../group_behaviors/GroupBehaviorsDemo.tscn | 11 ++++ project/demos/group_behaviors/Member.gd | 51 +++++++++++++++++++ project/demos/group_behaviors/Member.tscn | 12 +++++ project/demos/group_behaviors/Spawner.gd | 18 +++++++ project/src/behaviors/GSTBlend.gd | 4 +- project/src/behaviors/GSTPriority.gd | 4 +- 6 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 project/demos/group_behaviors/GroupBehaviorsDemo.tscn create mode 100644 project/demos/group_behaviors/Member.gd create mode 100644 project/demos/group_behaviors/Member.tscn create mode 100644 project/demos/group_behaviors/Spawner.gd diff --git a/project/demos/group_behaviors/GroupBehaviorsDemo.tscn b/project/demos/group_behaviors/GroupBehaviorsDemo.tscn new file mode 100644 index 0000000..806d7ec --- /dev/null +++ b/project/demos/group_behaviors/GroupBehaviorsDemo.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://demos/group_behaviors/Member.tscn" type="PackedScene" id=1] +[ext_resource path="res://demos/group_behaviors/Spawner.gd" type="Script" id=2] + +[node name="GroupBehaviorsDemo" type="Node2D"] + +[node name="Spawner" type="Node2D" parent="."] +position = Vector2( 397, 207 ) +script = ExtResource( 2 ) +member = ExtResource( 1 ) diff --git a/project/demos/group_behaviors/Member.gd b/project/demos/group_behaviors/Member.gd new file mode 100644 index 0000000..9e4b8b3 --- /dev/null +++ b/project/demos/group_behaviors/Member.gd @@ -0,0 +1,51 @@ +extends KinematicBody2D + + +var agent: = GSTSteeringAgent.new() +var separation: GSTSeparation +var cohesion: GSTCohesion +var proximity: GSTRadiusProximity +var blend: = GSTBlend.new(agent) +var acceleration: = GSTTargetAcceleration.new() + +var _radius: float +var _color: = Color.red +var _velocity: = Vector2() + +onready var shape: = $CollisionShape2D + + +func _ready() -> void: + _radius = shape.shape.radius + _color = Color(rand_range(0.5, 1), rand_range(0.25, 1), rand_range(0, 1)) + agent.max_linear_acceleration = 7 + agent.max_linear_speed = 70 + + proximity = GSTRadiusProximity.new(agent, [], 140) + separation = GSTSeparation.new(agent, proximity) + separation.decay_coefficient = 2000 + cohesion = GSTCohesion.new(agent, proximity) + blend.add(separation, 1.5) + blend.add(cohesion, 0.3) + + +func _draw() -> void: + draw_circle(Vector2.ZERO, _radius, _color) + + +func _process(delta: float) -> void: + update_agent() + if blend: + acceleration = blend.calculate_steering(acceleration) + _velocity = (_velocity + Vector2(acceleration.linear.x, acceleration.linear.y)).clamped(agent.max_linear_speed) + move_and_slide(_velocity) + + +func set_neighbors(neighbor: Array) -> void: + proximity.agents = neighbor + + +func update_agent() -> void: + var current_position: = global_position + agent.position.x = current_position.x + agent.position.y = current_position.y diff --git a/project/demos/group_behaviors/Member.tscn b/project/demos/group_behaviors/Member.tscn new file mode 100644 index 0000000..c2ae670 --- /dev/null +++ b/project/demos/group_behaviors/Member.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://demos/group_behaviors/Member.gd" type="Script" id=1] + +[sub_resource type="CircleShape2D" id=1] +radius = 15.0 + +[node name="Member" type="KinematicBody2D"] +script = ExtResource( 1 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource( 1 ) diff --git a/project/demos/group_behaviors/Spawner.gd b/project/demos/group_behaviors/Spawner.gd new file mode 100644 index 0000000..c1d8556 --- /dev/null +++ b/project/demos/group_behaviors/Spawner.gd @@ -0,0 +1,18 @@ +extends Node2D + + +export var member: PackedScene + + +func _ready() -> void: + var followers: = [] + for i in range(19): + var follower: = member.instance() + add_child(follower) + follower.position += Vector2(rand_range(-60, 60), rand_range(-60, 60)) + followers.append(follower) + var agents: = [] + for i in followers: + agents.append(i.agent) + for i in followers: + i.proximity.agents = agents diff --git a/project/src/behaviors/GSTBlend.gd b/project/src/behaviors/GSTBlend.gd index 33f0699..67f5899 100644 --- a/project/src/behaviors/GSTBlend.gd +++ b/project/src/behaviors/GSTBlend.gd @@ -9,8 +9,8 @@ class_name GSTBlend # `GSTSteeringBehavior` and a `weight` key with a value of type float. -onready var _behaviors: = [] -onready var _accel: = GSTTargetAcceleration.new() +var _behaviors: = [] +var _accel: = GSTTargetAcceleration.new() func _init(agent: GSTSteeringAgent).(agent) -> void: diff --git a/project/src/behaviors/GSTPriority.gd b/project/src/behaviors/GSTPriority.gd index 3c8dfa7..4cb84df 100644 --- a/project/src/behaviors/GSTPriority.gd +++ b/project/src/behaviors/GSTPriority.gd @@ -4,7 +4,7 @@ class_name GSTPriority # acceleration. -onready var _behaviors: = [] +var _behaviors: = [] var last_selected_index: int var threshold_for_zero: float @@ -38,7 +38,7 @@ func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration: var behavior: GSTSteeringBehavior = _behaviors[i] behavior.calculate_steering(accel) - if accel.get_squared_magnitude() > threshold_squared: + if accel.get_magnitude_squared() > threshold_squared: break else: accel.set_zero() From 82d92016a47451edd80c129c063f89627497b5b4 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Mon, 13 Jan 2020 12:38:46 -0500 Subject: [PATCH 22/23] Add GDQuest theme to improved seek demo Replaced the text boxes with sliders to improve usability. --- project/assets/theme/button/disabled.stylebox | Bin 0 -> 416 bytes project/assets/theme/button/focused.stylebox | Bin 0 -> 426 bytes project/assets/theme/button/hover.stylebox | Bin 0 -> 410 bytes project/assets/theme/button/normal.stylebox | Bin 0 -> 397 bytes project/assets/theme/button/pressed.stylebox | Bin 0 -> 402 bytes project/assets/theme/empty.stylebox | Bin 0 -> 217 bytes project/assets/theme/fonts/default_font.tres | 11 ++ .../assets/theme/fonts/default_font_bold.tres | 11 ++ .../assets/theme/fonts/default_font_code.tres | 11 ++ project/assets/theme/fonts/font_title.tres | 11 ++ .../fonts/montserrat/Montserrat-Black.ttf | Bin 0 -> 275192 bytes .../fonts/montserrat/Montserrat-Bold.ttf | Bin 0 -> 261588 bytes .../fonts/montserrat/Montserrat-Medium.ttf | Bin 0 -> 260236 bytes .../source_code_pro/SourceCodePro-Medium.otf | Bin 0 -> 145516 bytes project/assets/theme/gdquest.theme | Bin 0 -> 2688 bytes project/assets/theme/icons/chevron-right.svg | 1 + .../theme/icons/chevron-right.svg.import | 34 +++++ project/assets/theme/icons/chevron-up.svg | 1 + .../assets/theme/icons/chevron-up.svg.import | 34 +++++ project/assets/theme/panel/panel.stylebox | Bin 0 -> 403 bytes project/assets/theme/separator/line.tres | 7 + .../assets/theme/slider/grabber_area.stylebox | Bin 0 -> 404 bytes project/assets/theme/slider/slider.stylebox | Bin 0 -> 452 bytes project/demos/follow_path/FollowPathDemo.tscn | 3 + project/demos/seek_and_flee/GUI.gd | 26 +++- project/demos/seek_and_flee/GUI.tscn | 141 ++++++++++++------ project/demos/seek_and_flee/SeekFleeDemo.gd | 8 +- project/demos/seek_and_flee/SeekFleeDemo.tscn | 6 +- project/demos/seek_and_flee/Seeker.gd | 22 ++- project/demos/seek_and_flee/Seeker.tscn | 4 +- project/demos/seek_and_flee/Spawner.gd | 4 +- 31 files changed, 270 insertions(+), 65 deletions(-) create mode 100644 project/assets/theme/button/disabled.stylebox create mode 100644 project/assets/theme/button/focused.stylebox create mode 100644 project/assets/theme/button/hover.stylebox create mode 100644 project/assets/theme/button/normal.stylebox create mode 100644 project/assets/theme/button/pressed.stylebox create mode 100644 project/assets/theme/empty.stylebox create mode 100644 project/assets/theme/fonts/default_font.tres create mode 100644 project/assets/theme/fonts/default_font_bold.tres create mode 100644 project/assets/theme/fonts/default_font_code.tres create mode 100644 project/assets/theme/fonts/font_title.tres create mode 100644 project/assets/theme/fonts/montserrat/Montserrat-Black.ttf create mode 100644 project/assets/theme/fonts/montserrat/Montserrat-Bold.ttf create mode 100644 project/assets/theme/fonts/montserrat/Montserrat-Medium.ttf create mode 100644 project/assets/theme/fonts/source_code_pro/SourceCodePro-Medium.otf create mode 100644 project/assets/theme/gdquest.theme create mode 100644 project/assets/theme/icons/chevron-right.svg create mode 100644 project/assets/theme/icons/chevron-right.svg.import create mode 100644 project/assets/theme/icons/chevron-up.svg create mode 100644 project/assets/theme/icons/chevron-up.svg.import create mode 100644 project/assets/theme/panel/panel.stylebox create mode 100644 project/assets/theme/separator/line.tres create mode 100644 project/assets/theme/slider/grabber_area.stylebox create mode 100644 project/assets/theme/slider/slider.stylebox create mode 100644 project/demos/follow_path/FollowPathDemo.tscn diff --git a/project/assets/theme/button/disabled.stylebox b/project/assets/theme/button/disabled.stylebox new file mode 100644 index 0000000000000000000000000000000000000000..5838b762d953b292bfe91ed1081fee1895223499 GIT binary patch literal 416 zcmV;R0bl-7Q$s@n000005C8yU0{{Ss0RR9fwJ-f(V*>RH0H)GBE>KaF0Pw&0Ux;d- zYq7k|_dxoj0ZAnBDe>2`WClRYK%M=UFc8?K3nfTJQS1RM04@MA0Mu%z4VV3gT&aZ4 z6)KBsd%a})mNLFzHm~A=5hy&7K zRvCRRTbrY>AgQ)jyttOUSRp68L48pp5tIsLvVki8UtqHNApk#QL2>9Jz{5YlaGu#n zpQd9&(-&oQ?Sb2Ui5{hN>PJ~x-17uEAV2~DijF-0(vblo(wJSw=K_1hcLM8I1_Koj znt`IooUw$EYR54HR3AXW{S_WVlR!udoGU>C@^c@uvCk93LTA2%yfW2W-{aPX!3nyk zWAL3vkA>%7gqUjME@i^UfNleZ)5}5!-Gm`9ypkYN=mKF{5C0*6-)A{$)*#upSk-P62h UTs@Z$+*`g}W7fmP0#Z{$LspZ#H~;_u literal 0 HcmV?d00001 diff --git a/project/assets/theme/button/hover.stylebox b/project/assets/theme/button/hover.stylebox new file mode 100644 index 0000000000000000000000000000000000000000..fb464a1a3e3d0d2f746393552a071227236c591e GIT binary patch literal 410 zcmV;L0cHMDQ$s@n000005C8yF0{{Sm0RR9fwJ-f(R072d0EQAhFkn#w0RO|{S@X~Q z(@ZgwDDj+m-gT_Im%Mjeonog-5^V}>@3Vv;N{`B@p^R+X0V@D405AZnp*CFh|G82L zA6KX>uI=@b?OVz?vr+l~X*wjTds(hRT*Ex&1#l z?_0K{=zqbf?cONi)pq1PNsc9NjJ^e(#7PB?S^Q5RK^N1#T&`hWxTx8dQ0G0z<+^;!8aS} z<8*{zwb%)Q+ntFZrF3dYSz;UnMLbjiHXuL(0BWpyzqBxbCR=!IO;Cx(T7zJs_jg=|4#_hR0=ic(=nrA%#EK*ZL ELl+^u*8l(j literal 0 HcmV?d00001 diff --git a/project/assets/theme/button/normal.stylebox b/project/assets/theme/button/normal.stylebox new file mode 100644 index 0000000000000000000000000000000000000000..4f8c7da913c0d4a5b6b7228ce8d6b4e29a6242fa GIT binary patch literal 397 zcmV;80doFQQ$s@n000005C8x@0{{SZ0RR9fwJ-f(Jpx?|0QS*3E?_|f0RKbnvD=0| zS8hllJZGMB9qaB1?;TgC7(zxY*+xEp152VJOrgSfu-ySE04o460Gh44{zsk?s^h7- zp4wIp*E*GpG5eDLPyRE!(NSntBHgAf{~H7U7k@3II2rHboUOT32ATb5oY(DA(DUEm z(su8I@M#fNA@EZK1UO|tfry`A!MJ9hbenz-4kcc7bh|N+ zlTt?QsWugjTUlPzW9&`gm**RkgA=Qp!2B1JZLJu(8b(!$LpbL0p-_t?zMcgF(uwedR6+ECfTB)9*I^S)(E zivBB3ZTCh7ueKlWNpcK%Tl6jHB+d(x$}x-o2_)!Zx|ho}%m)`S+j5E!htptI8GSBW zTLU2>Qf;qzaV>eVLOytd`XWXRlnQ0Cfgt|L=7*dgQV1McaKu0GKOn()W+Q!?j*_M^ zDpwEO?o0G2rBgr3(&C;cHXuL(0BWpyzqByGCR=)KjbA3{Up#08in4RY5<;pS#~7e~ z0EPEgcnmFpuogU5LI$MgK44>;Cx(T7zJs_jg=|4#_hR0=ic(=nrA%#EK*ZLLw^ys9smFU literal 0 HcmV?d00001 diff --git a/project/assets/theme/empty.stylebox b/project/assets/theme/empty.stylebox new file mode 100644 index 0000000000000000000000000000000000000000..4467232230be2504f1750f6b35abed8d5e925f93 GIT binary patch literal 217 zcmV;~04D!ZQ$s@n000005C8y(0RRBO0000ewJ-f(hyc9>08$DfC2$EF0sQ~}fA--p zbjj<&jP$>&NF%UFg@;&K-)}*wY1MYo?g0(Tq68pE1O)N}{D`seLYZvO#)L%aQn4tP zYGCeT2q_@^#_KS+qSIYv40dz}UPXezg15<*9!o&w(!SiM>nAv!ddc~6#iW~>TG~=B z_@FW2fA92Z6Hdg!uO+O~2&wVeJ-QtHO4x5r6q5W?P=4NflP?}OG5dx`)~aB^TEusq3_@Cvc^|Id!*#pKm(QHlWaggZRB%(e zQUx_rzcpc8^t%s>RdDY_T#vnc+^p&8JF}}*@Egg$aN4-bFMhG|Eu{Yq(nmj-{;ex! z{_T5}`6}29J-IE2TC-4ON&OA+=8rz5-~L|);Q z;nfIdhc_YoK?s@QlJLg}Zw_xkcx!ko!rQ{1BD^D9f$*LXd4>0esFU!%@IHk1hrdAh zV7MOPhVVIr&xg<PPjX2!E|nM!i|Tti0&{=zis;d1)7^Anls8B?xa$y9NEhS4}|8RDN1^+VKca zNNWea_Gu>}EKchW%HXsi2#2Lzi13=UYY~1A>3yVCD#L3ZyrF`s{zK1E`4he~W2$O5 zb==HpY6^NMKDD(fz$r%+sOBoD95A9#wHY>~s!(+}dqicS!dNDUhf#OD#lC8$3M~#) zo;tzeP#vY(AVrftqx%)A{(bwLQ>aGt9f5GnkUpae)s$gp4lPty4Ic{W*N-@JSfN^c zj_}-m&WIs}YL%6uRlaI#aioq`?JQ1%ekWR-u8vXdEpDP(sFN(tP%TxF#Z6T!b+W~o z>R5G(#aXJgI@RKAb(|_zr(JgOjA>pj!xjt+85S|@#IQTV3Wft2Rx=#Ma4f^g45u@k z#c=NB<7QmuEnv8m;WCD+7_MWuk>MtWTNrL8QC;YGJsi*$iG~wEpU(o+sVbr({^gSrun(8{6r!2QGh` zwd+k=Y|h`FWX?D4R}mWAd)ZeJ8r^$&usOe4uDq??$s^;k74mG45#vQGq=!UHRYn7$ zzcpV{ys`RC@rE5R*4EYTt=(U{srF-p`&9c5{31g`+pqFL`52VF$l(w^ zwHq5|LY}*jvz21c1r75aCN*F9QH};bwO^u6@^O6Kr_5!j-Oj7dN~i@W6Y{9tA|(JS zsNI4Pb`3UK<6Ka?3CF?e2Wcpeni4718DH~BQbkjE2$CgqV@#Y$;f6)jM0kF=yeH(%SrS)tTjU%L}6U7)ij4P0EeqQ_rd8b>ot?;82Y| z4#C1$-}*6zl1wKk)?50N`6T0|m(~B|vmA!202~;@64qx-&^oIkwjFw^sZ*54N)}n5 znK6!jf@_gyKc<#JD?m?!reZB5#IZ{(i1J_FF7{>nr2p9rU)}@BGHTbcf0too6hQ;g zZx`gk$^iFAnre<2#)ztcD?9mD#autUw}J9grGpWF{piuLaemOTI~(TqRqnPBveA8J8i>QS|zH z%Wmq{)uLWTwJ%amlFpoL-(#s*t3*kr7}*++%O$;+HZhL>M(2Z;(dHP}2YOpVSCg)R zEK~YL1MyBPH4uBS)Q!c#M>g7Rgy znoA-<0x)0dnzYi1$hx2wYhC$Zo@a8*ml{RujI~rH9trJ=mcj9&X*Y!Mli=IVR2fKv zUV=QUZ7pZWJX&a$-cXOXCFE#vN()c;W$m4`ma%0KRiyVM+nRkt=Az<`n;e`Wun zRQlI=c9>vtLA`$CXcP0@Y$TBdr@4HDQ(r38r_Q`lV15n=0FRt@rLtcWnGH5jM#Pm_ZJ9IrhKwzvyJ(b;IRb5hQBR#_&jr}ulC~1Lrj{_~F~8l! zGKxKrI+B{eNA!SPQ)^#46ROvaaXOoI>dBVT)M~?Jlrd3&KK3!%0DcRjKz0FSJ}!L| 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

d@+2}ZyoLk-}5_$ zAA}$J-NHTLKEFr!NqE4o(4O}EVLH^IKU_yT*FRI|={$e5&e!?=1-g}P<=5y!-PXTQ zx7S7fIDLvf#h<7<>#qLAx`*!JPtm<~AOA94rTh8Q^awq|pRUi*=lb8)HF}JHg`T9R z_*dzf`bz&A{ayWC|GWA+eVso?&(k;h*Xf(|LjQaEhx&*94SI=Q>d(`+=v(~n>)Z4l z{sMiszRzEzf1%g;OZCHgy??8IR6pw9rhly;_kXIN(a-yL=oj=0{+)WWe%W6c-4Wg4 z-yQud`k8-E^z-QF{;KHC=uZD$wDsNoYP9#g{+j5%=sy4c=ois1{IzKR2mN0}FGer< z4@56VFZ=7Fz0qF(m(fSjNB%?6zUX8B;pp?|bN`X(Ky<+0AicwX6g?x&{~*A8E9ek( zRQ-d~gJo)9usqnW)(4-5#a>p}Aw1jb6P_DR_bx$iYKqag5~Igj>Afh!@kk}XuqoBXza()H~`W+c|YFl)*Su}2(%XUm0;=*p!*9?I_5;jZ&hfkZm1==sF2{Z0Pw)LZ^ef2Z2x@A7x4Kl|^&OYIFG z2_I2^(MRj%>LY!uK3?t9?evN2@A_nYvigTURTrzzbO(L9`a+lKa&b{<*2k1dw zpoi+SyhxAK7kHWaB7L!!r!Ui2crEo+`dY7zo~v*0PS*4FeD5^9Kriq*=pX1sUPrxH z|HwOC->h%;&d~p*f8v$s<$Af-O|Q^*dENCIz1Az!ztq3`c6aF%MD112lb@+JrWcXD0 zeE356R``CnJN#4laagPIS3Ww>S|0^jN9kkqX}X*4u6ycI-CqyZL-g7D`+AxFnSMlX z(2wa~>5clgXc<4vOT#)M?V7YDO7>E;^ycV(+9F?d75ktR?8DXAyPqB2q{8qA;bN5^ zE(w3ETEI%&qFO=ETUBdViJz+D#7d~+q3u2D#PHtmUe!LlFT78k1Y7Y7RTMrLu2-kR zRy?OphyKs2-YCPXsv_JPzO4p@?}qQHktoso>O7Qcw;C1h4fm<@VJkjYW5O@Pf2v7h zG1R577|qlaeU#2uvvhOaLd`}CcU0fir|ZsYsV>o7)Ga7|H+3tlL{Ie-v~Z>RsUD~Y zsuieZh((_o{2*kseVi)uZZ3^?-U>y{R_fcas08w!$yHuYM1o^moirzwkP!KY5)n z&n$rTKi50iJI_1c>+4_EBzb%^ZXnAU%@B*+W(_}hrc^G&3`)R7*qsNP#Ihjw7`Dz;-EbEaj-0y2zzo* zFg>_8cs7_7Yzm$aZV6rpHU~cmwuH@sW#Libaly{;_^?~>=dedu8irx7aC(@=-gH75 zcEZxyr=5fnqc^3Ukk%%xEw5p@(ATgBkd~cxyvj@~PV27<(gvpuQ9aUzrCq2>(Fd

fCjhhaHkGgTVqEq_%_Fn9Sx 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 literal 0 HcmV?d00001 diff --git a/project/assets/theme/fonts/montserrat/Montserrat-Bold.ttf b/project/assets/theme/fonts/montserrat/Montserrat-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9a425b9a626ff7524a091e6a1f14ba200ffc4b16 GIT binary patch literal 261588 zcmeEvdwdqf)&J~1yPFVmCvu4xBSnlF0Wn~J03kv|RHTTA6crSa;-yp(sdv$$RZ0*uAx16{BbR{4O`hNPd}lV#B;*O9we9=IZ=cW3e)sH| zGiPSboVo1fQI1k76M?64dtP$>c{p=aezk{usk z`n6J##mXu8LKA8TQ)yZ3n5yeM^)|Yj@+YaibGAre35XlXrqY_oiVtUitgDspHK_&-L;D3y#|xdWA}hM~-QgVsmg zi*USp8sR+kGQwBX8wi)E&k%mDHX{5&ZAQ3NAusBH(?&T?JEt?kBIifVp=m+or_Uw4s;TM;=^Igz%J zVuU4;>k$4lG6~_Mkr@bQMxH|WbYv;QWs!FfE|080xYEl|j@Q^b5#dSRIS4y>T@ZHl zMkBn%Lt5Ug-fakP_kM-&5f3uG$=;&~AM>UnoaRkKINkdl!Y9002%qwhmiM%WGVz}E zo<;aa?@tK->@7gJ(0d!#MAbh}|fbe1eVT8Z-e~oam z{}{sm@t;6A%b$&Kj*mS0ulTPZeBDPL{T2TE$_f4${82dxPQq0xl5j`DWQ30;OoctT zsu8Hk%1ua3I0@m&39Z1_I^k4=`3a?<^hvk?;YA5oAiN{tPK5U%zKgg@B{{7l>r|v? z>4gJS)-}Jl`3BYMhGAoFQlns<*rHJt!68lMs3s~>a$f&j)$*bXdgiJ&m-H{mRhF85u;I$!M$=->A5`yvS3=Y)ss+GYB(C-w36ID~y+Tcd2nL5?r zB-LEy8GM||R;L-9tWHp;8=RtAs51;sRVS)^b>{Wg-h7jj&afH7T!wiJ+c7L;Sj@0D z!+s10F&xTpB*W1R$1%M3#$h*K?>xkC3d0!;=Q5nna1q003|BH-%dnhbCBwZEx{6^E z!>k*xzwvrEhhZMW_6&;{mNM+ea4^H+3~ypMj^TKQ6B$lpIE&#tSc8jQZ0A3Hj3C7b z?ehN?@>QS`P#zKWe+4C?-AU^#LGRLE4OUm9@ zu8n>leG}mU&^AY_fU2VVRSwQ~Mb}4nquh^2TJ>(xMRi|}E{bkY9#Yva*X0QM&Cot!zaRDhq>^vVgLXBiT@9MwdKO-Xw=XbPbX8VAx`k&Gj038X6DLP1GsWQQ}rxn#GrD zVH+l~CPcbz<8rQT!sgXj*FAbrvstxaa>@(3JrSm(tUd$MoH~Az@S;AXY&3xg;Iu_3x}K0k=L~xNzJ55ltUc|V?nGf#b`hx zP4*f!kCF{j(ahmh4>{_fNsJTHv%;2MeJupFeUQ+@ST>5K7ittzJQcPWDUn#*&{u{j znWMJ8T10&s#tqw3n1Ymm{%L=wx$Rb1Ev{}`ioT2ZHR_8I!gNA!!<<#uWSGxt*#K+3#g+8v*U{&MBf0@2v$gcS;-f+MbpqPt>9S~$mgA;}!0hXq8pGSnjW?quelUg+oKC!ecLkl?e-=}4Q6XPARG^@wdIvi1xv>-|KS@xOQ zJ5}o>ISMyz4d~5}Xe*Km%IJ?`L(t=`Fa}CuHLmPM>)3+h>gZE)1tWkUI!7rKlW zg|AZhK@oqO75$h}+DHEmiD+3UuM|kyiTMn8&6Z^RP+;p>eNE3;&_W=48P`3YB`%Nd zfV>^ivg(nm9xEuMA=?S$`ci8~iWR^gVm4+rV?)t{$l(Ui#EM(;Ck%P$-CJVpQy$&S zv4?IIGB!zqHb07fh@*^v6Tl^##O_3d0P_H83DgD0W+9zi!WnKMHvKXE80s&MKZ}i^ zYR3=H&9Sb0Lh3slhwC)+jo$I{DYn)OHTfaN3K;n@uOeMy=ZD_Lw2#o@jxC=UCC14o z?7!9)mQyV!%q;6ep-tP@nXx6m%v+Dfv8=3mZ$t zIJhNd3T^3MCB;6-wYKnmTnWPJ8#icfHsP{$3$b0FlF!Xy1RSel*OB`$zQryO_9@z( z0e_K?cJwAaS$T8`Ru$IbT#w-uY6;#{yd-EZqjlxMzqLgz79nl|QiFfMd_ZOt`3Sc} z9}x|ruOWdvN<0KINNFiw@9nw~W7VuKS%j^oo8SkshsssI+g8fXVvr1UPxDJ*ISEcY{QCDBhomG+2U zQ7jF|9T+?B!BIxlGUnKio~x)K95X~ep|s87 zi-2~44q3>-KFI;>SoUz01FNmjLcGa3j__iZO^byumRb`3a**jC!pH$LUfE1eF!F{p z$-k_^8GDDne;uU+UnsH3E#4J63I;l?XG!$6i~}zttAKl{ElUh7PfCWZMCgc?h5S|_ zM{F+=SExpQ^~{14@okch^oeX+2({jNejpb)zaTJyXxo5I`U~+#C{O66=g~sJ8m6{o zUe`UH2M>fkMbd)ad!ye2eaHSyYU5b9(3>1vJc)(-5iBdwS@&;ZD{>{yI*>`ijNycr z_9Nq9v2$4kXU&lB2)$zEVC3k#h}9?c0_kDX#U_ywysN&S!TLn&vQiZxa%Y4!ZAPH7 zPN8d&wN#ys=$a#EhPxWo&{Ss8M{KZ2%PwqwLysT|#^0#jJ+Od7(&CVgjCNDN5wLY@ z9Vr`EC2uLz#Pkc*i6)8$h?Rw_oIRtQ(Px|M;gK}}K4}MLW9@_|^&T-|!1_77O(itl zirMITScKdkV^4=ZPDavUALYwf620GLkjMMBym`8ZA8k^xTT0(ckvr4iC z@4x3HEZy2xQ*Ub8uhq+9U!+yp1o3Pr*^l6rKac(+`UOV9;@8%oeC6)b9?n({;fywc zD>9Ck(fsxrQs61VO-fC?hm>GQ!?F5~B4o%l+^5hofxizqQGb^0nb>ySIg1ywE(fZG zs!VNj5}l6DaA%6M#M$n)aQnDZ-3^hv$jy<(Uf{L!273>9&wFcq*U$F{`uFqhyFIydUwsBfbIjqYwVz0r$}7B^bj zXnCWRjn*{U(r8~&kW_%@S#aOR*{V)-DpY&tE8uO|cVORzeK+>+R5P~-ZO0AHQ`x~F zw5Eh$plTmnrt*RzI9{bvf??Qys)Ar4?u8x)iMf#21`7y{Nl0QFo`I-ddxsTBDx!qMll#p7x@i zTBD9yq2>L5&i_s+1*o5F)X&MNpA^(f3hE>ab&`XpcDA5iwyHc_IT=?@#+5v2QU9l} zcxd-o&bQdH>HuxC;A_8BcY%7Fl507*mV;|K%ww{%0ceZrhkSN`cex&UErNF`f~6M2 ztDJ#+cR;?2z}*I(q`i3l=#F3z)<-?>=c=D~v+5U=V*fG9B?3wwD0!ghvmBh|;4Ft} zmm=*_q+JSWc($@yQcT0++`j5m_hRh*u>Tl)f9#iFAAtQ*>|bCn$G!%|(^4+h@0%&t@1ffJzd{Sh3VKI32IphH3H#5m zkH$U*`&jJ1P>q7yabw{Q9Ph;O0njF3e+B!i*cV}c8~ZZsE20|{hN(u%eeoF?%l>W3 ziWgBoH)FKh6lQ);-rjP8(ST0qp=NTch)FpJWl{XEJa41k|mVNxcgx2eBd`Yd3y$0d}m_ ztB#=T2G=Ic0d`?T{w;X^nOVOznkq@ilYNkBt`A=`*S^#7lJJX_&4x}Ot9qte%KD|y4x&ZNJto2O6YHst2Og#-Qh1eD4CgM3J8;gYA5j+YRmg=r zxgj>goMW9A?LU+Xs;m=h36irKt1mkDx(2zzu$3w4f;>uydpY}IfuBQza>()FB}G1J z3G%QSjC=>Yi<%?Wh36FZ!dL!PG=YAy@|X+@tH6`dV#E8fQk{u7a*t^Z`v}~LMV^wd zM)oOqk7Maz97t|iQTK5Ld52dQ>)iuO$Yc)WzSb`I<6ZFXSe@rJvDJgnO6*2k2c9KG zd~FF_RT15f+@c=|4SbczC+mslvhFT-%u~@q0@N4Q%FvILA>4|e94mMiu^j1@M?XdE z%{Z1J2A-Q>OZ^6+tn#ge_w`U_Dcbjdf3rFPx>w*lRcMeWZSFI0ZV(S{TEtdmDBH5N)oTjtq{da7vmw}))&Ty*2Jrj~EH!g_q#*4DYSxdAQ`0{j8M788 zPOa6HTr18Ga(Z-Yj+e}_=@zTkV~ZCr^`p}#fmMIFr`?kLdg6-riPt zi`lrk7gsr^!@9Eca24qP7s*%?-uGl&{RaN;D~uX;am9WuI5c+^pA%REzf*x{2Udw+ zL=3q%xm6WoWV{3G)|EJJ##;4Ppve;fa>sEOyzE!-pOpw@HCk4*H%ZEf3-4;mN1i_7 z20twE*lUNh>Z9>YIM0F9H}U%}`T^v<3Y`}5Egs>>!gB)bl@Ur`Aeigc@VI#61pMO9 z55Y5jiV=Pep8k{P^H%9p&}hl{fpcOZ4Ym{8IscRB!cvsxF<`=U;_%! zkJ-;^)00tRop*+GTE`w9t2Kq~Qd(*J)_tr}k6rJYF;M<8x{)47`anHCh0UP16Fu4E zNEx%g4DaH_`XRg#g*b9<^%sz)?`7{|?dZ{w^!H+MyHO7M9>*Q-gS(M4kcJjy!7l`b{Irqm0k@ z$#c)pzxs)5^eoAs3$JgUXOf(3#{L0lI^Po8hje)t-+)JJqn|`!Plj?lh!#u?QId1bgYj0#FLZkY4@*_kAi?CZnkOwpw*Qqo+SsaF zel?HOjHxZs1S5|~UD{!|#qKYM6zeE?jh)7F6Qea8!EbG3xoOLx1}Hym!F*z$WrlOv zkSlpoDBP%JSnJiLDeo?cAJ*k2clY-(uG}rZQEhN(wFSPb6OkW zW1Aw*Mp*U=tlBg~+|N*2cv=K<0tXm)=^3QGm%*o&Ays)IQa_E^5xi)@sKw3j zw%ZVHU>fp<;99X;tjJJPo@M+#ldcxRw~7qZCk9yk}3FmggMW zBS+!|q-CZf&k^V?vw~gG&ml?fg=0fGFGC5HL-I!Hr%)=KZ%avOU8Cz`c?3=B$l4%r zwLXzRX3Bs+q#X>Ua?9q4~*QzCiad<(V_^-A!jZpgbGrwd*99lT^G z8}!UVD@9%;WQk}$E@v_NZgm#;vrv-Re4YqT;xmV>a70ZJXQTD@(y>swlqeb-id9;m zY!78?4kIDZRG~q)@M-_%poZ2^%4-s2NPspZW6v$9PkBmoH)px>G^bcZF4~ohLEpwo zKr@Urx1%2|k1mMLK%6qpk+)#Pwh?x|598iWSG5>(MzMj)RWnXplli`Zzp+Fy`+8#t;h8!7CEcCv;bBQUW^>DkKZ+wguf zJaAU@52%?e)ZbUAm9Xf)P(S{OafU$*kgI>?@I)%ynd4eYH9hHpiO4?BF%59bt_fb?`OkM~g5U5-IRe znD5BC(aF_)M=NL)+A4ZBq+H$ZS*|7^m37Zl^izWR8p;dW$VwU3)i?s91eDJqd16^4 z;&%|a5kFAlU3C!vUlu-*CTUAO;#nV*pkCv|`|s@UxV|g=+#;|>Gb%!#N&lkt29;;v zI%0%n;?_DK|EO8LMVC<9-O|Q{BIn1lRi~aEi&d>pjC53lx~leomd#aL-%$lLoFNI% z;vTV~>|^PhzDAg&jIqnO)@mgtx=`fFK5SN=GiWbtw?|yl1e-f9#axJYaDT_=>lPRO zWhH!6k!XO{_j>eq@Fe<8zdbn0{OMb)fy!F3yl?SY^zX3BWf)5}Wh-J!Le1x(?WLg2 z={E%1qpiyQuf1qt)uj?o5u_|Dw-xnVm%9V7QM6oHr~eLT(mukOR*h#AV^Xwr$Ik0Q zN4%k1gUO`8r}1lCz=_mRY?E0;%%jKXbs^*=6>~9pT2{Qz0eAr28}G!KboxzrO=fZp;=nJ>}j%ei>(u+(ZKugkdxsg9G_NLMa~xvztYe?t*`)L-qm2B)HI=w(pWxIc`P@Qx%>N4w!JBby>=>7Yq3A|coAj5gNn zv_|RLe(8fyN60^bQe-Ve%RrSnM8ANrTt*&farBvz3hDxLNY0$MNPKEw*3)oS$@OQ^ z>Hun_debdjpNc(){w|jDP|J`ackg2LA-dq48XBR^b zp~)(MTb+9*5^$ zYx0C|E5NqoZY#dl6>2Rdj#9b*%2{L_xrsLs+4dEt zCN@`H*SaRiiJsf$t&JhCm+Fo=@2R*VV|1BY$T&vk5;B`nstc}m!FdVFxe|QxO`dG* zZOGF`T>>l~OG<$Kuf#_!@R(-y78OS17A|l#{G)--6-xSzHQBWgTdiMVDHTZBDVuP)Ih za828m@IL_w&xj8WIG6cDIqNkEwJ&QLe1a&B#D5oAzQ1*X+>epGaj*6d|E?tKkSk-!|K!G+Mu{J} z%9;l?OndovDumS=>80{u<1(t|hIKjE7`80X@zoDli0m>xtAO|44*QVjR%-MTLcYe7k(yi;+9;mA6#GrMw^ z@V~lAo78i%y4A3}T-^-+1hsZMjGYS#_n6=#DY0t}Me=1%{X-00lQp8^&KK%WwpQ@$ z;x}uq#fhyn%w9ys(Y8Rj5A~CrzP#^c`P$@p&}kO>wcTuu@{JZ5@g-q3NZPNgK6XA7K|Flj5l?HUqQAh`6(3w8+AZ3&cnGN7ksW#OyFJTI+5oH_Eg}b!#^Z}8 zS$dAa)l&H~1^cg~6~QrI7muXx9%iFFP`DADJdC?;n_Td`=IGTu04Ov zb^8kR)9sEqU9Qs08V1tPI&iFmbLnyaBb$sPkb`}anB*ybqTu>Q#-hT9eLE~g%0b7_ zBaHZw>$)OeiiIU0Rgov($yis-7WN}-v*^>VZp z$B{@qX*KLp0Pi51es=2LSl+yMvJH9XH=J?z>ob09FqO8@FkNeK$@u&jwgmV(Y%*SE zDEDhU_($3BbTUF>X%qF&H^KRXloHa^B`>23GlM|d4IE=2MuRu34&e?Y`T*QjK;E}t z<|KC}XBm{op>ySpCz z7Q77BnpRofrXd32^3>-u?MT9Rgq02DU3{Aj7-MDJOJ;7x+kPx%f}@m+Je~Q&ZRh`R zqK+;qlty>>#bIjP|q%bNW~48MTdJ z#1SSYBU!d}X)We`kt1p|WUfBK&c48UB42Br00|o>@jTNh@2jVUu8vPStx8)fOd>=0*`e%%w=Ha`c zrSLgLSVdTkzUS}gds1TG%ak12YpGf-l(gvuS##FB0$xJyt2b=RF<TSG$O;d}#IkZKz7D^95>dBz8m!& zJUqSw#qlAZV3zx%vLVOcvA@>iM@>9Rh}5;87e0?#;V8Y(v2V~mmiHr~Bk$kSwwqym zCtvTxx?iol3tisil$i(Gl6=2SHs)R4PvZy^gqFIGL+vMpcaXttMxfx@&RBSpOpful zT6sU6oK3JMm>fS&yepzhylc?t6LT#^w{de;&%7n9_akJUs40@$e{rk!VgI6>qeM6B zzw#A+@oC(nuQO7BS<_nFWx^d0wD|ovtI=YkOKOV-2mCF{vl364;wr+uh%Y}`P2;h{c-g{I>2Yc(LeJiKW|c;>@G?^5os{Y}%iaiaE6i;hv{>S`YG6*1efd<4n{Z`gycnOw&iO98E7H`|E*x`Dh83cEA!Lx7nh z2)XmpmUZr$bdbsqyxn#bc^6yP^-~uXp$-_XScJzqSTO(k#3sY?mgt#WST^=m!D7F# zFMNf8XKO&gvtkIp<(mL}KMj5ezNxmgzzh6SYvH(8z5(*zKz*&{II*hQKYl|UP@`y9 zp+(p7kMQL&|F~WEA+Q4Z_NMqpJk!n`Nq>beTY)a`?0*}Mb40#u+K1vO{&O4Vu#?4=En0@0O0DAAE%>Scq10vy>Y){WGVj9u zRC(SKJo?Tio?e6!^8DH7=x6!7EY5L9lD>!k35Alwo6_cKmXEOFV`@xm7B36()mGWW zXCvGrp}iqRnbAw?*kW@Q$)%y;Ju6tG^o5~~Xx?r5`o9)J`)YeM>6x#C7>$u8c%;|W z?}XuN0$N|{jWM%nZ#z&I#%n_&=N`DmTtlwRU#fGd(>bQFMDB+hPb{n3h1&jL0n!)B zn?QIH0>`uP%f_)E_BP-W?~)#dbJHThv&)AUwas{?9sj*mL!(%gM;k^Hrfhn2)P^? z9)c}qVfW>!F7U~l7--#y|GhlJ0-vv2R%nmn-(^%KPvUbV1RrC~!9r^iUE^)0SBQ7{ zze*2R7wT6ctf{)VbW4d}4q@A>D{fshSU;Y?g=g81^+$QGM8@ITd-FXvcnYk;zzWt& zY>sR6}%_=cnGgSfsKv`y7%)emH*^OcPC z%m`0(|C~=nLVJ{njN7FhVSNm#$-8+dv+8kkJ+k4s|B6^E;bZAVkXOjo8$3MLXK-~7 zj&9ZeKzA7Yu` zg6jjMB~J)D*C$`!0zFi+Q?71RuA6&IyXUq(CjR>5dq`Wk@I}_{xbQCKJc4iRMckg) z`(W>fbS3Q{de5&@X2cz6(j8*1=PJ>yzWg-wn&(~(+1(%uUt`4g1$}oU_M5Pe!G3!K z(x|@-eEgI8e6`R?lAl_PeW}6Af!C;&Y8{Sc*sD|}!Yyhau6yb*`JKaSU_H)ZSSrFb z$g_lt8NRNZ=!rs!rfG`&-}>P;5=I>d|8IWyuTH9PI`|*(!`C@i3U;?(HRUXk#u1Z) zk&xg537vZ+jL6IsID&tEckUp*L*)CvFjE2U<`f|;iQr%E z9T__zbns8*P6wgj9F&pSBV~kUEIwt0a*tv6Q&t}ne|@rjq^nYv)YzSrcdF05R9AVa ziP-U6Nh-el$+RW?A97z?r#vqe-?3!6@CYW)qFa6WY3MaSwKZhBkhKB(CKXB9h8<72 zreNJAY$ zL(aV9IdYafANxX!zBGApc$U00d3iNn8Hc_uc}+D>Sqww!7NI9sV&9isMSQq%la%xn zFC_`bCMhjb@^EaC(niNmDUf4IXY9p>QVKjM<-(Ny=KM;1B%g)BH9WkMGCE~ch(RA) zH^!Aav5!xAC}onynlE`v%2b>`j(wJ3r-!k1*`{^`tpt0KrrYJ5+Bda#$PJDGwQ=fTP={)24Ll>4b!b>dtj)hmmY&F@mWwFWB)kq8WDZi8oi+^nl3rgJ(p6j+IXQ3RsUDs$+ zoguSW$4lLmx-Dgo!8=p;rXGsnG}pq38mFbEWvA>(%WB*tEw?_L)>`wJSov~HYmdEW zT47o@9Q$DJXRcb9d;>L|ct{Kjl6GXv(O1(bzeZk=uQcN`(?%lBO`0>+%A@F?HYS#r zw5tskeQr0B1>bAo2^ve7HZg{IJ_WStX*1L4Re|SWpC98%Tb#BqJWE@uaoX~VxUK(18{?))q7CqgKE7TUIy5mG?}{RWS^dm;MPt*hhM~xek5oUs!JG73tg4jm@VY$WR$U zj4LBq^Eb-A!A&|-8dSbY2)+?!}D;)WQh~zQKx3? z#Ma-knHu(wwvaJR$I6%inX@&vZ9e0fjOQ~J7#_ikG?p-9NzCRm-m&N_V)mS|T4S-# z4EV;-K5Nw11}mM^sYk<&*XV_{}L!M04E56K)D z@?;up`xD#VgfH|_(nd0`4r4;@NR2aZ${dqF&WYJ+181$y zWJxR1Tta8E%t-Zo)wxHox{UN*r1y&a3|FreihC>RLrEV>`cRpR0?E}AN#}gn=_%Ni zH9p6AoVc6D63cBtd>i?1Bjr?5zL3zBwI;{;f>)=L(wUU$ZUN}iNq>rzr(_?C${gZv8P4H+{$$2FN#v-zgzj7~6!&c6NxUj+fDWdX ze?jVbysB3LhLdNg;~>^>a`q>sFDd;=(WTvuIqgOYQ+KYWoF7s0%?z)1--Hg&2v%78 z6-@rgqNjU4d6+Nf3DTb+{Y2)XC&R}hKZYic6FBdHp21bnM5lpWUNaVx(xes4P~J4xc^Ja zuZUg7@=RRO>IAv!o?s}FqhC?~UoqWZQNAl!eMp^i$$t`M=F19>Q%qb8NshXJxRu)+ z^j7X#gk6N#ppa?<;d-iP#; zNcpXV?jVhMbucmRBp}vc=M@P_??p;4Cj}H8w-@QJGsMab=rvQHX-DgQZ8|%@IGliV3823ubT;<*c znbRq=1?hXpQzfy~bms=d>d344qL1?rUj2}qy(!@ajZG*#?~?O)hL^ioXLK$n?#1u| zhIypt87x+D3h@Gl^gNFCkmpk}%f#74+@Ilv)Z|?W-76TTlYTyJ<4VE!{}(Bli4sQW zNnD5dn#R>?Dl6Dp53i9Nq)pVE!@Y# z{R|!m{<`QQXGk6VLbv&Ce03a|Azk8*v}E37VO!5JmYjHbx!sCu>u|3{x8qK*=r#`H zPDFW4F+75&8$1(uj=}SQ=UaH8g%?}6Av{YB|8mG&bM{I(J9{1WGK04OSDjr+y725X z^!BAm1>V_*ghj&#-CU`>kG;YDztpY->z|i(DzvQKpbrGbWky# z4uOS}HSUlZORKj04$Wfx1y))eaxA*hlW`4?Tj>LMelHfiF>ofKMwLA=x}$3hjE;YeVWl{Mhq9Q zel=ZihuIc>CWZ@E8O%D3(K|dJhrU45J1i0#i1CMVIxOk1qQmMA?{rv;GzD+4@TNF; zo1yOnzs(cUMb2I;?jZ|X@;kaQddEZyry4BssTAlse?Yx;vk)ht}dZHc9@uCS6q@twac$jf9c=pT zR$3SjROiu7cY;N?<4!d6DL76y# zTx!x4jIoIPI`_vu$ii1zc({cd!ZXV7kCtQSv7PTk7!QxPcpkFwB*d9&;y&JaR_D1! zreHJn=q&g}i{23Ys^Nd5R@{&-GM8C0-?Olt?kbD^i6t|hp6e}sThDTfUU4MuI1uHq z-J*wa_jEqcMQM7MpfssVvV}7>mat1R3+FTdx3YLnw{Sa+yL5!ik}gGEdgEwgwB;J~ z0T$0-gNIr?Bf8wsp>dbhQV!VHVi!EX;0-v2^i9Cq4F3qBciGuxFOGr_ zSvaK6uEi6N{=AM`08t~hNZ5H@{K-%+iP4@2;9x0_cR!F zU4y?*9C|+^XJ9RUBd2Ic(a55kimomigX@BCxA47j@B~Aj2!5LG#>R@~_pw&l;X z=yNPQ&tQ=sPq+DoXCd@nZ1O00slm(R(1mBE#lObj`trWc(#_Vh8bhY&S%#y?*<$fm zTG%eD>bT&q3s*tbKCRn1WcOtzpm+^o4kwNc5R~R#4Rk`(%{)~cxuxP zzu0gnvuhr38!d;pz`~{b^g+PGyI$FK6po{@-`RC+ z*YP;obQ?cp@e6&DiEGoRT0D<;ohAOf>s;)>U7w5LE;&cXHhh85S=VYWrL<33~2 zZEWJo)o#yg9^wUte-Y?Q^!T&eJKa`vTW#oq*IIbPG2%^ze;ef3aYMSu-)YI*YhgRx zLos@H*OD1W&+dsaemmXnsWE!@tRr#v?9!y}xiNYew|ndE`Q6)VdiO#-mgwFMyn-=4 zsm2(G5cjOb6NlctkKylEH~%?k*WCx2bcXX(8^SZ%@Q;Pe@x^z_S@A>Irxs5l7W(6cJ`4D{;<=>12psai zYT-A4ml^)|idPkXV&n^6Z{hM|#1)2rJLK4LL%PV{W63;VVJqDpDn{=SSTf`2*&{i| zZ>QTMGe+;xtZrN*??&fyV0S%oG=Gm)z^7Z-w8tJDK`%0N!6g>%eH7fcR@?y=|6mJ; z@`r-|h8`p2N{^ed-`!&z@dFlJcpf%9HlA$pOzSbD$800NHh#vUKOYC%JPRzIMHXIS z@H@5Avg59>_)S_u>9N|PueGqPv(3Lj^Dyov3vbi7Mtelt?6FhRd+de%_dk-S$Dz`s zlEf0XBo(}Zvn*`rCE2xj;?Z+;+>+KY{*rv)!jkqS-Ei!Qy^q$Rq+bm8U|kzMflCI) zaF2%#W}U|9B}3xSuh#UEkzxZe{!mWIO(nON+*>lHWCGF=Jki2a;^66qJ`?;lPe>Oz zbF8@YENsi4Z_yW8c(K7EKb~$&Lw@LeugT+0z!MFg8HX-BOD+B>A+9Iy%fqz5W9wb{9Y#nU+Br7e+ zbC~Yq7Pk3Ao>{m)*VK#P=Pdl9grIW#PcW$r|^}jPdvA*t1#B98D)~W#Q8;+|J;>;IE4=ayr(*FLayV#zk>t zhIENrV#(}nVO!6>mYjHb8DPb=br@{X?YKiNx{XcTo+D7sH)tN>n++ZZ`rUdw*|~qu z2YNoN>BN&QJnb0q3?qLwWZH2Jo${ZtWIk_UJKY5qeUT+Io}NoAemmWFEc%Kgu~2H{ z-Nd!WlRa0XFE({eZ0a{IUR#Ub)G7H*J=T!9q35Qa+q7;yYvY|3eQz9W^Bjut^l~-s zl~_x@#osG6#^2M(7fLv;6McGRSvSjJ|(^7Z(tS9{<>P4Cq$ zhP$DhdiB(F;yxDcXE5xx2G77a^dXww>*`wkMozDhppWTwlW-k@Z?A)XZ!P`_hR3E) zjPaa1s4!XjtX@;#!vv4E@Yn`moBvM3KfWHB4_PwnO1GhLZQX1gZ2BZCt*I8a(|z2c z+i?wluj#lx)6|jRIToI0;rSL0c@|9?~g_l}*xrJ96yr!PG>n#2<3x_hd zAgxM67hGlGeHK2faj6&MKbALp8~z4wymx?Wes_v*Gv34ZC+~?|i?^rliF_ep^m5`# zyx(NbQq9m2OgheWDy zwIiib3}iH&>x|^aXLq|LWq)7b97wM85F4h9;;l~+j#<4s4=>ILCcFOX+3!_S58e6F#?^3Eil%G9TdhLOKg z&Q!{oOa8fhPdia#;de(e)?CJ#D;m0ESW|PUNq5%NT-MZF*3?|q%iPF*q&}DRHCOVE z@5(_RcMPRH&G0s+V!d1L+{O~PjU{j!wKDI%l3%~y-iwlZk+WB%9I5moe=pWAzt-mb zj{JOcGW-&orZ83q@^_&8N2nD`+j&HIT!zjg%$m9LQpzb632v!KKq&3BKl5w9``w?Z^k*vlH4k&qpK0}HTK$>UPZ)O)b1{gq z1~Jwk^8bYV_Pg2oy>z~7?Mx!)B>Iy{nlmE)WC;DqsjR_CtiegtVG`4w#B?V~?(8?N z-4i5rZ=~qsT`Q73zFqJ2WgCzGPPmjqAuVT==-@_}?kJ|K-xwdoyo_S%qnP?A+R|^8 zi_-gT^e3?JDwab}300MphJFWLRf$#zkqSa-iB)WgRU%VWNs6FIORS<~{XV(JlJq22 z#(I>c`l#lSR3fjjH9bnZ;ycpj3kcn*?RLsB zUkaq05=!V!3Ede>zcbIb<(&tqkA7$VL8ka1`5$B*J;+!OvaB9tjvk~nK1gePkk)uP z^Fo_(X)_3=76yp~^N#%lYBGWHCs6(b%AX)Pa{rg9OkgS#n93=X*@}75@0p*)w}{VT z?VlC705x?AW1STl2po-^fbhLYTZCst`b)?+gwKkcM2!9g^cD!$Q|2dpulN(n)Zd2a zL`o-8Ix&?_F09wNp8Q+oJ#hC8zUh5E)4g6wGO|>zM&2a9?hTufzlhR`D6L4Yx=GZq zh;curo<-ENhRYCMDX(5?@L|Ng zlrs6wwlhSuQY-m3`!wbvoBTth4^q=2PcZxqVhs@u&71aLGS)P)H?_%NNpYIw3nB7l z-ou|J+5)4*)HE%Dd3ld<`98V&J@N0U^Y1C)_taK@nL>Zvpc~7l9m}vCIj8X*`vTD! zdOk(@D0%e<>hlM=s{X(n^^nj_5xSc~IYV?FSqmE|bAzEkbBqn3ZKNMt(-5|cQu37Y z3kVA|CjVlFrIb@DI=fk{%~Gbak+oUM+AL*lma^_jBiA66QkDb11>p3ioZghvn{j*d zYB!ccDeGN-ZQ)#Uo-3Sg4s)cxXmCC0d}H64NZeYksvUw6O1S z5c(ioDk0Oll=;1s<#Q?9;~CWR4C?t2@kjh3!$|JEYBvC*_g2!Ggf29YE1qn0ZIy@mmH?xk!sF7fm9|DKq|862!WWqx`N+@e`)fm8s}&D0HRf zU71!_rqz|@$=(Xz*?}cE{6dHQ4F&Zn%i(OPJM}3gSF$~RDs_jioQVDG6dv^)>-sU) zbsqU&AZ0o!XOgm0B&f%v_SH_-KI1w&nfgwa-cIIpr__$iZ#}qAGufY@xrlo-01>Ja>naT#$B zggYs1C#79PO)esZ-}iBbx*}(&8)Yb8GZ`AmL|7u6YLW9J;9~L*BxNNj14t>RZu+|+ zOPpMAUQBuk^(>K6iqOI%ACmKIkzl@j)RvrWsa0EE{hm2Gn{k&jUu`3jueQur+en7s zh~%!VTSj~z!v2(_`=DkTQ=0zf%W$_CJj0p0;jZLvFy#+t9*5(rEXc2DQTdw zT&OL?TNrl>e-(1XP`D5HG`T^A7HVK_QK;!?upp{`AqA4md5!^<$P+`oLV&}Pjm7# zXDZFf**x-d#BEOg=Cqjvrx7R#a&M&_b~1r#@)lX`Mjzn=ksblujcEk)G(j&^C>@{@=s%|Qz`RQ z#yXX;P9^_o!jEr?i`@<;&tUQlCeL8{iox^}d90(|tewHEoxx0ZFw+{$v<5R5Ybb3E zrL7TZ5mF)_iA+7la0+;}fN2$w?oxgM^?#qK6fl(nrcyv{3z${`(<)%O4d%RKFy|d* zOt-Css!Ze~ly+1m@)1fqDq}k;lT?7E1(k_3wVC{z$-kNU>=KIGNTj)qG^TD>2*&q% zq}5y@oX!=ZTjX&~r(KyZF)886aElp=$H<_B3|H1nGKAA@Mak(*CEe`?O1k?!L(E%& zWmI;l5~~})6bCTH0W6aNlCFCxQyjpO8NiY`U8FguQJ>Qo>omqXjb(T`^9~l}q>M{J zo5DXqw#IjV6vDc8UuELoDl_q4F0HE9-qwhW!)v6}5n>dK5V=VyO&KHdoCyk^+->(? z+Ogi`{?I$-Cvj!|Q29hZ>0+#V)N-poZ-epW{&oD7;fwv1K$SR3ScTs{?1%BI(mal5 zj!AOeNq3q!E%g&aZuawt{oeLppjpO0h-x=gwDF_nRFioV3 zvnpq}Gm5{_j{L?tck*nwGv2|73`ri5Tq=7&B^wSOY>hp5cCmKVyhlH|XUIf6Ndo5s-uV8^RYD&S5wYtt+2n$9#^! z@;L(2-!RMPI4oauNGeR48*2^D3^cg^#y%VA{?Pj~^~n68^7uT`SkQnnt3Pk)su;gg z>=)wKUk!q1x)T43dZikL-)J?KHHz^&>Uc3j*iFsf zf^UKyK~=CDlSmgl=LLQ7mu~%n!74Er5)4s|gDZn8RaP)G7^;pBt`4qNO@iUUaMd&z z5sXmHf|0>U)jYT<7_G8{TY@R-#9(3Ys_Ggn3Kps2;O*dT)gw3*e6LCph9wMBJ*B_& zSNi4R|J6WszWN{h3&>k)sd`&2Q-4+OsK2Q)^@S=|Ut-l_v)ZaE)K_X7MyHkP8+`F| zhuZ11b%r=spp9SU40VP%S36HRFFPMNYn(5gtxkor!>MxiIEP)&J;&|m_IF3Qiz1JD zKlg49N`v0P`9c3+AWCHjay1mWxheQrFgmz3xGnfaa7XaV;KASz!PCK?k%w1;SCNOe zg9AYnnm?8>75cjVeg6H(!R7eZol@kWw|ZHft6ss3?FFaExd`jX7dw-j^PJc4d(ipV z`OJ9;T7BpI#>Iwj7M|mtgD;y7bgy#ex+B~h@%6iV+?md+?vw75&RX{^_bumBceT6P zS?7M{Zgf8LZt-q$%Dh{>Tb(bw+r9goa_@fcQD>X?nD>~o-}@i$f1Cr}bZ@$I(0jt0 zv@0l=DUgB0&jtv>MisZxoO^CyuY|v-V*Px?(yE=yuZ08c<*|j zxh=fUy-jXgZ;Q9pJ;&ST?Q}bNRo-E@*mr!~Px3wAbNl*%pYC4lXZo4$U_Z;xa)07y z``PXgKiB_}dxhWH&vS?Qr~9Y7!~OPtNB3I4li$f5<#+dcxYzqV{a)@(et*BeJK7)M zU+VtcAL3u>-r|q&N4aDDG5)RY9sXVZUG81}J^nrJ-TnjqFWr0mU-=Ka_xZo}f9>Ay zPxhy{5BO94sqTaRbpHwWA%BkltUJ;FlRw{`;=klCaHsjN_^-Ir{n!1)?(h7!{CC_Z z{N?^~_ep<+|Gqmrcp`YhofG^%_`Um7@V~+Tx^sgkgD2gmQQLFeXHer$yYqr)gJ<18 z27e0vOPSmIziwB5lw{OCx7RW~kngnUTF}L1e#|@1%Hbyi1%O-lg7X=ep_^Ioq_z z7wy&8CPi$ohXwhKFi{Iq)7=Ww)7X_MJ(lP9oEwqTn)iEXkw+hhsb%r%ihcC8~=E}iQ4X;;Gd*+`mOv^)VKa={%Ptv{|rB0?ep9CXQ=~zk>5=n z_DlS8vG{eKf4&p(FZ6%x1pYw(Cr+||m4B_1>0j^P;xzZi`gb}l{d@iUozwgY{siYt z{~`Y&r;Y!JKhbIHPx61`oaH~}Kjxh6|BwG$r@)`-&vef5XZe3{3jKNhb54=}g8zck z-T#aKrc)fu2xd6v27e6x=*W1zl{dy4>)qy!^M2ut_ojGLy=mTWz2A9{drx|Eyr;Z* z-V5G~-b>!=-eT_!?@jL=Z@IVL+w4_%UwON{DE>MNpUm}rU)Jgx`%V2b{d4?6zq8-P zFZKKQ7x5Bf9w-}^873;kF9*Zf8P-%vAdf|GzdPziS=OjcKkRft^&f23b>RY&m@ z_)Ga)J*+aoQ~XMK-Xq>5mE}$L9#zfYFQ%$&=s8WbfWP>iI#K+EItki7rB3ml_MTR) zy=T2=)v53re^PngpS=a@40w&V)mhO09n~FqSfz@+)!qhmzW1f~r5cDFZB~~dR~2fI zSLy9km&0r9S66xmz3KAw0-qYBg&63H1r;dA9l- z9%O+k6R)9m!E3yOk)n$khzFmpR3CLO{_}FYdRpCy-sxpETfL&*P|vF+>NB-aeXcgD z)##%(tB=t?eTxz70jG`n%4vrYY7Y8=OP$l4%bd%dbDf_!^PE!WIp-y38v3Y@oSEzs z{(?KMDb6xC%`I`hMLW8{Jq_*X7WXXoR`-7QGWVD6Yv>(bcQ?9ExD}Bz-6fH>k>W@Y zDT!PcX%_iuWKyJCxPe+zU#zmGz-ib_&ERU>+{5G=E%ZSYI8ha;3 z%Dj`jb0S}RoxCod=XLc)dkM6rlM`COnp!8EiX6k55>8HNneZc?!-v7vuyUM`nsAaz zPRLIvRXGWL5-w1k5-v)(LUn-+-l;B3xDS@t7qXI$!hKD`aBz=I7^(UuT%T~Gx;Wuy z31d|Mgs};?VKju%042%TBNgM5naaf&WtQ?VPMM4G%QL|nE-sZvS7?qIiyBq;h%S6ztl#!7Xn|AGI3O7>Uzt5lBv zq5q*e!C&pKR*n3R{Et*Ce~rHeJRkcXt7iTu{wJ!9{}2BksQQ5)!Z-h%MkYq{|oga_-c4n8Fi?ZL7xEs zQy*LqT!=B&MZrbLRbPy>5-`&02g;9wALGv}`Um|n-nt|hfYH^Z!KL6I7z~6zzbv>+ z)8MD-4Eq0;!I)qSQXd

7QQ{8- z4?w~%gI}V=Cj=9K9}FG@ekgbdv3`XSW@hkk@GwS-6N8DMJQ_TTaAB|z`eQ5wei;$A zMDMc<;fi1dLaDhlj6c6oj`Xas0I9zdS${tJrlzdLGucBO4;$&i(mal(8DVLru{1rF zX28-+V`-+dG&5P6%~+Zdt29ptF2@Kr*_5V?a2<|t9gc8QIKp+=o4V{xQ(2nFp*Ot+ zv7}5JVbpjl@-HRZ2;;}wfTeuXSiV_S`DR(=n-<(1+>O$dQce!;4ekY&vQB1M`z-4O zmUWU<)=5@br?IRvSk{e$M}kK%`j!$;3w|B^8g)4-m;~$jP4FAw$-!h`sfn~;3dZKm zt@=2Q^>G~P<85dzBlKo0W&E2P{I|52GudJ?*hu*I}vi#dZWCXX#9g)QbdwwN>7VoqU;>Btt7VYQgHtYe>b+>~|PhIO3CI&R83 zZpJ#!W*z6Uj(yf~Yqpqt(_*Bi(^=E4O}mk~%sE!;$ztpA*m^v+p5s~HZCT&xtnaq0 z?^M=zTh@0f>$@rIy9MhzhwZ5a>pO?-sVVDQx2gixcRK64fc2fg`fkMfZp->kW7}%W z`c7lpYRdX<&iX!q^?fqyyD97YMAr97tnU+9-zTxYo3g%7rbj(n#=7ckjCKEjQ2grI zGU8S3>0QsJcRd^4^-rLScWo)7UtAR*dp3RSS+twhY{zYBH*MLD+Xm8(+Xm8(n^^6* zF}?AR*qToZ#2W{+uw1t0PP8+uP{78HS7})LOHs$E2>PKU{0pxFB?GQI73+c?Y%vL| zk4pI}UAazIP_Uw+PFAO?Q_xHQ7~x3Fqa*5<=&MgbUp)`uOX#s%v&U|Y9(xHWZ(&yH ztL5moi!r<04C!0&OGNLz6Vi8~4^L9x;V1v|upc}JaL?=lC(Ah=D=p2?x3|HZvn?p? zoO9GEPN7o>T{`367+mLk=K|&7OZ-0peTZ|l3Y=^3%wDl`FaBk+t@E%mNhM)SJx`sA zQNV|)5dHspgkL(l)g_pvey38LgU&&93I2&917RkfEh}_8xE+8oR|GD^D(WR}v0I|f zlaT^K8F3e34tb**h!OWKsuiA>8l#$H>~J^mJ?{PLe2gGwBCd?YPsQBwHQ;6LGKBBD z>ktcbOYoFoB<{OkU?g6|k$4ft8lGx_aYnMrjhum5OfJS9Z4sUoIR{}stT&t#xgjzM z_|eFt2p`An=297hAbdLVylNWxTV#c57I{DNzRHfQjQm4&i>!^TSKT9@V+M3#)z|2yp0iZB4*Kl$Ef>#ZzVWC@IC-#jrR%gT5lcjMz0Lv7v2}D4M)zWc$>UUNM)P1 z4Y9uVz6R%ZZwJDi7)4)zQS=^g9`FtTAM_5Yz&nHybzASScNjcTFRF?$hd_(q7`s^J z=gPzUJWzq3=r>Xq_(^^e+SYOYaTtfB`su2z%-b{XB#+11rR={tV!J%)<&X4{M8&Qaiuh|6}h!iW@GY4xr+$xTE4SuBeEp zxG$dzqN9u}DxxO;xu-hVjLUrU{p0_9|MLuaI9+|as=B(W?)#qezVE$-z*mj6D1gP15A8VL3 z40|47jlic(RukHrtx;GWV;u|}Z%x2DhguV{&S6jixljR9@Vzsj0&=aH)=aE(Bvimy zYqm8T?MGQhVfkol4u0ueYaX_pZ_US=h&7=7cxw?_PO?tH-Vk@d`ire4Xg|$biglJ- z%ke2xBR+*{MEgo>C64@T>uj{IvR2`DX-&}wI`UkskJtqE03C@nFSV|~@?WgKV0oRj z4(qJ9)?@h^>l)y-*0pHaU|olGuD5Q+GU69lzSFuJsFlcg>ptr~tcfTFK7G)75Xb+J z^)QwZ(ZHvOXyD3jwYCDahaOH3-IpG^fF3$b4?UV5IzSISoE|zv58aC%x;H)a1bXO3 zdg!6_&=vI1gXp0L(nAlYhc2Us?nMvX8Bw%G@CD6m6UfD?=%;(cFxz_i>4sl0TbGMv z&`qRO3Zl!&VeGS&s-nWw8x0>F!lHRwH-nWw8H@s_u2~y#C3PaKQo z?`|l2Y-e%q=66n!$bwnK7-UGjG(66V{ulwlNb9IaypFU## z72oox`6!mPkIyw9Hy_6yo-m(43u5QMXU(lRC)(>L)9dG&+szm7jW3!n;nN-Ft7z8@ zAjf>ud=o8in{NZ(K?E(GoFJE+z%t)A-$%QSsU?#c_5$^|Tf9copexUZ3etJqj zy`$fH&Uy|$Nn2-wcG;jsPNOY0XoYQBVGr%EqvQQh?uhq89csnn*w5I{pha6!KW%6- zt*4iEGnuwBnN~8H_Awp&|6W)gtw^+eY^8m4U>zH=JOp;IiFUA+cF=(xJQD5N_F1rf z%do6fivzoL1D3URacHwzX|qPsW{srHnopbM&}Mn4W8!G1;%TQ6Xr~fsr;ehXYK>7d zakNvDqiQA#7OIsNYB(*_WLhYP7HT#vR4bLuY$_WYdG(Q4e-vy`D{YWN8|0ZDNyg7{)Q)l!L( zXp~`DYo-!pe!5~=E2k1FrxK%&F$yhOKZT94#?e^TDyqad&sdFRt))tg3yjOKtQFNE zR8)shQS~-%GoFNs(z>dix@sVG)gbDs!>Fr98{Zq>V_U7RvZ$^~sIJCRU6q)5X1D8l^!C29-;{z0(Urk!*YDO0v@839>OtK!Z)!+CH7`T%!bGO!an&?Fm=tUGVN$+4Qttk`eKZetPnDieG{YN}9Gaq3cmI(YrWQrE&Bz%~YihRcQD3gsA3ze!SHtTkh^Qd-n61^prS3NqOD^V%THa~ zLS5TnjkHE$pIY6vAg?tV+a6>cgl)CbZK2XFwhpllL5tSAb=12J@Su~>qE&A#GM!Vg z)imn}azxtgEf7MJly*3$=AIwRJ7Ebuqa@tHUhv6@>mj8-b|AynR_md++kr1I`deT{RNhro-cy+inMM7rt7MK4bD3qD zLM@&~EuKa#el)dskXk%MEgqy64^WE-sl@}-;^mB!ccm8ZMlIfzTD%*zcsb+bA!_k_ zYVi=Ycs}FgM=(x4ow_{8IQa~!^C08oGpNza85J*Q^t+ra(4j^zCKq(b1xHey7n23L z{I6B#^+hWcb`=$NkP16Ug&mA4Y|RT>sk4J*hb?4>4i)x6glCc`xC5_xAk=!Mj z+$DwFCB@iaY!HeJCKU{36ZUf-#vEoC4};C5lg(t2&193!t!WQh(-c}$MQdu% znkLekR?(Vf(wbT^Ips`R(=1w3H=A5VJKBkMw3v3(patzj3+iSUd(&$6p^Z$Wbxe%O z8YjkNjWcN-b7>v(XdQED9rI`%Gie2@X$9Tva3ZZ>0|rpGNsWn<|E@@ScIX_@kVkqykFO-i913eXNE#AE}rX_GQ(lQK=64K%4IvuU3)sVB3k zAx$dAELyBgszgPVXi^_$Qy-ethuO4enbe1FG%=fM(4>XSqz*Kx10CwXZ0bOhdM`UB z8<}mE{nR$LwlJ?#f3Z{GJOX1l@--gI!foE zHO-`gila?MEhX}L5o#wNwNpA(Q-pdcLcQdpUW!mJ`KXjqsg!(FO6gQe1E`cD)JPGk zqX^ZJpX$g*T@;}%>Q6-!p(0ABBC4epN~ad`Q46I~1x2WW(y4zU)IYUUJ`pM(A2m-Z zHBUO#&H$>NTI!ry>YQ}yoCp<8gbHT>6;6Z-CyoloM}?D4Z4;rk@ln;JQq>Hgs)uMgM&hVOd{iR?4$vXbThEJfYLC9u9)0L7-RiX} zdc}V9if%@)l%BAdKCqg8FM)oq6a8Kp{a%=UuN(bd0rf*Sdc5xRcs-~edQm@w>Gyim z@72)nb)w(vO}`hUW(d;nb)i}aQ7we17P`_CmeCWIQ6ZF38+4=J>q(E-lOC@dJzgO_ zUJ-eJ89iQSdb~1vyw3D^-RSEo>Fc`Dr*)%G%Ov~v(X(Ze{b!N=`{?B|>E(LU%azf~ zmC?(U#pKk=$n_)ic$xHane=R#WbnP{-!jSFb)Aa9|4*a7$gN4ynJ1Gz$Bb5>{C@3; zt~yaspQGzdRJ5YRts>F&BO!W~5dBGjJ|sZz5uo=7(R&2wH$wCq0eXqv^bZ5*AL{8J z2GBnYqJId{Glb|9Li7WJVroNr(+~8H@dIJ{fiV3*n0_Ek4-lpY2-5@fqzC9p5737m zppG7(fgWHWZGQr7f0(vEleRxh+n>*9WIp+5n6|$Ut$tFB)%VcSchr6SW5tL0Pij4W zS>^HHsqb(rJ7Q}(V(U0`?S^99Ou1DXwAmJ|wOf~=qBdLG<^XMTh_<<&wmCrC9H4Cu z(KZKYn?tnC18AE=w9WOj$^lyC0IhO>_Bcd)9H1o*&=S|v2G`RDhiHQb&;|!+gX?L7 z1GK&YTHg?@?*LlgdfM80+S&kZZGcubK>He^eXXZ`4bZ-ZXkT5+8lYvZr)3S%vJRkS z4bY~B7z+x~n%2{T252<{w3;DW%>b=tfL1d^dl{m24A44;Xct2VSVUb7F_qeAFH zh2UD#5>^uSpfz>t2~%iIO$HWrLe{!g{(e>tUiU+4JoW{aH|U4y5MSB zUq7v{pVrqOV}1R!z5!M=6jN^`Qg68R3vP5J)s3Z4T~zF^S%~mDCD5pHzr|6%b!HYc5|agWm<8<~lLd`13)+iW(C&=kn9PE9 zWfnBTENIuL>eE@!2(zFODnK*pnRTtFLmlX+4(v=F7@z{IVE)tf*cJ5HRaAgU^xIYR z+g0@274+Lx^xGBm+f~$i)zo{{^x-8`dfn*BGw8`n>B%$b$-B^#S5WB%=+7(Y&nu|z zy3wn5iSg>AGKdHqgDN4qE-E3qE-FK1uDq} zD#-=X7_D+6fSF_jS!4v+)P#M=3wkhS)sGRt-Z7D@p3%sa&S&;#{Hh-#fc+W8>c*^GKdt$wfe=xwbB^Za-(~-)RQi==+KiopBZ63)5m;fg!xP_^O z)y!d5Gs3K9F0+~us$4I#nh|C-bC}hP#AG!i%xaoczg}iF^O)6)PzjsNYUWW7dzsbD zVOBFjZR}-Mvlp|PKI&wXI@!alW`tQyUyNopnbnL?Ih)LCc4t>iWb?8V$>gt<*W zHMz;$rbA^OpfWe9%&VB&43Yy@kOP)7w;3W6tYU66NIqCaK3G9MSVcZq!Q5sMSz!iQ zVFg)XDHVG+a>FX-HjBs*tC-sik|$PCy;qYhRxr2ea>goZ_$1~wi^(6W$RA6Y)hr^5 zEG3JqAdAc(i>xAxEM-13L@rsyOlA=oWfd7^1v8mN?GpO^sQRi2Yjg~TdS-|XN zkj%7#%rt}9OSjUuipoEU*~=igY6bOwH5qFK8EYxCmmx+0x-oAVB!{hH6rdaPmPO>V zRm@n1$Z9LdYOBaSdNKC#PGQNrFqeYD7|6TfFYmz^V+&)9 zw_}|bplZGJlqnd&ze5;|n0gQ;{Q=`Dew069%{JMFt=bjFDPjb&sRz(vw1fw~GbFq! ztV%?jDpftP+zaC;B)n-gmi5Sqc>2)<`q2c&O}+G{i5#(xXOtU$LX*QE-jv~_>^$VtHlWDr+hN{UlJ>;0pzKq z>zPyVkykb_r{H4`X&}4IC%bH5PQgcxna{q_z`ikRUN~&s$fhrHJm)FIfiF7|AJ?E$g`?rc$Ql|)*Mqk)=ZvN zO`g>pQ$5y9o;B3e)nm;uJgb^KYdCpUa}3WKPM%dAQ$5y9o>fhTRTaaq95SqCGOQ{x ztf8zvb{ST448xLSSi{Jzn#rmpSyfXEpR!~4lubTWMLyL`J~e_&swt-WcqrLZa|~~? z$(wq|@TLaxrVQH9eA>_+w4s^gO%3Et8RSh3w5R#xO%3Et`Q%OIw5=Gwgb_^nw5^zl z03()r*hip z9<z%gp~^iF*+Gyq$|uwR{tnFpo2kk*@yCd<}!Af%ZOGTBU-tPXw@;I6=FoIkP)pSMzjhU(JEp@E5sOOE~8aBj8Wz? zT9v~Xr8~Ac#28eFc^sF$=EtztQDm?AF}$^zoS>OGoq>#25`Rq_u_cybO zA(yPSfw9HDQEsb8OL-Y#?8BOa;wanIqoumCt|5(;2dT^fx%{`85wMyl3)b^n74GN4 zd6*?;5o&>TeY7-}noEHfm=^#q!fY&3&l)2vc%#dKdQ_?nA9D@xTJu`e8tbZL2i3=z z(F?Q5+=2bvY2Jz4HfEJU%R}ZvSbi84$2R9@k<{Q4I{GcF`5|Uzv1rF#ORY@IIwLGt zVFRd@tXp-9nLs3}cNw$OBdUYsO$B63LB{5a$(4d+NkQ_XLh_?R@}nTLS~kZcc*u{u zjKsx}AH~N+-#lbS2j;ePRYj0&sDunC$e5Z#2IOH(t%wXLLc29!hwlt%{SX2HT_ zKmjtK5E)RI3@Ahf6ea`8BLfPP0foqb^2mU~WIZ7=ooq6l95S73a-2M}n>?}`H#?R` zb`v6_v7^~2eRVBzmN;^j0&_Vk-YxQ!AQ?)KQ6ZaE32|g7K}Ln*$WRP&6Pv8W9j{zS zJ`!XMsDRO*;^_UMM?J-niP)@Dh$9mTGVbFg2Z$vc9K@7SzXh$rueBk!bol6mjGf2H8X$*@Q(l5oEl^%lprYiPQwi zAcBn1C^CpnG5Iow5t$+~h#(^}9x@1<#22#egIgxtX)cj(Be={kraa)%&eE*`Rm zAfqi|vW7&mhCH%{9I}QavW75OLn2v2n5-d>tRYO+kVn>#Mb?l_){sZmkVC!@CSS-R zUkH;gB$6+L$rSR)6q3jk!ej~oGKJ1$3SlyZ95RIvnL-wsLJpZi9+^TmnL?OMA%{#M ziA*6(rVt`i$Rbk+lPTnpDP)l;WRof6kSS!5BZSBi637ukF4w4;q&O*Gh?GC^r$}iQa^oZGQFsuUNnXNGo2nXm%cHVUa^#3(MPZ7=JMPu zo}ZpDm7Xw-o-mc3FpZwjPfzHh5A@Od`I(txzGcnaS=4>MD86PlmC!+LL6`hh)c8*ID!lHhqFapO8s!;Abu- zlM2}%t(ns!#^T+|Ia+R4ullG+T|1plJDov0olZOLqn&p3r>i_&3vJRuXVU)~w9qy! zbT%!tJ1*6&6|-rNZQ5fQtrgQFjok64*|ffHm6-O?*TVDaIU{V^U5j?trrqtR64TWL zvGrj#Ev`w6D`{~R)tya?D`|1vS}~ipHk(#9n^xAQm6f!zHm$5d`|A34gZ4F(Hq}p? znnj!Hr|mRpH4R!yKO@zdw1siBg>Ge725n(HtzaDOpO2Q$$2%a6mM@)_&#es0pk4~m z@}<${#nIaNXzk)@)iQYBq|u&b(4M&!VCl4E8MI{a`y)~lgpYPBjdm-Yb}NH+D~$@r zwOd|VtPI+!I4YS?Or=)_tyDbilaKZ(p7tr7x+O&WltKHHLi-d)`{Y)ArSoo1rA>;X zO7YPqx%FNdv`O*QC$3G3qb3Q_CZ*91#nTS?Xn}HQd)!Jdw{pR)^a@dXglLTd)E*() zq&Qk5AFYvF=@nv+N~KN8q~6GkVfp#AObN6}3A9Oxv`OylNBOi&9$F?3S$ikiCwDH$ z4%V(`tjZ-*PoRBDqJ2uHeM+KzN~V2Eh%$9O+gC2_Qv&T%0@-;&w7zOBW@~e2`1&R1 z&Wy5cJ>tQ&G)c5HCaR?*{>K@Iq5*a*;)f@RGsGog11h^7$9w_ri!Y^+$(Z#IPbgd?<$JO?OI#|h6ZeQGFgx`Jn3Y;$*6U7~W61qJQ>5dU^bmDol$avsV9tZH z#bwBf-z%QPY=b++*HXz;8ANqhjquh_91Na5uzp-nTsm+JaLb7Li9xY<MLHV@Aoj;#6@ta_^fkQ_?HqL$OC1 zGEIgg<`(C9uyHO5MNiRyF%VP5F=8=BMf@4M;6AYbS7G75k)}+SVc8?PzJpm3ibO9l z5SjjInAhP?;v8`WGWz$6r^RdV1>YjkmLUryo(jSJdqlP<7FA-97%Pqt^TiTzuDDX% zEFKWg;OQqHi|?c@Gi9N~b2qrYSL8skRAZLLabmhyfSDoA6IY2_#Afj<=B)Ue*ee}G zV2fn0==yOY7qtkzF*5sLF+(iG91^R=UofNNgJLV@bo@koFFlyOp;%T$*N+!I%x}>L z-fX;>iCHO57w3z$;x^0z`J8wQb$Hf@s0~70bj0Vx8EC z(c9ZFU*vA_gN&28n9IC(bp1rkVNs52I1F$UcR^mOxhlo!Sw@t5HINf=L_!jYf;>X0#hKU!GkMuSWhZ38Ke3ZC_ zxQ)1j_y+Oa*15;ciQ7foP5g?um)NE;-Xz8mQ;1naKQT-!C3YqDBG$AXGrcvwj@U?S zB90**LYzXJK|G2$k9a)s6yj3inZ$E(I1A!0B3@2hOWZ)bnRo|r6Y(M9V@l4{m#EXcR z6W0@cS(0Gg`b_>2804P+2;}p#pm_9=YXvHy;xwic`Lry||E61#iSBbY`|J~RHaibZC{G5cCz$&QrD-gZ98S$To5YgF& zSj#(zo_vN{vNl9Gk`S{9APUh{R?7&U9MO!~ACJIO$`;6zX>K*sh)IJs4VeVwUT7Gv6 zM0gwBJ!5tvegmoo-PcLc*NM?r{S0;NVgKjjqVMr!Dz-0PYRY|#Dfx=jZ0 zTsi#5x8T3qaw%HyY{LC5SPC}b|N8wcGPoM=-Dd#ntz__Wc$q>(AcrEBHUp8mMTjlk zjJsz$B3-)?NlU?ZdEjL-9Q~Xa$1#9j2YklK!Cp-VOe(sBIcBh=aPAVEI4oOE{Ql1{ zzdDNG_4*iv>Uj6>6ERRc;REA)u+MB@&i+p@p94Pe0Uak#f4={dE_hezbOrWuFpkx! z<9>VWU+T#v_c*Gs+})|(|5=TGzkg4)cvs;>fW4dnT&Lr=*7K7FV5Kuqe=cOFdH*?6 z`b_-uGZmPHyFCeU=`o0Hnj#J{@hstYR$yz#Sq}6%X96=Edj4VnMq|H`A%^BKp12cmDlPAkM; zv83?p}mmlX3(<|m;4%6ywB zH2U`u_W+fDkI2TeqdqY|MRsZxa#MJI74lK%TNfZxei1U{YphFv^9}9a0&i@8A9yQRr}W=}Gq3!crB{8d{-!=rpQ_#J@9H!4x%xtViRVRs zt@fyI)VJz8wO4(w_NgD#kE%_z8yHAnC_RG~W?`}o$M6_lBhH975-<}}x{+ig8!1Mr zk%r|ABh$z-vhif4T*GJN8Ga+*2pFA=pb;{{MuAai6dA=viBW2FHp+|&qlixx7YpgTY z8&@0G;OSBuFbeQG<9g!;<3{5q;}+vqjNsd7+-}@q+-clp+-=-r+-q#Y>|Xa94;Y(` z2aSg?$JZmqU-3k$$M8g|C-6+Fr;IJe)5bH#vv@Mqa~SRSys_PQ!FbVl$=G4MY`kK; zim`vM8*dnI8gCi(>L-kAJsr8ml^CyjHpZYXL!ICX)CaD@Xw`EuN_Dk;K4$(|G?O_7yt9SqWr&gUkvz-`=aSr?u_xcH-7!j_}_A0{Crp3{KwxH|H@sF^P{Lo zJu9C2gL>A(Ffw~4p5t^Rp5ipyo^LO}i0s7}O}zx8sNb~TvfsAfvD?5fx;R~(Zr~w3 z;JbRlb5%LjPH(4=)7PnS`oV|QIuU1pQ|Ht>4bDJkkTck6bcQ%Xond$~+9}RrXQgwN zbGEa}ImbEIInP<`Tr6Y`Y?*7})VuH%Z=*$XNLX~uztnqZ`v7Bwl>AYsoLA(tVxRay z{3w1BZOB1mXcRKN2C}Labb*8Hq!$^)cx3q!p%RjjGfqW*HeJ`y=#eJKMdl)3n1@Vw zJ`_YJ8AR?jjQnaLa-hY?Q~mSCxmP)p#ou$rJtJFE_Ty>sW ztSDD($lj8g;GOpsrKbs~gmf>Lzuw zx<%cpZc`i8?dlG7r@Bkst?p6xs!bRHcE29^r5?n{uZPtmm>>U9^%zFFJfWUcPpK{H zY4wbHR&B+2mu>2KwOze{x$|FAJJieS74@omO}(!4lU(0YZ>x9kG`|njPKiBzp6F+pw&|E2(`&|=@n(XVXeOD-W(vklr(wKwhM8$*nb~HJ znQQtmccS0S$H?hUX3z|oVY9$2G>gn)vjiikJDX)@IYv)+(X%IF?!+EurPYevigW}R7YHkbp=K^RfpXbv%ln#0WD<_NRN9BDRVR>jfgLFO29 ztT_&|DvmcNn1`5$niI{#%t@GEaf*4kIn|to*#)PYGt8N0i+Q9u%baZlXf z<}r9m;TNc8`pW#;+=Edj-ZAX2R)b-4$2(?fT>ao12Z;IDr zNHG33*-EieQ4N}o3cwpMitHxqX4L=RYHhS`!)UTQP>FLFpRRc?Dsb*Y725;WW<9

Z@4WQYq*`>^U`Rv!S$e5!G|J> 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 literal 0 HcmV?d00001 diff --git a/project/assets/theme/fonts/montserrat/Montserrat-Medium.ttf b/project/assets/theme/fonts/montserrat/Montserrat-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..db5b1af89c2f416bd41dac41bfa19f48b83f89e1 GIT binary patch literal 260236 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

&yo7o^d0IGc!PMt~DGWVV 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

?`{lJ>rSbGf-3EytO-7Klc#M9WF$DOlECImujQ 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�}y&6uAD_Y$6NhT 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

L3^|io} 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 qfmM(!s3SNNa_b12VN+tH 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 QImo-z7}y+euC(HR02hem8UO$Q literal 0 HcmV?d00001 diff --git a/project/assets/theme/gdquest.theme b/project/assets/theme/gdquest.theme new file mode 100644 index 0000000000000000000000000000000000000000..1cc33cdce86d42d07bf74a214b58437f95395543 GIT binary patch literal 2688 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 literal 0 HcmV?d00001 diff --git a/project/assets/theme/icons/chevron-right.svg b/project/assets/theme/icons/chevron-right.svg new file mode 100644 index 0000000..258de41 --- /dev/null +++ b/project/assets/theme/icons/chevron-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/project/assets/theme/icons/chevron-right.svg.import b/project/assets/theme/icons/chevron-right.svg.import new file mode 100644 index 0000000..000f669 --- /dev/null +++ b/project/assets/theme/icons/chevron-right.svg.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/chevron-right.svg-f77dee7a088177a2ac1d467f4c7cd3e1.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/theme/icons/chevron-right.svg" +dest_files=[ "res://.import/chevron-right.svg-f77dee7a088177a2ac1d467f4c7cd3e1.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/project/assets/theme/icons/chevron-up.svg b/project/assets/theme/icons/chevron-up.svg new file mode 100644 index 0000000..4eb5ecc --- /dev/null +++ b/project/assets/theme/icons/chevron-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/project/assets/theme/icons/chevron-up.svg.import b/project/assets/theme/icons/chevron-up.svg.import new file mode 100644 index 0000000..14e96f7 --- /dev/null +++ b/project/assets/theme/icons/chevron-up.svg.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/chevron-up.svg-48b5b69265734774d0a7516dcc6f0863.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/theme/icons/chevron-up.svg" +dest_files=[ "res://.import/chevron-up.svg-48b5b69265734774d0a7516dcc6f0863.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/project/assets/theme/panel/panel.stylebox b/project/assets/theme/panel/panel.stylebox new file mode 100644 index 0000000000000000000000000000000000000000..1c623a7bedd81d02d197af0687720376ed3668fd GIT binary patch literal 403 zcmV;E0c`$KQ$s@n000005C8y40{{Sf0RR9fwJ-f(Ndk=v0H%>UFi=rM04wG5WBfm` z4FJi6SN0wFo_rwL+n$nsm{L;(6f+R@+zd2IpmjPB1FJ%j2Ppt5051UAaM^$8N+pb3 zp|ZHP*GslMo}w&fHl5~#tfI{I9;wg^K*rP^L` z<681!g}m?v^+gb9k}!31oEI5QX5#bNfG8dS1i(}fD1djffON0heqL?F@}(e#xVm_ zA3)jt6&OQFAcO_am5>4XxsTXb%@fB$Gv7g6nd+_YanJ^U6S}Cw;5m;53;(|eI@R_r x)r8*x9SjgoFAF7flS5$f%7Vy27ck=s1W)rc;~5vvQp77rBjB46bMB!z&+N%&k$bh7+nnu~s4k`dE05AaUwB4%zlB<;NadoO5 zZevTe4OKB_pYngoe~5Rs3(Zz&+qC7sBj7*d54~6hSr;$ltnE}`CVBl=IB#2p(DT1> zX}kAf__Q5)M-b!5`=SjUgE%D&@4o@$*h|(DS-S+lUS?NDZvv4lmy<>t%hvU9c%V$% z_%LiGBdgy!@5{| zj!GJ}qbe`VaV8`t#ws`xjg3HQgUsw9sm|nQ$s@yoxSw{ literal 0 HcmV?d00001 diff --git a/project/assets/theme/slider/slider.stylebox b/project/assets/theme/slider/slider.stylebox new file mode 100644 index 0000000000000000000000000000000000000000..6fbfe55919efe9c8c652b836acf1a38e393cc024 GIT binary patch literal 452 zcmV;#0XzOuQ$s@n000005C8zR0{{T50RR9fwJ-f(wE`6l0HzZ|GhmAnQUHL?cl#=z zpjN1S@mRN#pSny*=}9E{DM`zI4LuespeCfKlvHrb*p^WS7Aa(XF90$CHURRnFLO<~ zX@&nW=j_qSnKHbtwwn*u=@{Biy=?z${x`heqzF|Bo}%vjrvUt){tAzjr$xbB5U`FC zC-|ylwlx=6l@MIFsf~{s3u28)gB-JfBib|h%6TacKOkTN zm@`H_aR{hr0L-0XpUH#(f>o|yYEwLp?2E2~?4w*>0xczguFWVJHkM#hCQrpZo&{)ys|-L&;{`L0)wY}n(G-?&*drimX~YGdMH>@Q$s^i8`E3> literal 0 HcmV?d00001 diff --git a/project/demos/follow_path/FollowPathDemo.tscn b/project/demos/follow_path/FollowPathDemo.tscn new file mode 100644 index 0000000..ee075a6 --- /dev/null +++ b/project/demos/follow_path/FollowPathDemo.tscn @@ -0,0 +1,3 @@ +[gd_scene format=2] + +[node name="FollowPathDemo" type="Node2D"] diff --git a/project/demos/seek_and_flee/GUI.gd b/project/demos/seek_and_flee/GUI.gd index ae83330..e6826ee 100644 --- a/project/demos/seek_and_flee/GUI.gd +++ b/project/demos/seek_and_flee/GUI.gd @@ -1,17 +1,27 @@ -extends MarginContainer +extends PanelContainer enum BehaviorMode { SEEK, FLEE } signal mode_changed(behavior_mode) +signal acc_changed(value) +signal speed_changed(value) -onready var seek: CheckBox = $BehaviorControls/Seek -onready var flee: CheckBox = $BehaviorControls/Flee +onready var seek: = $MarginContainer/BehaviorControls/Seek +onready var flee: = $MarginContainer/BehaviorControls/Flee +onready var max_acc: = $MarginContainer/BehaviorControls/MaxAccValue +onready var max_speed: = $MarginContainer/BehaviorControls/MaxSpeedValue +onready var max_acc_label: = $MarginContainer/BehaviorControls/MaxAcc +onready var max_speed_label: = $MarginContainer/BehaviorControls/MaxSpeed func _ready() -> void: seek.connect("pressed", self, "_on_Seek_pressed") flee.connect("pressed", self, "_on_Flee_pressed") + max_acc.connect("value_changed", self, "_on_Acc_changed") + max_speed.connect("value_changed", self, "_on_Speed_changed") + max_acc_label.text = "Max accel (" + str(max_acc.value) + ")" + max_speed_label.text = "Max speed (" + str(max_speed.value) + ")" func _on_Seek_pressed() -> void: @@ -26,3 +36,13 @@ func _on_Flee_pressed() -> void: seek.button_mask = BUTTON_MASK_LEFT flee.button_mask = 0 emit_signal("mode_changed", BehaviorMode.FLEE) + + +func _on_Acc_changed(value: float) -> void: + max_acc_label.text = "Max accel (" + str(value) + ")" + emit_signal("acc_changed", value) + + +func _on_Speed_changed(value: float) -> void: + max_speed_label.text = "Max speed (" + str(value) + ")" + emit_signal("speed_changed", value) diff --git a/project/demos/seek_and_flee/GUI.tscn b/project/demos/seek_and_flee/GUI.tscn index 06917bd..c3d7918 100644 --- a/project/demos/seek_and_flee/GUI.tscn +++ b/project/demos/seek_and_flee/GUI.tscn @@ -1,98 +1,143 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=3 format=2] +[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=1] [ext_resource path="res://demos/seek_and_flee/GUI.gd" type="Script" id=3] -[node name="GUI" type="MarginContainer"] +[node name="GUI" type="PanelContainer"] anchor_bottom = 1.0 -margin_right = 116.0 -custom_constants/margin_right = 20 -custom_constants/margin_top = 20 -custom_constants/margin_left = 20 -custom_constants/margin_bottom = 20 +margin_right = 118.0 +theme = ExtResource( 1 ) script = ExtResource( 3 ) __meta__ = { "_edit_use_anchors_": false } -[node name="BehaviorControls" type="VBoxContainer" parent="."] +[node name="MarginContainer" type="MarginContainer" parent="."] +margin_right = 218.0 +margin_bottom = 600.0 +custom_constants/margin_right = 20 +custom_constants/margin_top = 20 +custom_constants/margin_left = 20 +custom_constants/margin_bottom = 20 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="BehaviorControls" type="VBoxContainer" parent="MarginContainer"] margin_left = 20.0 margin_top = 20.0 -margin_right = 96.0 +margin_right = 198.0 margin_bottom = 580.0 -[node name="Seek" type="CheckBox" parent="BehaviorControls"] -margin_right = 76.0 -margin_bottom = 24.0 +[node name="Seek" type="CheckBox" parent="MarginContainer/BehaviorControls"] +margin_right = 178.0 +margin_bottom = 26.0 focus_mode = 0 pressed = true enabled_focus_mode = 0 text = "Seek" -[node name="Flee" type="CheckBox" parent="BehaviorControls"] -margin_top = 28.0 -margin_right = 76.0 -margin_bottom = 52.0 +[node name="Flee" type="CheckBox" parent="MarginContainer/BehaviorControls"] +margin_top = 34.0 +margin_right = 178.0 +margin_bottom = 60.0 focus_mode = 0 enabled_focus_mode = 0 text = "Flee" -[node name="Help" type="VBoxContainer" parent="BehaviorControls"] -margin_top = 56.0 -margin_right = 76.0 -margin_bottom = 108.0 +[node name="MaxAcc" type="Label" parent="MarginContainer/BehaviorControls"] +margin_top = 68.0 +margin_right = 178.0 +margin_bottom = 94.0 +text = "Max accel (2000)" +__meta__ = { +"_edit_use_anchors_": false +} -[node name="Controls" type="Label" parent="BehaviorControls/Help"] -margin_right = 76.0 -margin_bottom = 14.0 +[node name="MaxAccValue" type="HSlider" parent="MarginContainer/BehaviorControls"] +margin_top = 102.0 +margin_right = 178.0 +margin_bottom = 118.0 +max_value = 250.0 +step = 0.5 +value = 20.0 + +[node name="MaxSpeed" type="Label" parent="MarginContainer/BehaviorControls"] +margin_top = 126.0 +margin_right = 178.0 +margin_bottom = 152.0 +text = "Max speed (2000)" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="MaxSpeedValue" type="HSlider" parent="MarginContainer/BehaviorControls"] +margin_top = 160.0 +margin_right = 178.0 +margin_bottom = 176.0 +max_value = 450.0 +step = 1.0 +value = 100.0 + +[node name="Help" type="VBoxContainer" parent="MarginContainer/BehaviorControls"] +margin_top = 184.0 +margin_right = 178.0 +margin_bottom = 274.0 + +[node name="Controls" type="Label" parent="MarginContainer/BehaviorControls/Help"] +margin_right = 178.0 +margin_bottom = 26.0 text = "Controls" -[node name="GridContainer" type="GridContainer" parent="BehaviorControls/Help"] -margin_top = 18.0 -margin_right = 76.0 -margin_bottom = 52.0 +[node name="GridContainer" type="GridContainer" parent="MarginContainer/BehaviorControls/Help"] +margin_left = 57.0 +margin_top = 34.0 +margin_right = 120.0 +margin_bottom = 90.0 +size_flags_horizontal = 4 columns = 3 -[node name="Sep" type="Control" parent="BehaviorControls/Help/GridContainer"] +[node name="Sep" type="Control" parent="MarginContainer/BehaviorControls/Help/GridContainer"] margin_right = 15.0 -margin_bottom = 15.0 +margin_bottom = 26.0 rect_min_size = Vector2( 15, 15 ) -[node name="W" type="Label" parent="BehaviorControls/Help/GridContainer"] +[node name="W" type="Label" parent="MarginContainer/BehaviorControls/Help/GridContainer"] margin_left = 19.0 -margin_right = 34.0 -margin_bottom = 15.0 +margin_right = 42.0 +margin_bottom = 26.0 rect_min_size = Vector2( 15, 15 ) text = "W" align = 1 -[node name="Sep2" type="Control" parent="BehaviorControls/Help/GridContainer"] -margin_left = 38.0 -margin_right = 53.0 -margin_bottom = 15.0 +[node name="Sep2" type="Control" parent="MarginContainer/BehaviorControls/Help/GridContainer"] +margin_left = 46.0 +margin_right = 63.0 +margin_bottom = 26.0 rect_min_size = Vector2( 15, 15 ) -[node name="A" type="Label" parent="BehaviorControls/Help/GridContainer"] -margin_top = 19.0 +[node name="A" type="Label" parent="MarginContainer/BehaviorControls/Help/GridContainer"] +margin_top = 30.0 margin_right = 15.0 -margin_bottom = 34.0 +margin_bottom = 56.0 rect_min_size = Vector2( 15, 15 ) text = "A" align = 1 -[node name="S" type="Label" parent="BehaviorControls/Help/GridContainer"] +[node name="S" type="Label" parent="MarginContainer/BehaviorControls/Help/GridContainer"] margin_left = 19.0 -margin_top = 19.0 -margin_right = 34.0 -margin_bottom = 34.0 +margin_top = 30.0 +margin_right = 42.0 +margin_bottom = 56.0 rect_min_size = Vector2( 15, 15 ) text = "S" align = 1 -[node name="D" type="Label" parent="BehaviorControls/Help/GridContainer"] -margin_left = 38.0 -margin_top = 19.0 -margin_right = 53.0 -margin_bottom = 34.0 +[node name="D" type="Label" parent="MarginContainer/BehaviorControls/Help/GridContainer"] +margin_left = 46.0 +margin_top = 30.0 +margin_right = 63.0 +margin_bottom = 56.0 rect_min_size = Vector2( 15, 15 ) text = "D" align = 1 diff --git a/project/demos/seek_and_flee/SeekFleeDemo.gd b/project/demos/seek_and_flee/SeekFleeDemo.gd index bf3bbc2..6ae0274 100644 --- a/project/demos/seek_and_flee/SeekFleeDemo.gd +++ b/project/demos/seek_and_flee/SeekFleeDemo.gd @@ -23,6 +23,9 @@ func _ready() -> void: var rng: = RandomNumberGenerator.new() rng.randomize() + gui.max_acc.value = spawner.max_accel + gui.max_speed.value = spawner.max_speed + for i in range(spawner.entity_count): var new_pos: = Vector2( rng.randf_range(-camera_boundaries.size.x/2, camera_boundaries.size.x/2), @@ -31,7 +34,10 @@ func _ready() -> void: var entity: KinematicBody2D = spawner.Entity.instance() entity.global_position = new_pos entity.player_agent = player.agent - entity.speed = rng.randf_range(spawner.min_speed, spawner.max_speed) + entity.start_speed = spawner.max_speed + entity.start_accel = spawner.max_accel entity.color = spawner.entity_color gui.connect("mode_changed", entity, "_on_GUI_mode_changed") + gui.connect("acc_changed", entity, "_on_GUI_acc_changed") + gui.connect("speed_changed", entity, "_on_GUI_speed_changed") spawner.add_child(entity) diff --git a/project/demos/seek_and_flee/SeekFleeDemo.tscn b/project/demos/seek_and_flee/SeekFleeDemo.tscn index cb19392..25c2750 100644 --- a/project/demos/seek_and_flee/SeekFleeDemo.tscn +++ b/project/demos/seek_and_flee/SeekFleeDemo.tscn @@ -71,9 +71,11 @@ shape = SubResource( 3 ) [node name="Spawner" type="Node2D" parent="."] script = ExtResource( 4 ) Entity = ExtResource( 6 ) +max_speed = 150.0 [node name="GUI" parent="." instance=ExtResource( 5 )] margin_left = -512.0 margin_top = -300.0 -margin_right = -414.0 -margin_bottom = -152.0 +margin_right = -386.0 +margin_bottom = -102.0 +rect_min_size = Vector2( 0, 600 ) diff --git a/project/demos/seek_and_flee/Seeker.gd b/project/demos/seek_and_flee/Seeker.gd index 58473fd..32022db 100644 --- a/project/demos/seek_and_flee/Seeker.gd +++ b/project/demos/seek_and_flee/Seeker.gd @@ -12,14 +12,15 @@ onready var _active_behavior: = seek var player_agent: GSTAgentLocation var velocity: = Vector2.ZERO -var speed: float +var start_speed: float +var start_accel: float var color: Color var radius: = 0.0 func _ready() -> void: - agent.max_linear_acceleration = speed/10 - agent.max_linear_speed = speed + agent.max_linear_acceleration = start_accel + agent.max_linear_speed = start_speed radius = collision_shape.shape.radius @@ -36,12 +37,13 @@ func _physics_process(delta: float) -> void: velocity = (velocity + Vector2(accel.linear.x, accel.linear.y)).clamped(agent.max_linear_speed) velocity = move_and_slide(velocity) - if velocity.length_squared() > 0: - update() func _update_agent() -> void: - agent.position = Vector3(global_position.x, global_position.y, 0) + agent.position.x = global_position.x + agent.position.y = global_position.y + agent.linear_velocity.x = velocity.x + agent.linear_velocity.y = velocity.y func _on_GUI_mode_changed(mode: int) -> void: @@ -49,3 +51,11 @@ func _on_GUI_mode_changed(mode: int) -> void: _active_behavior = seek else: _active_behavior = flee + + +func _on_GUI_acc_changed(value: float) -> void: + agent.max_linear_acceleration = value + + +func _on_GUI_speed_changed(value: float) -> void: + agent.max_linear_speed = value diff --git a/project/demos/seek_and_flee/Seeker.tscn b/project/demos/seek_and_flee/Seeker.tscn index 804897a..1d154bb 100644 --- a/project/demos/seek_and_flee/Seeker.tscn +++ b/project/demos/seek_and_flee/Seeker.tscn @@ -2,13 +2,11 @@ [ext_resource path="res://demos/seek_and_flee/Seeker.gd" type="Script" id=1] - - [sub_resource type="CircleShape2D" id=1] [node name="Seeker" type="KinematicBody2D"] collision_layer = 4 -collision_mask = 6 +collision_mask = 2 script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] diff --git a/project/demos/seek_and_flee/Spawner.gd b/project/demos/seek_and_flee/Spawner.gd index 9d6cbc2..87555d7 100644 --- a/project/demos/seek_and_flee/Spawner.gd +++ b/project/demos/seek_and_flee/Spawner.gd @@ -5,5 +5,5 @@ extends Node2D export(PackedScene) var Entity: PackedScene export var entity_count: = 10 export var entity_color: = Color.blue -export var min_speed: = 50.0 -export var max_speed: = 125.0 +export var max_speed: = 100.0 +export var max_accel: = 20.0 From 0e95c24c7f17449ed5fe654cc56f142fface98ca Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Mon, 13 Jan 2020 16:15:44 -0500 Subject: [PATCH 23/23] Add GDQuest theme to improved Pursue demo Changed text boxes to sliders to improve usability. This also involved adding some simple graphics, since the _draw method is not anti-aliased and doesn't look great. --- project/assets/sprites/large_circle.png | Bin 0 -> 2345 bytes .../assets/sprites/large_circle.png.import | 34 ++++ project/assets/sprites/small_circle.png | Bin 0 -> 1918 bytes .../assets/sprites/small_circle.png.import | 34 ++++ project/assets/sprites/triangle.png | Bin 0 -> 2752 bytes project/assets/sprites/triangle.png.import | 34 ++++ .../demos/pursue_vs_seek/BoundaryManager.gd | 5 +- project/demos/pursue_vs_seek/GUI.gd | 38 ++-- project/demos/pursue_vs_seek/GUI.tscn | 181 +++++++++--------- project/demos/pursue_vs_seek/Player.gd | 8 +- .../demos/pursue_vs_seek/PursueVSSeekDemo.gd | 15 +- .../pursue_vs_seek/PursueVSSeekDemo.tscn | 32 ++-- project/demos/pursue_vs_seek/Ship.gd | 28 +-- project/demos/seek_and_flee/GUI.gd | 16 +- project/demos/seek_and_flee/GUI.tscn | 5 +- project/demos/seek_and_flee/Player.gd | 11 -- project/demos/seek_and_flee/SeekFleeDemo.gd | 5 +- project/demos/seek_and_flee/SeekFleeDemo.tscn | 15 +- project/demos/seek_and_flee/Seeker.gd | 11 +- project/demos/seek_and_flee/Seeker.tscn | 8 +- 20 files changed, 298 insertions(+), 182 deletions(-) create mode 100644 project/assets/sprites/large_circle.png create mode 100644 project/assets/sprites/large_circle.png.import create mode 100644 project/assets/sprites/small_circle.png create mode 100644 project/assets/sprites/small_circle.png.import create mode 100644 project/assets/sprites/triangle.png create mode 100644 project/assets/sprites/triangle.png.import diff --git a/project/assets/sprites/large_circle.png b/project/assets/sprites/large_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..e69cc1136fbcf0d2212cc72a7c558f88d58869d0 GIT binary patch literal 2345 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 Ri`~{2GEiIZo7lFy|8LTpfx-X) literal 0 HcmV?d00001 diff --git a/project/assets/sprites/small_circle.png.import b/project/assets/sprites/small_circle.png.import new file mode 100644 index 0000000..560c875 --- /dev/null +++ b/project/assets/sprites/small_circle.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/small_circle.png-e9ef462acf0465fde3767e7b0877ff44.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/sprites/small_circle.png" +dest_files=[ "res://.import/small_circle.png-e9ef462acf0465fde3767e7b0877ff44.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/project/assets/sprites/triangle.png b/project/assets/sprites/triangle.png new file mode 100644 index 0000000000000000000000000000000000000000..5d8b0262cfc7bf42ed1968428fc5c3000aafd7a1 GIT binary patch literal 2752 zcmcImdsGuw9=<_DAXN1C;z}8USNY zYvYqFN%94llG1Z=f>My&Y`u|20}wJN+lVXENeiSP)mnp;-S@XfHl!t_>_nj)ksBjO zjW#ORL@v%<7_ZDtS4s%>oY_!FHbxWZNed2T>vaY*mMvuu@?!Mdxec?SL5L+?$_{fH zgp%a3Py}TnAt6`9QKAAKB$jYd5hCFUf*>A(ieW?yqkIm6Vu%RiOQ7M4OaosG%&BSwsDX zAEU2Fy)j}DCK9($rg)0djU*~|gawL-fC3Y>27<~m&vfb;hLbYfLQ2^@gon`C;-LI^ zREVJnCZLli#1Lc%DyOS}z%BUOfhj_(%6S{8T#iK>%og0BB%@_gHZ6*))e;yFCq<}| z6mZ1BA|(eE2uO~E7cA!R2n9h1c!&_id4sy>^D;`A;S8Sh{7}&nl#=EcjSr^ai$y4+ zkZ@2j9?an>XwMWPg5Zcqi9{*H=|K=9Y%wM+{oUZYU$Qz?5j0~kU%(?IDw2Z`!6XMq z1;HGJ7$rEQP(&akpN|T~DmFwYF%@Of<8+m1^|+dZjRrLv`dLi`rK3!8ilAf8ch)k^ zPJ0ohHPea98U8vJldFbjIxRFh1pwE5(Xz03&5e$dWX+T??}CO~V;3!I zVg=@xd$IHLykQYscFTn;tpMEYU(oA zn>%&A66A-g@mxdd&BG0i^xdrI#2^|kP-nFH>ipBot9@W3iAUc6WUuAXf^y-Hg%+jL?n3GvLJhZ4tr#$6P~MD&G{2n}gZW z)YDVGWXTehhgGEc1g!A(OZ)wMXOekGM7vybU8XV_tT~lH)nc|pkHp!UXUj37;Yp#I{ zYgbo9f0~+$vJRC7Qz7|?HSh`t$e)b90lg+%ko&d*UVb|5G+bhkDT|x%x?%*E> z$6DL&_w;N(mXq@Nspiw~ior_Fp6>4Mdd5T>ov-}^f z4qvRHII3wCXd=F9^PK_SZ~qd9CK~+#y7~O{vDsT-huc!OX4i)g9@H#vxqkinp+kRU zHL2zov7Rv8TeX!35Ap@p`2v2SFaAOIv}f~l_SCdG5IE3~V4L9Ob#(o~ii#7q)>zGk z*~^3OKo7t7+X_{J=dDe8y?&|3-nPKR*~h*6cf((-^ItH~aG7!9lQ9X2iLVnsUNC*K zD&TSPS+sPoX{UbO%0DkFl)Yn5Nv;CSwI?gW(v~#ZnznA98GE3xIEHyRucch7_?>;V z`oj3;#CzvOj_8to2M)}9gydX7u3g$H4UcKLulF>eXA|1Fj%EFIpVubGKU?U3m!VYbN#7wk{l(TGY1%t$cFwh)dvK-K`a2ORL6~`+KU&YVMyZ zZyFCN+9!EEO-^}vdXbMQ1by75aYbS@h4-ujPi7hNax_oQ+@9L+&lY~vpknx|{pL*U zjt{*Z&ng>tzc+Xs5?b{KpC@^ndW&w}3aRB!+XrT?Sv|AwP-l)KxC6T<-@GER0&Kg} yjr|aIJAVJZD;GX?a7q(qBh~32g{Z;HL!VJ+3!-9cik~_EF{2|F%BsTC^8W)CH42FU literal 0 HcmV?d00001 diff --git a/project/assets/sprites/triangle.png.import b/project/assets/sprites/triangle.png.import new file mode 100644 index 0000000..e63a133 --- /dev/null +++ b/project/assets/sprites/triangle.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/triangle.png-fa05d9e46946b626c9973edf66af1138.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/sprites/triangle.png" +dest_files=[ "res://.import/triangle.png-fa05d9e46946b626c9973edf66af1138.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/project/demos/pursue_vs_seek/BoundaryManager.gd b/project/demos/pursue_vs_seek/BoundaryManager.gd index 8cb79f4..a73b32f 100644 --- a/project/demos/pursue_vs_seek/BoundaryManager.gd +++ b/project/demos/pursue_vs_seek/BoundaryManager.gd @@ -20,15 +20,16 @@ func _ready() -> void: var world_pos: = ship.position for i in range(3): - var ship_clone: = ShipType.new($Player/CollisionPolygon2D.polygon) + var ship_clone: = ShipType.new() ship_clone.position.x = world_pos.x if i == 1 else (world_pos.x - _world_bounds.x) ship_clone.position.y = world_pos.y if i == 0 else (world_pos.y - _world_bounds.y) ship_clone.rotation = ship.rotation - ship_clone.color = ship.color ship_clone.tag = i + ship_clone.name = ship.name + "Clone" add_child(ship_clone) + ship_clone.generate_sprite(ship.get_node("Sprite")) _clones[ship_clone] = ship diff --git a/project/demos/pursue_vs_seek/GUI.gd b/project/demos/pursue_vs_seek/GUI.gd index 77c06e3..467c9e2 100644 --- a/project/demos/pursue_vs_seek/GUI.gd +++ b/project/demos/pursue_vs_seek/GUI.gd @@ -1,30 +1,38 @@ -extends MarginContainer +extends PanelContainer signal linear_speed_changed(value) signal linear_accel_changed(value) +signal angular_speed_changed(value) +signal angular_accel_changed(value) +signal decel_radius_changed(value) +signal predict_time_changed(value) -onready var linear_speed: = $Controls/LinSpeed/LineEdit -onready var linear_accel: = $Controls/LinAccel/LineEdit +onready var linear_speed: = $GUI/Controls/LinSpeedBox/MaxLinSpeed +onready var lin_speed_label: = $GUI/Controls/LinSpeedBox/Label +onready var linear_accel: = $GUI/Controls/LinAccelBox/MaxLinAccel +onready var lin_accel_label: = $GUI/Controls/LinAccelBox/Label +onready var predict_time: = $GUI/Controls/PredictTime/PredictTime +onready var predict_time_label: = $GUI/Controls/PredictTime/Label func _ready() -> void: - linear_speed.connect("text_changed", self, "_on_LineText_linear_speed_changed") - linear_accel.connect("text_changed", self, "_on_LineText_linear_accel_changed") + linear_speed.connect("value_changed", self, "_on_Slider_linear_speed_changed") + linear_accel.connect("value_changed", self, "_on_Slider_linear_accel_changed") + predict_time.connect("value_changed", self, "_on_Slider_predict_time_changed") -func _unhandled_input(event: InputEvent) -> void: - if event is InputEventMouseButton: - linear_speed.release_focus() - linear_accel.release_focus() +func _on_Slider_linear_speed_changed(value: float) -> void: + lin_speed_label.text = "Max linear speed (" + str(value) + ")" + emit_signal("linear_speed_changed", value) -func _on_LineText_linear_speed_changed(new_text: String) -> void: - if new_text.is_valid_integer(): - emit_signal("linear_speed_changed", int(float(new_text))) +func _on_Slider_linear_accel_changed(value: float) -> void: + lin_accel_label.text = "Max linear accel (" + str(value) + ")" + emit_signal("linear_accel_changed", value) -func _on_LineText_linear_accel_changed(new_text: String) -> void: - if new_text.is_valid_integer(): - emit_signal("linear_accel_changed", int(float(new_text))) +func _on_Slider_predict_time_changed(value: float) -> void: + predict_time_label.text = "Predict time (" + str(value) + " sec)" + emit_signal("predict_time_changed", value) diff --git a/project/demos/pursue_vs_seek/GUI.tscn b/project/demos/pursue_vs_seek/GUI.tscn index f339484..4eda7ac 100644 --- a/project/demos/pursue_vs_seek/GUI.tscn +++ b/project/demos/pursue_vs_seek/GUI.tscn @@ -1,132 +1,139 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=3 format=2] [ext_resource path="res://demos/pursue_vs_seek/GUI.gd" type="Script" id=1] +[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=2] -[node name="GUI" type="MarginContainer"] +[node name="PanelContainer" type="PanelContainer"] anchor_bottom = 1.0 -custom_constants/margin_right = 20 -custom_constants/margin_top = 20 -custom_constants/margin_left = 20 -custom_constants/margin_bottom = 20 +margin_right = 364.0 +theme = ExtResource( 2 ) script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } -[node name="Controls" type="VBoxContainer" parent="."] +[node name="GUI" type="MarginContainer" parent="."] +margin_right = 364.0 +margin_bottom = 600.0 +custom_constants/margin_right = 20 +custom_constants/margin_top = 20 +custom_constants/margin_left = 20 +custom_constants/margin_bottom = 20 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Controls" type="VBoxContainer" parent="GUI"] margin_left = 20.0 margin_top = 20.0 -margin_right = 241.0 +margin_right = 344.0 margin_bottom = 580.0 -[node name="LinSpeed" type="HBoxContainer" parent="Controls"] -margin_right = 221.0 -margin_bottom = 25.0 -custom_constants/separation = 10 +[node name="LinSpeedBox" type="VBoxContainer" parent="GUI/Controls"] +margin_right = 324.0 +margin_bottom = 50.0 -[node name="Label" type="Label" parent="Controls/LinSpeed"] -margin_right = 153.0 -margin_bottom = 25.0 -rect_min_size = Vector2( 153, 25 ) -text = "Max Linear Speed" -valign = 1 +[node name="Label" type="Label" parent="GUI/Controls/LinSpeedBox"] +margin_right = 324.0 +margin_bottom = 26.0 +text = "Max linear speed (2000)" -[node name="LineEdit" type="LineEdit" parent="Controls/LinSpeed"] -margin_left = 163.0 -margin_right = 221.0 -margin_bottom = 25.0 -rect_min_size = Vector2( 0, 25 ) -focus_mode = 1 -text = "200" -context_menu_enabled = false -shortcut_keys_enabled = false -__meta__ = { -"_edit_use_anchors_": false -} +[node name="MaxLinSpeed" type="HSlider" parent="GUI/Controls/LinSpeedBox"] +margin_top = 34.0 +margin_right = 324.0 +margin_bottom = 50.0 +max_value = 500.0 -[node name="LinAccel" type="HBoxContainer" parent="Controls"] -margin_top = 29.0 -margin_right = 221.0 -margin_bottom = 54.0 -custom_constants/separation = 10 - -[node name="Label" type="Label" parent="Controls/LinAccel"] -margin_right = 153.0 -margin_bottom = 25.0 -rect_min_size = Vector2( 153, 25 ) -text = "Max Linear Acceleration" -valign = 1 - -[node name="LineEdit" type="LineEdit" parent="Controls/LinAccel"] -margin_left = 163.0 -margin_right = 221.0 -margin_bottom = 25.0 -rect_min_size = Vector2( 0, 25 ) -focus_mode = 1 -text = "120" -context_menu_enabled = false -shortcut_keys_enabled = false -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Help" type="VBoxContainer" parent="Controls"] +[node name="LinAccelBox" type="VBoxContainer" parent="GUI/Controls"] margin_top = 58.0 -margin_right = 221.0 -margin_bottom = 110.0 +margin_right = 324.0 +margin_bottom = 108.0 -[node name="Controls" type="Label" parent="Controls/Help"] -margin_right = 221.0 -margin_bottom = 14.0 +[node name="Label" type="Label" parent="GUI/Controls/LinAccelBox"] +margin_right = 324.0 +margin_bottom = 26.0 +text = "Max linear accel (2000)" + +[node name="MaxLinAccel" type="HSlider" parent="GUI/Controls/LinAccelBox"] +margin_top = 34.0 +margin_right = 324.0 +margin_bottom = 50.0 +step = 0.5 + +[node name="PredictTime" type="VBoxContainer" parent="GUI/Controls"] +margin_top = 116.0 +margin_right = 324.0 +margin_bottom = 166.0 + +[node name="Label" type="Label" parent="GUI/Controls/PredictTime"] +margin_right = 324.0 +margin_bottom = 26.0 +text = "Predict time (2000)" + +[node name="PredictTime" type="HSlider" parent="GUI/Controls/PredictTime"] +margin_top = 34.0 +margin_right = 324.0 +margin_bottom = 50.0 +max_value = 5.0 +step = 0.1 + +[node name="Help" type="VBoxContainer" parent="GUI/Controls"] +margin_top = 174.0 +margin_right = 324.0 +margin_bottom = 264.0 + +[node name="Controls" type="Label" parent="GUI/Controls/Help"] +margin_right = 324.0 +margin_bottom = 26.0 text = "Controls" -[node name="GridContainer" type="GridContainer" parent="Controls/Help"] -margin_top = 18.0 -margin_right = 221.0 -margin_bottom = 52.0 +[node name="GridContainer" type="GridContainer" parent="GUI/Controls/Help"] +margin_top = 34.0 +margin_right = 324.0 +margin_bottom = 90.0 columns = 3 -[node name="Sep" type="Control" parent="Controls/Help/GridContainer"] +[node name="Sep" type="Control" parent="GUI/Controls/Help/GridContainer"] margin_right = 15.0 -margin_bottom = 15.0 +margin_bottom = 26.0 rect_min_size = Vector2( 15, 15 ) -[node name="W" type="Label" parent="Controls/Help/GridContainer"] +[node name="W" type="Label" parent="GUI/Controls/Help/GridContainer"] margin_left = 19.0 -margin_right = 34.0 -margin_bottom = 15.0 +margin_right = 42.0 +margin_bottom = 26.0 rect_min_size = Vector2( 15, 15 ) text = "W" align = 1 -[node name="Sep2" type="Control" parent="Controls/Help/GridContainer"] -margin_left = 38.0 -margin_right = 53.0 -margin_bottom = 15.0 +[node name="Sep2" type="Control" parent="GUI/Controls/Help/GridContainer"] +margin_left = 46.0 +margin_right = 63.0 +margin_bottom = 26.0 rect_min_size = Vector2( 15, 15 ) -[node name="A" type="Label" parent="Controls/Help/GridContainer"] -margin_top = 19.0 +[node name="A" type="Label" parent="GUI/Controls/Help/GridContainer"] +margin_top = 30.0 margin_right = 15.0 -margin_bottom = 34.0 +margin_bottom = 56.0 rect_min_size = Vector2( 15, 15 ) text = "A" align = 1 -[node name="S" type="Label" parent="Controls/Help/GridContainer"] +[node name="S" type="Label" parent="GUI/Controls/Help/GridContainer"] margin_left = 19.0 -margin_top = 19.0 -margin_right = 34.0 -margin_bottom = 34.0 +margin_top = 30.0 +margin_right = 42.0 +margin_bottom = 56.0 rect_min_size = Vector2( 15, 15 ) text = "S" align = 1 -[node name="D" type="Label" parent="Controls/Help/GridContainer"] -margin_left = 38.0 -margin_top = 19.0 -margin_right = 53.0 -margin_bottom = 34.0 +[node name="D" type="Label" parent="GUI/Controls/Help/GridContainer"] +margin_left = 46.0 +margin_top = 30.0 +margin_right = 63.0 +margin_bottom = 56.0 rect_min_size = Vector2( 15, 15 ) text = "D" align = 1 diff --git a/project/demos/pursue_vs_seek/Player.gd b/project/demos/pursue_vs_seek/Player.gd index b0b7762..29df3ed 100644 --- a/project/demos/pursue_vs_seek/Player.gd +++ b/project/demos/pursue_vs_seek/Player.gd @@ -40,7 +40,6 @@ func _physics_process(delta: float) -> void: _linear_velocity = move_and_slide(_linear_velocity) _update_agent(_linear_velocity, rotation) - update() func _calculate_angular_velocity( @@ -94,6 +93,9 @@ func _get_movement() -> Vector2: func _update_agent(velocity: Vector2, orientation: float) -> void: - agent.position = Vector3(global_position.x, global_position.y, 0) - agent.linear_velocity = Vector3(velocity.x, velocity.y, 0) + agent.position.x = global_position.x + agent.position.y = global_position.y + agent.linear_velocity.x = velocity.x + agent.linear_velocity.y = velocity.y + agent.angular_velocity = _angular_velocity agent.orientation = orientation diff --git a/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd b/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd index 5f1dbb1..e65d583 100644 --- a/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd +++ b/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd @@ -5,12 +5,19 @@ onready var gui: = $GUI onready var pursuer: = $BoundaryManager/Pursuer onready var seeker: = $BoundaryManager/Seeker +export var start_linear_speed: = 200.0 +export var start_linear_accel: = 25.0 +export var start_predict_time: = 0.3 + func _ready() -> void: - gui.linear_speed.text = str(pursuer.agent.max_linear_speed) - gui.linear_accel.text = str(pursuer.agent.max_linear_acceleration) gui.connect("linear_accel_changed", self, "_on_GUI_linear_accel_changed") gui.connect("linear_speed_changed", self, "_on_GUI_linear_speed_changed") + gui.connect("predict_time_changed", self, "_on_GUI_predict_time_changed") + yield(get_tree(), "idle_frame") + gui.linear_speed.value = start_linear_speed + gui.linear_accel.value = start_linear_accel + gui.predict_time.value = start_predict_time func _on_GUI_linear_accel_changed(value: int) -> void: @@ -21,3 +28,7 @@ func _on_GUI_linear_accel_changed(value: int) -> void: func _on_GUI_linear_speed_changed(value: int) -> void: pursuer.agent.max_linear_speed = float(value) seeker.agent.max_linear_speed = float(value) + + +func _on_GUI_predict_time_changed(value: int) -> void: + pursuer._behavior.max_predict_time = float(value) diff --git a/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn b/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn index 2691452..d9d2437 100644 --- a/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn +++ b/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn @@ -1,16 +1,20 @@ -[gd_scene load_steps=6 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://demos/pursue_vs_seek/Pursuer.gd" type="Script" id=1] [ext_resource path="res://demos/pursue_vs_seek/Player.gd" type="Script" id=2] [ext_resource path="res://demos/pursue_vs_seek/BoundaryManager.gd" type="Script" id=3] [ext_resource path="res://demos/pursue_vs_seek/PursueVSSeekDemo.gd" type="Script" id=4] [ext_resource path="res://demos/pursue_vs_seek/GUI.tscn" type="PackedScene" id=5] +[ext_resource path="res://assets/sprites/triangle.png" type="Texture" id=6] [node name="PursueVSSeekDemo" type="Node2D"] script = ExtResource( 4 ) __meta__ = { "_editor_description_": "Toy demo to demonstrate the use of the Pursue contrasted to the more naive Seek steering behavior." } +start_linear_speed = 150.0 +start_linear_accel = 75.0 +start_predict_time = 2.0 [node name="BoundaryManager" type="Node2D" parent="."] script = ExtResource( 3 ) @@ -20,32 +24,38 @@ position = Vector2( 49.2031, 556.936 ) rotation = 1.5708 collision_mask = 2 script = ExtResource( 2 ) -color = Color( 1, 0, 0, 1 ) [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Player"] -polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) +polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 ) + +[node name="Sprite" type="Sprite" parent="BoundaryManager/Player"] +modulate = Color( 0.968627, 0.188235, 0.0352941, 1 ) +texture = ExtResource( 6 ) [node name="Pursuer" type="KinematicBody2D" parent="BoundaryManager"] position = Vector2( 868.495, 87.9043 ) collision_layer = 2 script = ExtResource( 1 ) -color = Color( 0.811765, 0.909804, 0.113725, 1 ) [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Pursuer"] -modulate = Color( 0.694118, 0.694118, 0.694118, 1 ) -polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) +polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 ) + +[node name="Sprite" type="Sprite" parent="BoundaryManager/Pursuer"] +modulate = Color( 0.756863, 0.952941, 0.054902, 1 ) +texture = ExtResource( 6 ) [node name="Seeker" type="KinematicBody2D" parent="BoundaryManager"] position = Vector2( 821.24, 87.9043 ) collision_layer = 2 script = ExtResource( 1 ) -color = Color( 0.113725, 0.909804, 0.219608, 1 ) use_seek = true [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Seeker"] -modulate = Color( 0.317647, 0.317647, 0.317647, 1 ) -polygon = PoolVector2Array( 0, -30, -25, 25, 25, 25 ) +polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 ) + +[node name="Sprite" type="Sprite" parent="BoundaryManager/Seeker"] +modulate = Color( 0.278431, 0.815686, 0.14902, 1 ) +texture = ExtResource( 6 ) [node name="GUI" parent="." instance=ExtResource( 5 )] -margin_right = 261.0 -margin_bottom = 150.0 +margin_right = 309.0 diff --git a/project/demos/pursue_vs_seek/Ship.gd b/project/demos/pursue_vs_seek/Ship.gd index 7d9d770..194c329 100644 --- a/project/demos/pursue_vs_seek/Ship.gd +++ b/project/demos/pursue_vs_seek/Ship.gd @@ -1,27 +1,13 @@ extends KinematicBody2D -# Draws a notched triangle based on the vertices of the ship's polygon collider. +# Represents a basic ship -export var color: = Color() - var tag: int = 0 -var _vertices: PoolVector2Array -var _colors: PoolColorArray - -func _init(verts: = PoolVector2Array()) -> void: - _vertices = verts - - -func _ready() -> void: - if not _vertices: - _vertices = $CollisionPolygon2D.polygon - var centroid: = (_vertices[0] + _vertices[1] + _vertices[2])/3 - _vertices.insert(2, centroid) - for i in range(_vertices.size()): - _colors.append(color) - - -func _draw() -> void: - draw_polygon(_vertices, _colors) +func generate_sprite(sprite: Sprite) -> void: + var new_sprite = Sprite.new() + new_sprite.texture = sprite.texture + new_sprite.modulate = sprite.modulate + new_sprite.name = "Sprite" + add_child(new_sprite) diff --git a/project/demos/seek_and_flee/GUI.gd b/project/demos/seek_and_flee/GUI.gd index e6826ee..c3750c8 100644 --- a/project/demos/seek_and_flee/GUI.gd +++ b/project/demos/seek_and_flee/GUI.gd @@ -4,23 +4,23 @@ extends PanelContainer enum BehaviorMode { SEEK, FLEE } signal mode_changed(behavior_mode) -signal acc_changed(value) +signal accel_changed(value) signal speed_changed(value) onready var seek: = $MarginContainer/BehaviorControls/Seek onready var flee: = $MarginContainer/BehaviorControls/Flee -onready var max_acc: = $MarginContainer/BehaviorControls/MaxAccValue +onready var max_accel: = $MarginContainer/BehaviorControls/MaxAccelValue onready var max_speed: = $MarginContainer/BehaviorControls/MaxSpeedValue -onready var max_acc_label: = $MarginContainer/BehaviorControls/MaxAcc +onready var max_accel_label: = $MarginContainer/BehaviorControls/MaxAccel onready var max_speed_label: = $MarginContainer/BehaviorControls/MaxSpeed func _ready() -> void: seek.connect("pressed", self, "_on_Seek_pressed") flee.connect("pressed", self, "_on_Flee_pressed") - max_acc.connect("value_changed", self, "_on_Acc_changed") + max_accel.connect("value_changed", self, "_on_Accel_changed") max_speed.connect("value_changed", self, "_on_Speed_changed") - max_acc_label.text = "Max accel (" + str(max_acc.value) + ")" + max_accel_label.text = "Max accel (" + str(max_accel.value) + ")" max_speed_label.text = "Max speed (" + str(max_speed.value) + ")" @@ -38,9 +38,9 @@ func _on_Flee_pressed() -> void: emit_signal("mode_changed", BehaviorMode.FLEE) -func _on_Acc_changed(value: float) -> void: - max_acc_label.text = "Max accel (" + str(value) + ")" - emit_signal("acc_changed", value) +func _on_Accel_changed(value: float) -> void: + max_accel_label.text = "Max accel (" + str(value) + ")" + emit_signal("accel_changed", value) func _on_Speed_changed(value: float) -> void: diff --git a/project/demos/seek_and_flee/GUI.tscn b/project/demos/seek_and_flee/GUI.tscn index c3d7918..a63d376 100644 --- a/project/demos/seek_and_flee/GUI.tscn +++ b/project/demos/seek_and_flee/GUI.tscn @@ -45,7 +45,7 @@ focus_mode = 0 enabled_focus_mode = 0 text = "Flee" -[node name="MaxAcc" type="Label" parent="MarginContainer/BehaviorControls"] +[node name="MaxAccel" type="Label" parent="MarginContainer/BehaviorControls"] margin_top = 68.0 margin_right = 178.0 margin_bottom = 94.0 @@ -54,7 +54,7 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="MaxAccValue" type="HSlider" parent="MarginContainer/BehaviorControls"] +[node name="MaxAccelValue" type="HSlider" parent="MarginContainer/BehaviorControls"] margin_top = 102.0 margin_right = 178.0 margin_bottom = 118.0 @@ -76,7 +76,6 @@ margin_top = 160.0 margin_right = 178.0 margin_bottom = 176.0 max_value = 450.0 -step = 1.0 value = 100.0 [node name="Help" type="VBoxContainer" parent="MarginContainer/BehaviorControls"] diff --git a/project/demos/seek_and_flee/Player.gd b/project/demos/seek_and_flee/Player.gd index 037b73d..485b88e 100644 --- a/project/demos/seek_and_flee/Player.gd +++ b/project/demos/seek_and_flee/Player.gd @@ -2,21 +2,10 @@ extends KinematicBody2D # Class to control the player in basic left/right up/down movement. -onready var collision_shape: = $CollisionShape2D onready var agent: = GSTAgentLocation.new() export var speed: = 150.0 -var _radius: = 0.0 - - -func _ready() -> void: - _radius = collision_shape.shape.radius - - -func _draw() -> void: - draw_circle(Vector2.ZERO, _radius, Color.red) - func _get_movement() -> Vector2: return Vector2( Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"), diff --git a/project/demos/seek_and_flee/SeekFleeDemo.gd b/project/demos/seek_and_flee/SeekFleeDemo.gd index 6ae0274..9fcd168 100644 --- a/project/demos/seek_and_flee/SeekFleeDemo.gd +++ b/project/demos/seek_and_flee/SeekFleeDemo.gd @@ -23,7 +23,7 @@ func _ready() -> void: var rng: = RandomNumberGenerator.new() rng.randomize() - gui.max_acc.value = spawner.max_accel + gui.max_accel.value = spawner.max_accel gui.max_speed.value = spawner.max_speed for i in range(spawner.entity_count): @@ -36,8 +36,7 @@ func _ready() -> void: entity.player_agent = player.agent entity.start_speed = spawner.max_speed entity.start_accel = spawner.max_accel - entity.color = spawner.entity_color gui.connect("mode_changed", entity, "_on_GUI_mode_changed") - gui.connect("acc_changed", entity, "_on_GUI_acc_changed") + gui.connect("accel_changed", entity, "_on_GUI_accel_changed") gui.connect("speed_changed", entity, "_on_GUI_speed_changed") spawner.add_child(entity) diff --git a/project/demos/seek_and_flee/SeekFleeDemo.tscn b/project/demos/seek_and_flee/SeekFleeDemo.tscn index 25c2750..02a7a48 100644 --- a/project/demos/seek_and_flee/SeekFleeDemo.tscn +++ b/project/demos/seek_and_flee/SeekFleeDemo.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=2] +[gd_scene load_steps=11 format=2] [ext_resource path="res://demos/seek_and_flee/Boundary.gd" type="Script" id=1] [ext_resource path="res://demos/seek_and_flee/Player.gd" type="Script" id=2] @@ -6,9 +6,10 @@ [ext_resource path="res://demos/seek_and_flee/Spawner.gd" type="Script" id=4] [ext_resource path="res://demos/seek_and_flee/GUI.tscn" type="PackedScene" id=5] [ext_resource path="res://demos/seek_and_flee/Seeker.tscn" type="PackedScene" id=6] +[ext_resource path="res://assets/sprites/large_circle.png" type="Texture" id=7] [sub_resource type="CircleShape2D" id=1] -radius = 30.0 +radius = 32.0 [sub_resource type="RectangleShape2D" id=2] extents = Vector2( 10, 300 ) @@ -32,6 +33,10 @@ script = ExtResource( 2 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] shape = SubResource( 1 ) +[node name="Sprite" type="Sprite" parent="Player"] +modulate = Color( 0.952941, 0.290196, 0.0588235, 1 ) +texture = ExtResource( 7 ) + [node name="LeftBoundary" type="StaticBody2D" parent="."] position = Vector2( -512, 0 ) collision_layer = 2 @@ -74,8 +79,8 @@ Entity = ExtResource( 6 ) max_speed = 150.0 [node name="GUI" parent="." instance=ExtResource( 5 )] +anchor_bottom = 0.0 margin_left = -512.0 margin_top = -300.0 -margin_right = -386.0 -margin_bottom = -102.0 -rect_min_size = Vector2( 0, 600 ) +margin_right = -294.0 +margin_bottom = 14.0 diff --git a/project/demos/seek_and_flee/Seeker.gd b/project/demos/seek_and_flee/Seeker.gd index 32022db..9374926 100644 --- a/project/demos/seek_and_flee/Seeker.gd +++ b/project/demos/seek_and_flee/Seeker.gd @@ -2,8 +2,6 @@ extends KinematicBody2D # AI agent that uses the Seek behavior to hone in on the player's location as directly as possible. -onready var collision_shape: = $CollisionShape2D - onready var agent: = GSTSteeringAgent.new() onready var accel: = GSTTargetAcceleration.new() onready var seek: = GSTSeek.new(agent, player_agent) @@ -14,18 +12,11 @@ var player_agent: GSTAgentLocation var velocity: = Vector2.ZERO var start_speed: float var start_accel: float -var color: Color -var radius: = 0.0 func _ready() -> void: agent.max_linear_acceleration = start_accel agent.max_linear_speed = start_speed - radius = collision_shape.shape.radius - - -func _draw() -> void: - draw_circle(Vector2.ZERO, radius, color) func _physics_process(delta: float) -> void: @@ -53,7 +44,7 @@ func _on_GUI_mode_changed(mode: int) -> void: _active_behavior = flee -func _on_GUI_acc_changed(value: float) -> void: +func _on_GUI_accel_changed(value: float) -> void: agent.max_linear_acceleration = value diff --git a/project/demos/seek_and_flee/Seeker.tscn b/project/demos/seek_and_flee/Seeker.tscn index 1d154bb..6e5d647 100644 --- a/project/demos/seek_and_flee/Seeker.tscn +++ b/project/demos/seek_and_flee/Seeker.tscn @@ -1,8 +1,10 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=4 format=2] [ext_resource path="res://demos/seek_and_flee/Seeker.gd" type="Script" id=1] +[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=2] [sub_resource type="CircleShape2D" id=1] +radius = 16.0 [node name="Seeker" type="KinematicBody2D"] collision_layer = 4 @@ -11,3 +13,7 @@ script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource( 1 ) + +[node name="Sprite" type="Sprite" parent="."] +modulate = Color( 0.113725, 0.635294, 0.94902, 1 ) +texture = ExtResource( 2 )