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.
This commit is contained in:
Francois Belair 2019-12-21 13:07:43 -05:00
parent 3e9ce641fb
commit 3d50dcdb9c
8 changed files with 159 additions and 79 deletions

View File

@ -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 )

View File

@ -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)

View File

@ -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)

View File

@ -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"

View File

@ -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 )

View File

@ -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)

View File

@ -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

View File

@ -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"]