cak3_lover
cak3_lover

Reputation: 1958

Merging 2 overlapping Area2D nodes?

I have a node called "Merger" which is an Area2D with a CollisionPolygon2D in it as such:

enter image description here

with the following script:

extends Area2D

onready var shape=$Shape
var is_merging=false


func join(obj): # basically does self shape = overlap_obj shape + self shape
    ...


func merge_in(obj):
    if(is_merging):
        return
    
    if(obj.get_class()==self.get_class()):
        if(obj.is_merging):
            return
        
        is_merging=true
        obj.is_merging=true
        
        join(obj)
        
        is_merging=false
        obj.is_merging=false

        print("deleting=>",obj)
        obj.queue_free()


func _ready():
    self.connect("area_entered",self,"merge_in")
func get_class():
    return "Merger"

But whenever I place 2 instance of these on top of each other instead of merging they both get deleted:

enter image description here

Output on running:

deleting=>Merger:[Area2D:1269]
deleting=>Merger2:[Area2D:1272]

Also I'm trying not to use prioritybecause setting the priority of every instance would be a pain

I'm trying to make a water like object such that if 2 instance of them overlap they become a singular object,
So is something like this possible? or any similar approach that might yield the same results?

Upvotes: 1

Views: 478

Answers (1)

cak3_lover
cak3_lover

Reputation: 1958

Thanks to @hola and @Thearot in the comments I figured it out:

extends Area2D

onready var shape=$Shape
var is_merging=false


func join(obj): # Merges object shape into self shape
    ...


func merge_in(obj):
    if(is_merging):
        return
    
    if(obj.get_class()==self.get_class()):
        if(obj.is_merging):
            return
        
        is_merging=true
        obj.is_merging=true
        
        join(obj)
        
        is_merging=false

        print("deleting=>",obj)
        obj.queue_free()


func _ready():
    self.connect("area_entered",self,"merge_in")
func get_class():
    return "Merger"

or simply without having a check variable:

func merge_in(obj):
    if(self.is_queued_for_deletion()):
        return

    if(obj.get_class()==self.get_class()):
        join(obj)
        obj.queue_free()

Edit:

Turns out the actual "merging" rabbit hole was a bit deeper than I thought
and using is_merging variable won't cut it, So I made this small algorithm:

var prime:Array=[]

func merge_in(obj:Area2D):
    if(obj.get_class()!=self.get_class()):
        return

    if(self.prime):
        if(obj.prime): # 1 
            if(obj.prime[0]==self.prime[0]):
                return
            
            self.prime[0].join(obj.prime[0])
            obj.prime[0].queue_free()
            obj.prime[0]=self.prime[0]
        else: # 2
            obj.prime=self.prime
            self.prime[0].join(obj)
            obj.queue_free()
    
    else:
        if(obj.prime): # 3
            self.prime=obj.prime
            obj.prime[0].join(self)
            self.queue_free()
        else: # 4
            self.prime=[self]
            obj.prime=self.prime
            self.join(obj)
            obj.queue_free()

And this should merge any and all overalapping areas:

enter image description here

Hope this helps ;)

Upvotes: 1

Related Questions