# I'm transferring the project from godot 3 to godot 4. Help please

I am trying to migrate the blocking algorithm from godot 3 to godot 4. I have birds that are duplicatedossible

``````extends CharacterBody2D

# these weights where defined through
# trial and error. You can play with them
# to check how they affect the flock.
var SEPARATION_WEIGHT = 0.5
var ALIGNMENT_WEIGHT = 0.5
var COHESION_WEIGHT = 0.1

var _max_speed = 2
var _speed = 2
var _direction = Vector2(0, 1)
var _separation_distance = 20

var _local_flockmates = []

func _physics_process(_delta):
self.rotation = Vector2(0, 1).angle_to(_direction)
var collision = self.move_and_collide(_direction * _speed)
if collision:
if collision is KinematicCollision2D:
print("cool")
_direction = _collision_reaction_direction(collision)
else:
_direction = _flock_direction()

# Inverts the direction when hitting a collider.
# This implementation handles colliding with Tilemaps specifically.
func _collision_reaction_direction(collision):

return (global_position - collision.get_normal()).direction_to(self.global_position)

# This function is pretty much all you need for calculating
# the flocking movement
func _flock_direction():
var separation = Vector2()
var cohesion = Vector2()

for flockmate in _local_flockmates:
cohesion += flockmate.position

var distance = self.position.distance_to(flockmate.position)

if distance < _separation_distance:
separation -= (flockmate.position - self.position).normalized() * (_separation_distance / distance * _speed)

if _local_flockmates.size() > 0:
cohesion /= _local_flockmates.size()
var center_direction = self.position.direction_to(cohesion)
var center_speed = _max_speed * self.position.distance_to(cohesion) / \$Area2D/CollisionShape2D.shape.radius
cohesion = center_direction * center_speed
return (
_direction +
separation * SEPARATION_WEIGHT +
cohesion * COHESION_WEIGHT
).limit_length(_max_speed)

func get_direction():
return _direction

func set_direction(direction):
_direction = direction

func _on_area_2d_area_entered(body):
if body == self:
return

if body.is_in_group("boid"):
_local_flockmates.append(body)

func _on_area_2d_area_exited(body):
if body.is_in_group("boid"):
_local_flockmates.erase(body)

``````

GODOT 4

``````extends KinematicBody2D

# these weights where defined through
# trial and error. You can play with them
# to check how they affect the flock.
const SEPARATION_WEIGHT = 0.5
const ALIGNMENT_WEIGHT = 0.5
const COHESION_WEIGHT = 0.1

var _max_speed = 2
var _speed = 2
var _direction = Vector2(0, 1)
var _separation_distance = 20

var _local_flockmates = []

func _physics_process(_delta):
self.rotation = Vector2(0, 1).angle_to(_direction)
var collision = self.move_and_collide(_direction * _speed)
if collision:
if collision.collider is TileMap:
_direction = _collision_reaction_direction(collision)
else:
_direction = _flock_direction()

# Inverts the direction when hitting a collider.
# This implementation handles colliding with Tilemaps specifically.
func _collision_reaction_direction(collision):
return (collision.position - collision.normal).direction_to(self.position)

# This function is pretty much all you need for calculating
# the flocking movement
func _flock_direction():
var separation = Vector2()
var cohesion = Vector2()

for flockmate in _local_flockmates:
cohesion += flockmate.position

var distance = self.position.distance_to(flockmate.position)

if distance < _separation_distance:
separation -= (flockmate.position - self.position).normalized() * (_separation_distance / distance * _speed)

if _local_flockmates.size() > 0:
cohesion /= _local_flockmates.size()
var center_direction = self.position.direction_to(cohesion)
cohesion = center_direction * center_speed

return (
_direction +
separation * SEPARATION_WEIGHT +
cohesion * COHESION_WEIGHT
).clamped(_max_speed)

func get_direction():
return _direction

func set_direction(direction):
_direction = direction

if body == self:
return

if body.is_in_group("boid"):
_local_flockmates.push_back(body)

if body.is_in_group("boid"):
_local_flockmates.erase(body)

``````

GODOT 3

and main scene with spawn

``````extends Node2D

# add a boid on mouse click
for x in range(50):
_create_boid()

var rnd = RandomNumberGenerator.new()
func _create_boid():
var boid = Boid.instantiate()
boid.global_position = Vector2(rnd.randf_range(-250,250),rnd.randf_range(-250,250))
randomize()
var direction = Vector2(rnd.randf(), rnd.randf())
if direction == Vector2():
direction = Vector2(0, 1)
boid.set_direction(direction)

``````

GODOT4

``````extends Node2D

# add a boid on mouse click
func _unhandled_input(event):
if event is InputEventMouseButton and  event.button_index == BUTTON_LEFT and event.pressed:
_create_boid()

func _create_boid():
var boid = Boid.instance()
boid.global_position = self.get_global_mouse_position()
randomize()
var direction = Vector2(round(randf()), round(randf()))
if direction == Vector2():
direction = Vector2(0, 1)
boid.set_direction(direction)

``````

GODOT3