Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 48 additions & 50 deletions src/Boid.gd
Original file line number Diff line number Diff line change
@@ -1,113 +1,111 @@
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
for boid in 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



41 changes: 21 additions & 20 deletions src/Simulation.gd
Original file line number Diff line number Diff line change
@@ -1,54 +1,55 @@
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
boid.cohesion_force = $HUD/VBoxContainer/CohesionSlider/HSlider.value
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)
4 changes: 2 additions & 2 deletions src/Slider.gd
Original file line number Diff line number Diff line change
Expand Up @@ -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)