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