diff --git a/src/Boid.gd b/src/Boid.gd index 105c16f..05b2b25 100644 --- a/src/Boid.gd +++ b/src/Boid.gd @@ -1,52 +1,52 @@ -extends Node2D class_name Boid +extends Node2D -onready var detectors = $ObsticleDetectors -onready var sensors = $ObsticleSensors +export (Array, Color) var colors := [] -var boids = [] -var move_speed = 200 -var perception_radius = 50 -var velocity = Vector2() -var acceleration = Vector2() -var steer_force = 50.0 -var alignment_force = 0.6 -var cohesion_force = 0.6 -var seperation_force = 1.0 -var avoidance_force = 3.0 +onready var detectors: Node2D = $ObsticleDetectors +onready var sensors: Node2D = $ObsticleSensors +var boids := [] +var move_speed := 200 +var perception_radius := 50 +var velocity := Vector2() +var acceleration := Vector2() +var steer_force := 50.0 +var alignment_force := 0.6 +var cohesion_force := 0.6 +var seperation_force := 1.0 +var avoidance_force := 3.0 -export (Array, Color) var colors -func _ready(): +func _ready() -> void: randomize() - + position = Vector2(rand_range(0, get_viewport().size.x), rand_range(0, get_viewport().size.y)) velocity = Vector2(rand_range(-1, 1), rand_range(-1, 1)).normalized() * move_speed modulate = colors[rand_range(0, colors.size())] -func _process(delta): - - var neighbors = get_neighbors(perception_radius) - +func _process(delta: float) -> void: + var neighbors := get_neighbors(perception_radius) + acceleration += process_alignments(neighbors) * alignment_force acceleration += process_cohesion(neighbors) * cohesion_force acceleration += process_seperation(neighbors) * seperation_force if is_obsticle_ahead(): acceleration += process_obsticle_avoidance() * avoidance_force - + velocity += acceleration * delta velocity = velocity.clamped(move_speed) rotation = velocity.angle() - + translate(velocity * delta) - + position.x = wrapf(position.x, -32, get_viewport().size.x + 32) position.y = wrapf(position.y, -32, get_viewport().size.y + 32) -func process_cohesion(neighbors): + +func process_cohesion(neighbors: Array) -> Vector2: var vector = Vector2() if neighbors.empty(): return vector @@ -54,60 +54,58 @@ func process_cohesion(neighbors): vector += boid.position vector /= neighbors.size() return steer((vector - position).normalized() * move_speed) - -func process_alignments(neighbors): + +func process_alignments(neighbors: Array) -> Vector2: var vector = Vector2() if neighbors.empty(): return vector - + for boid in neighbors: vector += boid.velocity vector /= neighbors.size() return steer(vector.normalized() * move_speed) -func process_seperation(neighbors): - var vector = Vector2() - var close_neighbors = [] + +func process_seperation(neighbors: Array) -> Vector2: + var vector := Vector2() + var close_neighbors := [] for boid in neighbors: - if position.distance_to(boid.position) < perception_radius / 2: + if position.distance_to(boid.position) < perception_radius / 2.0: close_neighbors.push_back(boid) if close_neighbors.empty(): return vector - + for boid in close_neighbors: var difference = position - boid.position vector += difference.normalized() / difference.length() - + vector /= close_neighbors.size() return steer(vector.normalized() * move_speed) - - -func steer(var target): - var steer = target - velocity - steer = steer.normalized() * steer_force - return steer - -func is_obsticle_ahead(): + + +func steer(target: Vector2) -> Vector2: + return (target - velocity).normalized() * steer_force + + +func is_obsticle_ahead() -> bool: for ray in detectors.get_children(): if ray.is_colliding(): return true return false -func process_obsticle_avoidance(): + +func process_obsticle_avoidance() -> Vector2: for ray in sensors.get_children(): if not ray.is_colliding(): - return steer( (ray.cast_to.rotated(ray.rotation + rotation)).normalized() * move_speed ) - + return steer((ray.cast_to.rotated(ray.rotation + rotation)).normalized() * move_speed) return Vector2.ZERO -func get_neighbors(view_radius): - var neighbors = [] + +func get_neighbors(view_radius: int) -> Array: + var neighbors := [] for boid in boids: - if position.distance_to(boid.position) <= view_radius and not boid == self: + if position.distance_to(boid.position) <= view_radius: neighbors.push_back(boid) return neighbors - - - diff --git a/src/Simulation.gd b/src/Simulation.gd index 3aff9ee..7e13e1a 100644 --- a/src/Simulation.gd +++ b/src/Simulation.gd @@ -1,17 +1,17 @@ extends Node2D -const BOIDS_COUNT = 300 +const BOIDS_COUNT := 300 -onready var boid_scene = preload("res://src/Boid.tscn") -onready var boids_container = $Boids -onready var water = $Water +onready var boid_scene := preload("res://src/Boid.tscn") +onready var boids_container: Node2D = $Boids +onready var water: Sprite = $Water -var boids = [] +var boids := [] -func _ready(): - - for i in BOIDS_COUNT: - var boid = boid_scene.instance() + +func _ready() -> void: + for _index in BOIDS_COUNT: + var boid: Boid = boid_scene.instance() boid.move_speed = $HUD/VBoxContainer/MoveSlider/HSlider.value boid.steer_force = $HUD/VBoxContainer/TurnSlider/HSlider.value boid.alignment_force = $HUD/VBoxContainer/AlignSlider/HSlider.value @@ -19,36 +19,37 @@ func _ready(): boid.seperation_force = $HUD/VBoxContainer/AlignSlider/HSlider.value boids_container.add_child(boid) boids.push_back(boid) - - - for boid in boids_container.get_children(): - boid.boids = boids - -func _on_MoveSlider_value_changed(value): + for boid in boids: + var other_boids = boids.duplicate() + other_boids.erase(boid) + boid.boids = other_boids + + +func _on_MoveSlider_value_changed(value: float) -> void: for boid in boids: boid.move_speed = value -func _on_TurnSlider_value_changed(value): +func _on_TurnSlider_value_changed(value: float) -> void: for boid in boids: boid.steer_force = value -func _on_AlignSlider_value_changed(value): +func _on_AlignSlider_value_changed(value: float) -> void: for boid in boids: boid.alignment_force = value -func _on_CohesionSlider_value_changed(value): +func _on_CohesionSlider_value_changed(value: float) -> void: for boid in boids: boid.cohesion_force = value -func _on_SeperationSlider_value_changed(value): +func _on_SeperationSlider_value_changed(value: float) -> void: for boid in boids: boid.seperation_force = value -func _on_DistortionSlider_value_changed(value): +func _on_DistortionSlider_value_changed(value: float) -> void: water.material.set_shader_param("distortion_amount", value) diff --git a/src/Slider.gd b/src/Slider.gd index 22c203e..5c8c2da 100644 --- a/src/Slider.gd +++ b/src/Slider.gd @@ -2,10 +2,10 @@ extends Control signal value_changed -func _ready(): +func _ready() -> void: $HSlider.connect("value_changed", self, "on_slider_changed") $Value.text = str($HSlider.value) -func on_slider_changed(value): +func on_slider_changed(value: float) -> void: $Value.text = str(value) emit_signal("value_changed", value)