0 votes

Hello guys, I'm trying to make a simulation in Godot on multiple threads, I'm trying to implement a small MAS(Multi-agent system) in it just for the simulation purpose.
In other words, I'm trying to spawn N NPCs(agents) which they are going to attack each other if they are going to be found one by another.
Each agent is a scene in which I want to be placed on separate threads and also I want them will be distinct one to another.
But not raise the question, can I do that? Or I can just instance each one of them?

Main.gd

extends Node2D

var dragons = 3
var screen_size

var dragon = preload("res://Player.tscn")

var thread_1
var thread_2
var thread_3


func _thread_function(userdata):
    var x = floor(rand_range(0, screen_size.x))
    var y = floor(rand_range(0, screen_size.y))

    var dr = dragon.instance()

    dr.start(Vector2(x,y))
    call_deferred("add_child", dr)

func _ready():
    screen_size = get_viewport_rect().size
    thread_1 = Thread.new()
    thread_1.start(self, "_thread_function")

    thread_2 = Thread.new()
    thread_2.start(self, "_thread_function")

    thread_3 = Thread.new()
    thread_3.start(self, "_thread_function")

func _exit_tree():
    thread_1.wait_to_finish()
    thread_2.wait_to_finish()
    thread_3.wait_to_finish()

Player.gd

extends Area2D

#export (PackedScene) var Attack

export (int) var speed = 200
var velocity = Vector2()


var is_fliped = false


var atk
var screen_size

var has_arrived = false
var destination_point = Vector2()

var target = Vector2()
var is_enemy_found = false
var can_shot = false 

var spawn

onready var target_found = get_node("RayCast2D")
#onready var attack = get_node("Attack")

var hits = 5

onready var attack = preload("res://Attack.tscn")
var flip_ray2d = false

signal _on_Player_hit

func _ready():
#   $AttackTimer.stop() 
    randomize()
    $AnimatedSprite.modulate = Color(randf(), randf(), randf())
    screen_size = get_viewport_rect().size
    destination_point = decide_next_move()

func start(pos):
    position = pos

func decide_next_move():
    var x = floor(rand_range(0, screen_size.x))
    var y = floor(rand_range(0, screen_size.y))

    return Vector2(x,y)

func move_character():
    if has_arrived:
        destination_point = decide_next_move()
        has_arrived = false
    velocity = Vector2()
    var is_walk = true

#   print(is_fliped)
#   print(position.x, " ",destination_point.x)
#   print(position.y ," ", destination_point.y)
#   print("\n")
    if position.x <= destination_point.x:
        is_fliped = false
        velocity.x += 1
    elif position.x > destination_point.x:
        is_fliped = true
        velocity.x -= 1
    if position.y < destination_point.y:
        velocity.y += 1
    elif position.y > destination_point.y:
        velocity.y -= 1

    has_arrived = position.distance_to(destination_point) < 2

    $AnimatedSprite.play('walk')
    $AnimatedSprite.flip_h = is_fliped

    target_found.rotate(1)

#   print(target_found.is_colliding())

    if target_found.is_colliding():
        is_enemy_found = true
        var d =  target_found.get_collider()
        target = d.position
        _attack()


    velocity = velocity.normalized() * speed

func _attack():
    spawn = attack.instance()
    get_tree().root.add_child(spawn)
    # Set the bullet's direction the same as the player's
    spawn.connect("_on_Player_hit", self, "_on_Player_hit") 
    spawn.start(target)
    spawn.rotation = global_rotation
    # Set the mob's position to the player's.
    spawn.position = global_position
    # Set the velocity (speed & direction).
    spawn.linear_velocity = Vector2(20, 0)
    spawn.linear_velocity = spawn.linear_velocity.rotated(global_rotation)

    return

func _process(delta):
    move_character()
    position += velocity * delta

#func _on_AttackTimer_timeout():
#   _attack()
    pass

func _on_Player_hit():
    hits -= 1
    if hits <= 0:
        queue_free()
#   spawn.hide()
#   remove_child(attack.instance())
#   print("HIT")
    pass # Replace with function body.

ERROR MESSAGE:

E 0:00:00.589 setshapetransform: Index pindex = 0 is out of
bounds (shapes.size() = 0). <C++ Source>
servers/physics
2d/collisionobject2dsw.cpp:78 @
set
shapetransform() E 0:00:00.589 areasetshapedisabled: Index
pshape = 0 is out of bounds (area->getshapecount() = 0). <C++
Source> servers/physics
2d/physics2dserversw.cpp:408 @
area
setshapedisabled()

Could any of you explain to me what I'm doing wrong? And also if it's possible at least o instantiate each Player.tscn on an individual thread.

asked Apr 28 in Projects by Vildnex (12 points)

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.