mirror of
https://github.com/Relintai/godot-steering-ai-framework.git
synced 2024-12-28 09:47:16 +01:00
1baed58659
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
90 lines
2.4 KiB
GDScript
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
|