godot-steering-ai-framework/project/demos/AvoidCollisions/Avoider.gd
Răzvan C. Rădulescu 1baed58659 Review smart agents
I made minimal changes, mostly cosmetic like so:

- rename KinematicMovementType to MovementType since
  GSTKinematicBody2DAgent.KinematicMovementType.COLLIDE for example is
  really more than a mouthful with repeated Kinematic in the name
- add optional movement_type parameter to the constructor, otherwise
  we'd be forced to construct the object and then specify as an
  aditional step the type of movement if we want something else than the
  default
- rewrote the constructor to yield on ready and removed _on_body_ready
- renamed _apply_steering to apply_steering as this is a public method
- renamed _on_SceneTree_frame to _on_SceneTree_physics_frame
2020-02-07 12:29:45 +02:00

90 lines
2.4 KiB
GDScript

extends KinematicBody2D
var draw_proximity: bool
var _boundary_right: float
var _boundary_bottom: float
var _radius: float
var _accel := GSTTargetAcceleration.new()
var _velocity := Vector2.ZERO
var _direction := Vector2()
var _drag := 0.1
var _color := Color(0.4, 1.0, 0.89, 0.3)
onready var collision := $CollisionShape2D
onready var agent := GSTKinematicBody2DAgent.new(self)
onready var proximity := GSTRadiusProximity.new(agent, [], 140)
onready var avoid := GSTAvoidCollisions.new(agent, proximity)
onready var target := GSTAgentLocation.new()
onready var seek := GSTSeek.new(agent, target)
onready var priority := GSTPriority.new(agent, 0.0001)
func _draw() -> void:
if draw_proximity:
draw_circle(Vector2.ZERO, proximity.radius, _color)
func _physics_process(delta: float) -> void:
target.position.x = agent.position.x + _direction.x*_radius
target.position.y = agent.position.y + _direction.y*_radius
priority.calculate_steering(_accel)
agent.apply_steering(_accel, delta)
func setup(
linear_speed_max: float,
linear_accel_max: float,
proximity_radius: float,
boundary_right: float,
boundary_bottom: float,
draw_proximity: bool,
rng: RandomNumberGenerator
) -> void:
rng.randomize()
_direction = Vector2(rng.randf_range(-1, 1), rng.randf_range(-1, 1)).normalized()
agent.linear_speed_max = linear_speed_max
agent.linear_acceleration_max = linear_accel_max
proximity.radius = proximity_radius
_boundary_bottom = boundary_bottom
_boundary_right = boundary_right
_radius = collision.shape.radius
agent.bounding_radius = _radius
agent.linear_drag_percentage = _drag
self.draw_proximity = draw_proximity
priority.add(avoid)
priority.add(seek)
func set_proximity_agents(agents: Array) -> void:
proximity.agents = agents
func set_random_nonoverlapping_position(others: Array, distance_from_boundary_min: float) -> void:
var rng := RandomNumberGenerator.new()
rng.randomize()
var tries_max := max(100, others.size() * others.size())
while tries_max > 0:
tries_max -= 1
global_position.x = rng.randf_range(
distance_from_boundary_min, _boundary_right-distance_from_boundary_min
)
global_position.y = rng.randf_range(
distance_from_boundary_min, _boundary_bottom-distance_from_boundary_min
)
var done := true
for i in range(others.size()):
var other: Node2D = others[i]
if other.global_position.distance_to(position) <= _radius*2 + distance_from_boundary_min:
done = false
if done:
break