Implement Separation behavior and add Proximity

This commit is contained in:
Francois Belair 2020-01-08 12:46:42 -05:00
parent 8fb4f4c51a
commit ac99344633
5 changed files with 133 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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

View File

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