Distinguish between two different instances of the same object

How do I distinguish between two different instances of the same object with GDevelop visual language?

Here’s my simple scenario: I’ve got several instances of sprites of the same class, let’s call this class Card.

When I drag and drop one card on top of another, I want to run a different action on each card.

With JavaScript, it’s super easy to use different variables, say selected_card and other_card, then compute their distance, then run selected_card.action1() and other_card.action2()

How can you do the same in visual language? We need something like an alias to rename some cards because otherwise, you’ll compute the distance between Card and Card and you don’t know which one is which.

Thanks for enlightening me! :slight_smile:

You could change z order of dragged card to something higher while card that is already put down would have something lower

Other than that we mostly use instance variables

Thank you very much for your answer. First, z ordering cards is not my issue here, I’m asking on a more conceptual level and used cards as an example.

My question is how to compare two objects of the same class. For instance, how can you compute the distance between two objects of the same class? Let’s use Card as an example class but it could be anything.

I could set an instance variable like an ID or any other criteria to filter the first instance, and the visual language will call instance Card. But how can I then select another Card and compare the distance between them? As both are called Card this seems to be that it can’t be done as the second instance overrides the previous Card.

Again, I can do this very easily with JavaScript. I’m just wondering about the no code solution: I don’t see any way to store an instance of an object in a variable, or in an array… Everything seems to be generalized by referring to the whole Class. Only exception being when you dynamically create an object.

I hope it makes more sense. Maybe the way I think can’t simply be done with the visual language, as I suspect.

Thank you for your time! :slight_smile:

Teach me JS and i will teach you how to think outside of box

You fail to to grasp concept of tools you have at your disposal
Z order i mentioned was not to give them proper z order
But use as means to control what happens to which card

Look
Imagine you fire a bullet
You want to make each enemy get hitted bullet but not spam damage so you want to create cooldown
So you could make timer or variable
I say fak both
I do not need to create something new when i can use what i already have

Condition
Enemy opacity = 255 (which is max)
Enemy in collision with bullet
NO TRIGGER ONCE NEEDED (so can be used in repeat for each)

Action
Change enemy opacity set to 254

Do you believe you will be able to even notice that opacity change?

Now

Condition
Enemy opacity = 254
Trigger once

Action
Change hp of enemy subtract 10
Wait 0.5sec
Change enemy opacity set to 255

And you just made invincibility frame for enemy
Out of opacity imagine that

So now that you understand basic concept

Let’s go with something as stupid as the above
This is example how to chain bullet attack

So imagine thunder
After thunder zap one enemy it finds next nearest enemy and zap him next

Have you ever seen such BS?
image

S stands for start and E for end i could shove in there Z X or A B
This is only there for me to tell apart where is start and end of each variable added to the list

Where i could limit it to just 1 but i was too lazy

Idea is If i add ID to string like imagine enemy 1 had ID 24
Enemy 2 had ID 41
We get 2441
Or 4124
But for now let’s assume only 2441
What i f i also have enemy with ID 1 and 2?

I proper order it would look like 224411
Can you tell in that string which number or sequence of numbers are for each object?
No?
How about now?
S2ES24ES41ES1E

Still no?
How about now?
S2E S24E S41E S1E

Now you see what i did?

I simply created string for each ball adding each ID var to that string with S on start and E on end
And now they can be read as separate numbers
Think of it as pointers in text i use to mark something

Now imagine (Back to your issue) you do same stupid crap with your objects
Give them ID vars
Now you have scene var
Object A is in Collision with object A
You add their ID vars to scene var with “S”+Object.ID+“E”

Now you can go with
https://wiki.gdevelop.io/gdevelop5/all-features/expressions-reference/#text-manipulation

StrFind(E) and StrFindLast(S)
To find end of 1st ID var and beginning of 2nd id var
Now you can set to another 4 scene vars position of object with ID var 1 and position of object with ID var 2
And now you have 4 vars which allow you to check distance or do whatever you want

Problem will start with more than 2 of same objects will collide with each other
BUT that is also doable i believe but that would depend on what you want to do with them
And if we are talking at multiple objects colliding with each other or pair but multiple pairs collision but at the same time

From here it will VERY VERY vary on what exactly you want to do and why

Dealing with multiple instances of the same object are one of the most annoying parts of GD. I agree, it should be like in JavaScript. I’ve made that suggestion before. You should be able to use Card.X() or Card[0].X() similar to an array.

I would suggest that everyone either make a suggestion or add likes and comments to existing suggestions.

There isn’t 1 workaround. Each situation is different.

You could add a Javascript event. Javascript works best in an extension. You could create a condition, expression, behavior or even a custom object. It might be a hassle but then you would have an extension that you could reuse or better yet submit as a community extension. Or maybe you could find an extension that’s similar like the object picking and suggest that the functionality be added to it. The object picking extension might help you. Either as is or as a template.

If you were dragging an object with the drag behavior. You could use the just dropped condition to save the X and Y into variables. You could then use the variables to check the distance or any other value.

This would pick the nearest object ignoring the object that was just dropped. I rotated the other object just to test it. You could then check the distance between the currently picked object and X, Y (you could also use collision or a rat cast or other condition)

You could replace the dropped object with another object and then you would have a draggedCard and a Card. You could then check which card the draggedCard was in collision with.

There are infinite other ways. Some might be easier. Each situation has its own solution.

1 Like

Thank you both for your time, explanations and examples. Indeed, either using attributes or variables can help. @Keith_1357 's suggestion of being able to use Card[0].X() is the closest to my opinion and their solution matches what I had in mind. Now I better see how I could implement this using various techniques.

I will stick to Javascript for the time being as things are much simpler. For the record, if anyone in the future is interested by my solution, here’s how I did it, assuming that card is passed to the JavaScript function:

// If both cards are close enough, destroy them. 
let card = objects[0];
let other_cards = runtimeScene.getObjects("card");
for (let other_card of other_cards) {
    if (card === other_card) continue;
    let distance = card.getDistanceToObject(other_card);
    if (distance < 10) {
        // Cards match is they have the same animation in my scenario
        // Combining both distance and animation conditions with an && operator didn't work though so I've separated them
        if (card.getAnimation() == other_card.getAnimation()) {    
            // Destroy both cards
            runtimeScene.markObjectForDeletion(card);
            runtimeScene.markObjectForDeletion(other_card);
            break; //Don't destroy more than two cards.
        }
    }
}

Thank you!

1 Like