diff --git a/project/demos/arrive/ArriveDemo.gd b/project/demos/arrive/ArriveDemo.gd index 3df302c..deaef47 100644 --- a/project/demos/arrive/ArriveDemo.gd +++ b/project/demos/arrive/ArriveDemo.gd @@ -5,33 +5,35 @@ onready var target: = $Target onready var arriver: = $Arriver onready var gui: = $GUI +export(float, 0, 2000, 40) var max_linear_speed: = 200.0 setget set_max_linear_speed +export(float, 0, 200, 1) var max_linear_accel: = 25.0 setget set_max_linear_accel +export(float, 0, 100, 0.1) var arrival_tolerance: = 20.0 setget set_arrival_tolerance +export(float, 0, 500, 10) var deceleration_radius: = 200.0 setget set_deceleration_radius + 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) + target.position = arriver.global_position -func draw(location: Vector2) -> void: - target.draw(location) +func set_arrival_tolerance(value: float) -> void: + arrival_tolerance = value + if arriver: + arriver.arrive.arrival_tolerance = value -func _on_GUI_align_tolerance_changed(value: int) -> void: - arriver._arrive.arrival_tolerance = value +func set_deceleration_radius(value: float) -> void: + deceleration_radius = value + if arriver: + arriver.arrive.deceleration_radius = value -func _on_GUI_decel_radius_changed(value: int) -> void: - arriver._arrive.deceleration_radius = value +func set_max_linear_speed(value: float) -> void: + max_linear_speed = value + if arriver: + arriver.agent.max_linear_speed = 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 +func set_max_linear_accel(value: float) -> void: + max_linear_accel = value + if arriver: + arriver.agent.max_linear_acceleration = value diff --git a/project/demos/arrive/ArriveDemo.tscn b/project/demos/arrive/ArriveDemo.tscn index 23a18f5..b84edba 100644 --- a/project/demos/arrive/ArriveDemo.tscn +++ b/project/demos/arrive/ArriveDemo.tscn @@ -2,24 +2,34 @@ [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] +[ext_resource path="res://assets/sprites/large_circle.png" type="Texture" id=3] +[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=4] [sub_resource type="CircleShape2D" id=1] -radius = 15.0 +radius = 16.0 [node name="ArriveDemo" type="Node2D"] script = ExtResource( 2 ) +max_linear_speed = 400.0 +max_linear_accel = 50.0 +arrival_tolerance = 10.0 +deceleration_radius = 80.0 [node name="Arriver" type="KinematicBody2D" parent="."] +position = Vector2( 512, 300 ) script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="Arriver"] shape = SubResource( 1 ) -[node name="Target" type="Node2D" parent="."] -script = ExtResource( 3 ) +[node name="Sprite" type="Sprite" parent="Arriver"] +modulate = Color( 0.952941, 0.172549, 0.0431373, 1 ) +texture = ExtResource( 4 ) -[node name="GUI" parent="." instance=ExtResource( 4 )] -margin_right = 227.0 -margin_bottom = 184.0 +[node name="Target" type="Sprite" parent="."] +modulate = Color( 0.827451, 1, 0, 0.501961 ) +texture = ExtResource( 3 ) + +[node name="Sprite" type="Sprite" parent="Target"] +scale = Vector2( 0.5, 0.5 ) +texture = ExtResource( 4 ) diff --git a/project/demos/arrive/Arriver.gd b/project/demos/arrive/Arriver.gd index cfb028c..2cfad09 100644 --- a/project/demos/arrive/Arriver.gd +++ b/project/demos/arrive/Arriver.gd @@ -1,46 +1,40 @@ extends KinematicBody2D -onready var collision_shape: = $CollisionShape2D - -var _radius: = 0.0 -var _agent: = GSTSteeringAgent.new() -var _target: = GSTAgentLocation.new() -var _arrive: = GSTArrive.new(_agent, _target) +onready var agent: = GSTSteeringAgent.new() +onready var target: = GSTAgentLocation.new() +onready var arrive: = GSTArrive.new(agent, target) var _accel: = GSTTargetAcceleration.new() var _velocity: = Vector2() -var _drag: = 1.0 +var _drag: = 0.1 func _ready() -> void: - _radius = collision_shape.shape.radius - _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) + agent.max_linear_speed = owner.max_linear_speed + agent.max_linear_acceleration = owner.max_linear_accel + agent.position = Vector3(global_position.x, global_position.y, 0) + arrive.deceleration_radius = owner.deceleration_radius + arrive.arrival_tolerance = owner.arrival_tolerance + target.position = agent.position 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)) + target.position = Vector3(mb.position.x, mb.position.y, 0) + owner.target.position = mb.position func _physics_process(delta: float) -> void: - _accel = _arrive.calculate_steering(_accel) - _velocity += Vector2(_accel.linear.x, _accel.linear.y) - _velocity = _velocity.linear_interpolate(Vector2.ZERO, 0.1) - _velocity = move_and_slide(_velocity) _update_agent() + _accel = arrive.calculate_steering(_accel) + _velocity += Vector2(_accel.linear.x, _accel.linear.y) + _velocity = _velocity.linear_interpolate(Vector2.ZERO, _drag).clamped(agent.max_linear_speed) + _velocity = move_and_slide(_velocity) func _update_agent() -> void: - _agent.position = Vector3(global_position.x, global_position.y, 0) - _agent.linear_velocity = Vector3(_velocity.x, _velocity.y, 0) + 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/GUI.gd b/project/demos/arrive/GUI.gd deleted file mode 100644 index 3ed6a03..0000000 --- a/project/demos/arrive/GUI.gd +++ /dev/null @@ -1,47 +0,0 @@ -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 deleted file mode 100644 index d870e56..0000000 --- a/project/demos/arrive/GUI.tscn +++ /dev/null @@ -1,108 +0,0 @@ -[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/arrive/Target.gd b/project/demos/arrive/Target.gd deleted file mode 100644 index 831df6c..0000000 --- a/project/demos/arrive/Target.gd +++ /dev/null @@ -1,14 +0,0 @@ -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/FaceDemo.gd b/project/demos/face/FaceDemo.gd index df51ca2..b754e51 100644 --- a/project/demos/face/FaceDemo.gd +++ b/project/demos/face/FaceDemo.gd @@ -5,30 +5,40 @@ onready var player: = $Player onready var gui: = $GUI onready var turret: = $Turret +export(int, 0, 359, 1) var max_angular_speed: = 90 setget set_max_angular_speed +export(int, 0, 359, 1) var max_angular_accel: = 5 setget set_max_angular_accel +export(int, 0, 180, 1) var align_tolerance: = 5 setget set_align_tolerance +export(int, 0, 359, 1) var deceleration_radius: = 45 setget set_deceleration_radius + 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))) + turret.setup( + deg2rad(align_tolerance), + deg2rad(deceleration_radius), + deg2rad(max_angular_accel), + deg2rad(max_angular_speed) + ) -func _on_GUI_align_tolerance_changed(value: int) -> void: - turret._face.alignment_tolerance = deg2rad(value) +func set_align_tolerance(value: int) -> void: + align_tolerance = value + if turret: + turret._face.alignment_tolerance = deg2rad(value) -func _on_GUI_decel_radius_changed(value: int) -> void: - turret._face.deceleration_radius = deg2rad(value) +func set_deceleration_radius(value: int) -> void: + deceleration_radius = value + if turret: + turret._face.deceleration_radius = deg2rad(value) -func _on_GUI_max_accel_changed(value: int) -> void: - turret._agent.max_angular_acceleration = deg2rad(value) +func set_max_angular_accel(value: int) -> void: + max_angular_accel = value + if turret: + turret._agent.max_angular_acceleration = deg2rad(value) -func _on_GUI_max_speed_changed(value: int) -> void: - turret._agent.max_angular_speed = deg2rad(value) +func set_max_angular_speed(value: int) -> void: + max_angular_speed = value + if turret: + turret._agent.max_angular_speed = deg2rad(value) diff --git a/project/demos/face/FaceDemo.tscn b/project/demos/face/FaceDemo.tscn index 8960aed..207981a 100644 --- a/project/demos/face/FaceDemo.tscn +++ b/project/demos/face/FaceDemo.tscn @@ -1,15 +1,16 @@ -[gd_scene load_steps=7 format=2] +[gd_scene load_steps=8 format=2] [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] +[ext_resource path="res://assets/sprites/large_circle.png" type="Texture" id=4] +[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=5] [sub_resource type="CircleShape2D" id=1] -radius = 20.0 +radius = 16.0 [sub_resource type="CircleShape2D" id=2] -radius = 30.0 +radius = 32.0 [node name="FaceDemo" type="Node2D"] script = ExtResource( 2 ) @@ -24,6 +25,10 @@ script = ExtResource( 3 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] shape = SubResource( 1 ) +[node name="Sprite" type="Sprite" parent="Player"] +modulate = Color( 0.945098, 0.215686, 0.0705882, 1 ) +texture = ExtResource( 5 ) + [node name="Turret" type="KinematicBody2D" parent="."] position = Vector2( 512, 150 ) script = ExtResource( 1 ) @@ -31,6 +36,6 @@ script = ExtResource( 1 ) [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 +[node name="Sprite" type="Sprite" parent="Turret"] +modulate = Color( 0.137255, 0.866667, 0.647059, 1 ) +texture = ExtResource( 4 ) diff --git a/project/demos/face/GUI.gd b/project/demos/face/GUI.gd deleted file mode 100644 index 4284c41..0000000 --- a/project/demos/face/GUI.gd +++ /dev/null @@ -1,47 +0,0 @@ -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 deleted file mode 100644 index 09eef08..0000000 --- a/project/demos/face/GUI.tscn +++ /dev/null @@ -1,153 +0,0 @@ -[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/Player.gd b/project/demos/face/Player.gd index d5fa879..5c7609e 100644 --- a/project/demos/face/Player.gd +++ b/project/demos/face/Player.gd @@ -1,21 +1,10 @@ extends KinematicBody2D -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) - func _physics_process(delta: float) -> void: var movement: = _get_movement() diff --git a/project/demos/face/Turret.gd b/project/demos/face/Turret.gd index 9209af4..7eb6cae 100644 --- a/project/demos/face/Turret.gd +++ b/project/demos/face/Turret.gd @@ -3,25 +3,23 @@ extends KinematicBody2D 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 _angular_drag: = 0.01 var _face: GSTFace func _ready() -> void: - _radius = collision_shape.shape.radius - _cannon = Rect2(Vector2(-5, 0), Vector2(10, -_radius*2)) + var 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: @@ -31,24 +29,26 @@ func _physics_process(delta: float) -> void: _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 + _angular_velocity = lerp(_angular_velocity, 0, _angular_drag) rotation += _angular_velocity * delta _update_agent() -func setup() -> void: +func setup( + align_tolerance: float, + deceleration_radius: float, + max_angular_accel: float, + max_angular_speed: float + ) -> void: _face = GSTFace.new(_agent, owner.player.agent) - _face.alignment_tolerance = 0.1 - _face.deceleration_radius = PI/2 + _face.alignment_tolerance = align_tolerance + _face.deceleration_radius = deceleration_radius - _agent.max_angular_acceleration = 0.5 - _agent.max_angular_speed = 5 + _agent.max_angular_acceleration = max_angular_accel + _agent.max_angular_speed = max_angular_speed _agent.position = Vector3(global_position.x, global_position.y, 0) _update_agent() diff --git a/project/demos/group_behaviors/GroupBehaviorsDemo.gd b/project/demos/group_behaviors/GroupBehaviorsDemo.gd new file mode 100644 index 0000000..d400c31 --- /dev/null +++ b/project/demos/group_behaviors/GroupBehaviorsDemo.gd @@ -0,0 +1,58 @@ +extends Node2D + + +onready var spawner: = $Spawner + +export var max_linear_speed: = 100.0 setget set_max_linear_speed +export var max_linear_accel: = 25.0 setget set_max_linear_accel +export var proximity_radius: = 140.0 setget set_proximity_radius +export var show_proximity_radius: = true setget set_show_proximity_radius +export var separation_decay_coefficient: = 2000.0 setget set_separation_decay_coef +export var cohesion_strength: = 0.3 setget set_cohesion_strength +export var separation_strength: = 1.5 setget set_separation_strength + + +func _ready() -> void: + pass + + +func set_max_linear_speed(value: float) -> void: + max_linear_speed = value + if spawner: + spawner.set_max_linear_speed(value) + + +func set_max_linear_accel(value: float) -> void: + max_linear_accel = value + if spawner: + spawner.set_max_linear_accel(value) + + +func set_proximity_radius(value: float) -> void: + proximity_radius = value + if spawner: + spawner.set_proximity_radius(value) + + +func set_show_proximity_radius(value: bool) -> void: + show_proximity_radius = value + if spawner: + spawner.set_show_proximity_radius(value) + + +func set_separation_decay_coef(value: float) -> void: + separation_decay_coefficient = value + if spawner: + spawner.set_separation_decay_coef(value) + + +func set_cohesion_strength(value: float) -> void: + cohesion_strength = value + if spawner: + spawner.set_cohesion_strength(value) + + +func set_separation_strength(value: float) -> void: + separation_strength = value + if spawner: + spawner.set_separation_strength(value) diff --git a/project/demos/group_behaviors/GroupBehaviorsDemo.tscn b/project/demos/group_behaviors/GroupBehaviorsDemo.tscn index 806d7ec..d1338cd 100644 --- a/project/demos/group_behaviors/GroupBehaviorsDemo.tscn +++ b/project/demos/group_behaviors/GroupBehaviorsDemo.tscn @@ -1,11 +1,13 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=4 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] +[ext_resource path="res://demos/group_behaviors/GroupBehaviorsDemo.gd" type="Script" id=3] [node name="GroupBehaviorsDemo" type="Node2D"] +script = ExtResource( 3 ) [node name="Spawner" type="Node2D" parent="."] -position = Vector2( 397, 207 ) +position = Vector2( 512, 300 ) script = ExtResource( 2 ) member = ExtResource( 1 ) diff --git a/project/demos/group_behaviors/Member.gd b/project/demos/group_behaviors/Member.gd index 9e4b8b3..6a891d3 100644 --- a/project/demos/group_behaviors/Member.gd +++ b/project/demos/group_behaviors/Member.gd @@ -7,30 +7,37 @@ var cohesion: GSTCohesion var proximity: GSTRadiusProximity var blend: = GSTBlend.new(agent) var acceleration: = GSTTargetAcceleration.new() +var draw_proximity: = false -var _radius: float var _color: = Color.red var _velocity: = Vector2() -onready var shape: = $CollisionShape2D - -func _ready() -> void: - _radius = shape.shape.radius +func setup( + max_linear_speed: float, + max_linear_accel: float, + proximity_radius: float, + separation_decay_coefficient: float, + cohesion_strength: float, + separation_strength: float + ) -> void: _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 + $Sprite.modulate = _color - proximity = GSTRadiusProximity.new(agent, [], 140) + agent.max_linear_acceleration = max_linear_accel + agent.max_linear_speed = max_linear_speed + + proximity = GSTRadiusProximity.new(agent, [], proximity_radius) separation = GSTSeparation.new(agent, proximity) - separation.decay_coefficient = 2000 + separation.decay_coefficient = separation_decay_coefficient cohesion = GSTCohesion.new(agent, proximity) - blend.add(separation, 1.5) - blend.add(cohesion, 0.3) + blend.add(separation, separation_strength) + blend.add(cohesion, cohesion_strength) func _draw() -> void: - draw_circle(Vector2.ZERO, _radius, _color) + if draw_proximity: + draw_circle(Vector2.ZERO, proximity.radius, Color(0, 1, 0, 0.1)) func _process(delta: float) -> void: diff --git a/project/demos/group_behaviors/Member.tscn b/project/demos/group_behaviors/Member.tscn index c2ae670..6b7d2bb 100644 --- a/project/demos/group_behaviors/Member.tscn +++ b/project/demos/group_behaviors/Member.tscn @@ -1,12 +1,16 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=4 format=2] [ext_resource path="res://demos/group_behaviors/Member.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 = 15.0 +radius = 16.0 [node name="Member" type="KinematicBody2D"] script = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource( 1 ) + +[node name="Sprite" type="Sprite" parent="."] +texture = ExtResource( 2 ) diff --git a/project/demos/group_behaviors/Spawner.gd b/project/demos/group_behaviors/Spawner.gd index c1d8556..e9853fd 100644 --- a/project/demos/group_behaviors/Spawner.gd +++ b/project/demos/group_behaviors/Spawner.gd @@ -11,8 +11,56 @@ func _ready() -> void: add_child(follower) follower.position += Vector2(rand_range(-60, 60), rand_range(-60, 60)) followers.append(follower) + follower.setup( + owner.max_linear_speed, + owner.max_linear_accel, + owner.proximity_radius, + owner.separation_decay_coefficient, + owner.cohesion_strength, + owner.separation_strength + ) + if i == 0 and owner.show_proximity_radius: + follower.draw_proximity = true + follower.update() var agents: = [] for i in followers: agents.append(i.agent) for i in followers: i.proximity.agents = agents + + +func set_max_linear_speed(value: float) -> void: + for child in get_children(): + child.agent.max_linear_speed = value + + +func set_max_linear_accel(value: float) -> void: + for child in get_children(): + child.agent.max_linear_acceleration = value + + +func set_proximity_radius(value: float) -> void: + for child in get_children(): + child.proximity.radius = value + if child == get_child(0): + child.update() + + +func set_show_proximity_radius(value: bool) -> void: + get_child(0).draw_proximity = value + get_child(0).update() + + +func set_separation_decay_coef(value: float) -> void: + for child in get_children(): + child.separation.decay_coefficient = value + + +func set_cohesion_strength(value: float) -> void: + for child in get_children(): + child.blend.get_behavior_at(1).weight = value + + +func set_separation_strength(value: float) -> void: + for child in get_children(): + child.blend.get_behavior_at(0).weight = value diff --git a/project/demos/pursue_vs_seek/GUI.gd b/project/demos/pursue_vs_seek/GUI.gd deleted file mode 100644 index 467c9e2..0000000 --- a/project/demos/pursue_vs_seek/GUI.gd +++ /dev/null @@ -1,38 +0,0 @@ -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: = $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("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 _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_Slider_linear_accel_changed(value: float) -> void: - lin_accel_label.text = "Max linear accel (" + str(value) + ")" - emit_signal("linear_accel_changed", value) - - -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 deleted file mode 100644 index 4eda7ac..0000000 --- a/project/demos/pursue_vs_seek/GUI.tscn +++ /dev/null @@ -1,139 +0,0 @@ -[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="PanelContainer" type="PanelContainer"] -anchor_bottom = 1.0 -margin_right = 364.0 -theme = ExtResource( 2 ) -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[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 = 344.0 -margin_bottom = 580.0 - -[node name="LinSpeedBox" type="VBoxContainer" parent="GUI/Controls"] -margin_right = 324.0 -margin_bottom = 50.0 - -[node name="Label" type="Label" parent="GUI/Controls/LinSpeedBox"] -margin_right = 324.0 -margin_bottom = 26.0 -text = "Max linear speed (2000)" - -[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="LinAccelBox" type="VBoxContainer" parent="GUI/Controls"] -margin_top = 58.0 -margin_right = 324.0 -margin_bottom = 108.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="GUI/Controls/Help"] -margin_top = 34.0 -margin_right = 324.0 -margin_bottom = 90.0 -columns = 3 - -[node name="Sep" type="Control" parent="GUI/Controls/Help/GridContainer"] -margin_right = 15.0 -margin_bottom = 26.0 -rect_min_size = Vector2( 15, 15 ) - -[node name="W" type="Label" parent="GUI/Controls/Help/GridContainer"] -margin_left = 19.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="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="GUI/Controls/Help/GridContainer"] -margin_top = 30.0 -margin_right = 15.0 -margin_bottom = 56.0 -rect_min_size = Vector2( 15, 15 ) -text = "A" -align = 1 - -[node name="S" type="Label" parent="GUI/Controls/Help/GridContainer"] -margin_left = 19.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="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 29df3ed..9487f1f 100644 --- a/project/demos/pursue_vs_seek/Player.gd +++ b/project/demos/pursue_vs_seek/Player.gd @@ -4,12 +4,12 @@ extends "res://demos/pursue_vs_seek/Ship.gd" onready var agent: = GSTSteeringAgent.new() -export var thruster_strength: = 150.0 +export var thruster_strength: = 250.0 export var side_thruster_strength: = 10.0 -export var max_velocity: = 150.0 +export var max_velocity: = 300.0 export var max_angular_velocity: = 2.0 -export var angular_drag: = 5.0 -export var linear_drag: = 100.0 +export var angular_drag: = 0.025 +export var linear_drag: = 0.025 var _linear_velocity: = Vector2() var _angular_velocity: = 0.0 @@ -56,12 +56,7 @@ func _calculate_angular_velocity( max_velocity ) - if velocity > 0: - velocity -= ship_drag * delta - elif velocity < 0: - velocity += ship_drag * delta - if abs(velocity) < 0.01: - velocity = 0 + velocity = lerp(velocity, 0, ship_drag) return velocity @@ -70,7 +65,7 @@ func _calculate_linear_velocity( vertical_movement: float, current_velocity: Vector2, facing_direction: Vector2, - ship_drag: float, + ship_drag_coefficient: float, strength: float, max_speed: float, delta: float) -> Vector2: @@ -82,7 +77,7 @@ func _calculate_linear_velocity( actual_strength = -strength/1.5 var velocity: = current_velocity + facing_direction * actual_strength * delta - velocity -= current_velocity.normalized() * (ship_drag * delta) + velocity = velocity.linear_interpolate(Vector2.ZERO, ship_drag_coefficient) return velocity.clamped(max_speed) diff --git a/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd b/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd index e65d583..5af3c3d 100644 --- a/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd +++ b/project/demos/pursue_vs_seek/PursueVSSeekDemo.gd @@ -1,34 +1,31 @@ extends Node2D -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 +export(float, 0, 2000, 40) var max_linear_speed: = 200.0 setget set_max_linear_speed +export(float, 0, 200, 1) var max_linear_accel: = 10.0 setget set_max_linear_accel +export(float, 0, 5, 0.1) var predict_time: = 2.0 setget set_predict_time -func _ready() -> void: - 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 set_max_linear_speed(value: float) -> void: + max_linear_speed = value + if pursuer: + pursuer.agent.max_linear_speed = value + if seeker: + seeker.agent.max_linear_speed = value -func _on_GUI_linear_accel_changed(value: int) -> void: - pursuer.agent.max_linear_acceleration = float(value) - seeker.agent.max_linear_acceleration = float(value) +func set_max_linear_accel(value: float) -> void: + max_linear_accel = value + if pursuer: + pursuer.agent.max_linear_acceleration = value + if seeker: + seeker.agent.max_linear_acceleration = value -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) +func set_predict_time(value: float) -> void: + predict_time = value + if pursuer: + pursuer._behavior.max_predict_time = value diff --git a/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn b/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn index d9d2437..0a4e5bc 100644 --- a/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn +++ b/project/demos/pursue_vs_seek/PursueVSSeekDemo.tscn @@ -1,10 +1,9 @@ -[gd_scene load_steps=7 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/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"] @@ -12,9 +11,8 @@ 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 +max_linear_speed = 120.0 +predict_time = 1.0 [node name="BoundaryManager" type="Node2D" parent="."] script = ExtResource( 3 ) @@ -56,6 +54,3 @@ 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 = 309.0 diff --git a/project/demos/pursue_vs_seek/Pursuer.gd b/project/demos/pursue_vs_seek/Pursuer.gd index 12ea4a6..b44276e 100644 --- a/project/demos/pursue_vs_seek/Pursuer.gd +++ b/project/demos/pursue_vs_seek/Pursuer.gd @@ -12,6 +12,7 @@ var _orient_behavior: GSTSteeringBehavior var _behavior: GSTSteeringBehavior var _linear_velocity: = Vector2() +var _linear_drag_coefficient: = 0.025 var _angular_velocity: = 0.0 var _angular_drag: = 1.0 @@ -24,7 +25,7 @@ func _setup() -> void: if use_seek: _behavior = GSTSeek.new(agent, player_agent) else: - _behavior = GSTPursue.new(agent, player_agent, 2) + _behavior = GSTPursue.new(agent, player_agent, owner.predict_time) _orient_behavior = GSTLookWhereYouGo.new(agent) _orient_behavior.alignment_tolerance = 0.001 @@ -32,8 +33,8 @@ func _setup() -> void: agent.max_angular_acceleration = 2 agent.max_angular_speed = 5 - agent.max_linear_acceleration = 75 - agent.max_linear_speed = 125 + agent.max_linear_acceleration = owner.max_linear_accel + agent.max_linear_speed = owner.max_linear_speed _update_agent() @@ -49,8 +50,8 @@ func _physics_process(delta: float) -> void: rotation = rotation + _angular_velocity * delta accel = _behavior.calculate_steering(accel) - _linear_velocity += Vector2(accel.linear.x, accel.linear.y) * delta - _linear_velocity -= _linear_velocity.normalized() * 10 * delta + _linear_velocity += Vector2(accel.linear.x, accel.linear.y) + _linear_velocity = _linear_velocity.linear_interpolate(Vector2.ZERO, _linear_drag_coefficient) _linear_velocity = _linear_velocity.clamped(agent.max_linear_speed) _linear_velocity = move_and_slide(_linear_velocity) diff --git a/project/demos/seek_and_flee/GUI.gd b/project/demos/seek_and_flee/GUI.gd deleted file mode 100644 index c3750c8..0000000 --- a/project/demos/seek_and_flee/GUI.gd +++ /dev/null @@ -1,48 +0,0 @@ -extends PanelContainer - - -enum BehaviorMode { SEEK, FLEE } - -signal mode_changed(behavior_mode) -signal accel_changed(value) -signal speed_changed(value) - -onready var seek: = $MarginContainer/BehaviorControls/Seek -onready var flee: = $MarginContainer/BehaviorControls/Flee -onready var max_accel: = $MarginContainer/BehaviorControls/MaxAccelValue -onready var max_speed: = $MarginContainer/BehaviorControls/MaxSpeedValue -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_accel.connect("value_changed", self, "_on_Accel_changed") - max_speed.connect("value_changed", self, "_on_Speed_changed") - max_accel_label.text = "Max accel (" + str(max_accel.value) + ")" - max_speed_label.text = "Max speed (" + str(max_speed.value) + ")" - - -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) - - -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: - 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 deleted file mode 100644 index a63d376..0000000 --- a/project/demos/seek_and_flee/GUI.tscn +++ /dev/null @@ -1,142 +0,0 @@ -[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="PanelContainer"] -anchor_bottom = 1.0 -margin_right = 118.0 -theme = ExtResource( 1 ) -script = ExtResource( 3 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[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 = 198.0 -margin_bottom = 580.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="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="MaxAccel" 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="MaxAccelValue" 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 -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="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="MarginContainer/BehaviorControls/Help/GridContainer"] -margin_right = 15.0 -margin_bottom = 26.0 -rect_min_size = Vector2( 15, 15 ) - -[node name="W" type="Label" parent="MarginContainer/BehaviorControls/Help/GridContainer"] -margin_left = 19.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="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="MarginContainer/BehaviorControls/Help/GridContainer"] -margin_top = 30.0 -margin_right = 15.0 -margin_bottom = 56.0 -rect_min_size = Vector2( 15, 15 ) -text = "A" -align = 1 - -[node name="S" type="Label" parent="MarginContainer/BehaviorControls/Help/GridContainer"] -margin_left = 19.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="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/Player.gd b/project/demos/seek_and_flee/Player.gd index 485b88e..9fba69f 100644 --- a/project/demos/seek_and_flee/Player.gd +++ b/project/demos/seek_and_flee/Player.gd @@ -4,7 +4,7 @@ extends KinematicBody2D onready var agent: = GSTAgentLocation.new() -export var speed: = 150.0 +export var speed: = 200.0 func _get_movement() -> Vector2: diff --git a/project/demos/seek_and_flee/SeekFleeDemo.gd b/project/demos/seek_and_flee/SeekFleeDemo.gd index 9fcd168..40a0e24 100644 --- a/project/demos/seek_and_flee/SeekFleeDemo.gd +++ b/project/demos/seek_and_flee/SeekFleeDemo.gd @@ -2,9 +2,14 @@ extends Node2D # Access helper class for children to access window boundaries. +enum Mode { FLEE, SEEK } + +export(Mode) var behavior_mode: = Mode.SEEK setget set_behavior_mode +export(float, 0, 2000, 40) var max_linear_speed: = 200.0 setget set_max_linear_speed +export(float, 0, 500, 0.5) var max_linear_accel: = 10.0 setget set_max_linear_accel + onready var player: KinematicBody2D = $Player onready var spawner: Node2D = $Spawner -onready var gui: = $GUI var camera_boundaries: Rect2 @@ -23,9 +28,6 @@ func _ready() -> void: var rng: = RandomNumberGenerator.new() rng.randomize() - gui.max_accel.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), @@ -34,9 +36,35 @@ func _ready() -> void: var entity: KinematicBody2D = spawner.Entity.instance() entity.global_position = new_pos entity.player_agent = player.agent - entity.start_speed = spawner.max_speed - entity.start_accel = spawner.max_accel - gui.connect("mode_changed", entity, "_on_GUI_mode_changed") - gui.connect("accel_changed", entity, "_on_GUI_accel_changed") - gui.connect("speed_changed", entity, "_on_GUI_speed_changed") + entity.start_speed = max_linear_speed + entity.start_accel = max_linear_accel spawner.add_child(entity) + + +func set_behavior_mode(mode: int) -> void: + behavior_mode = mode + + if spawner: + match mode: + Mode.SEEK: + for child in spawner.get_children(): + child.use_seek = true + Mode.FLEE: + for child in spawner.get_children(): + child.use_seek = false + + +func set_max_linear_speed(value: float) -> void: + max_linear_speed = value + + if spawner: + for child in spawner.get_children(): + child.agent.max_linear_speed = value + + +func set_max_linear_accel(value: float) -> void: + max_linear_accel = value + + if spawner: + for child in spawner.get_children(): + child.agent.max_linear_acceleration = value diff --git a/project/demos/seek_and_flee/SeekFleeDemo.tscn b/project/demos/seek_and_flee/SeekFleeDemo.tscn index 02a7a48..faf8d07 100644 --- a/project/demos/seek_and_flee/SeekFleeDemo.tscn +++ b/project/demos/seek_and_flee/SeekFleeDemo.tscn @@ -1,10 +1,9 @@ -[gd_scene load_steps=11 format=2] +[gd_scene load_steps=10 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] [ext_resource path="res://demos/seek_and_flee/SeekFleeDemo.gd" type="Script" id=3] [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] @@ -76,11 +75,3 @@ 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 )] -anchor_bottom = 0.0 -margin_left = -512.0 -margin_top = -300.0 -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 9374926..5795944 100644 --- a/project/demos/seek_and_flee/Seeker.gd +++ b/project/demos/seek_and_flee/Seeker.gd @@ -6,12 +6,12 @@ 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 var start_speed: float var start_accel: float +var use_seek: = true func _ready() -> void: @@ -24,7 +24,10 @@ func _physics_process(delta: float) -> void: return _update_agent() - accel = _active_behavior.calculate_steering(accel) + if use_seek: + accel = seek.calculate_steering(accel) + else: + accel = flee.calculate_steering(accel) velocity = (velocity + Vector2(accel.linear.x, accel.linear.y)).clamped(agent.max_linear_speed) velocity = move_and_slide(velocity) @@ -35,18 +38,3 @@ func _update_agent() -> void: 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: - if mode == 0: - _active_behavior = seek - else: - _active_behavior = flee - - -func _on_GUI_accel_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/Spawner.gd b/project/demos/seek_and_flee/Spawner.gd index 87555d7..99de62d 100644 --- a/project/demos/seek_and_flee/Spawner.gd +++ b/project/demos/seek_and_flee/Spawner.gd @@ -5,5 +5,3 @@ extends Node2D export(PackedScene) var Entity: PackedScene export var entity_count: = 10 export var entity_color: = Color.blue -export var max_speed: = 100.0 -export var max_accel: = 20.0 diff --git a/project/project.godot b/project/project.godot index fc258be..8a29bcd 100644 --- a/project/project.godot +++ b/project/project.godot @@ -161,6 +161,10 @@ _global_script_class_icons={ config/name="SteeringToolkit" config/icon="res://icon.png" +[display] + +window/size/always_on_top=true + [input] sf_left={