Picking instances

Get help using Construct 2

Post » Tue Apr 02, 2013 12:05 am

Hey guys,

I have a problem with picking instances when I have the same type of objects in a particular event - a kind of "Sprite is overlapping Sprite". The problem is that I can't seem to be able to compare their instance variables. Here is a snapshot of my "code":

The only way that I could think of comparing the Team variable of the Fighter objects was through storing it in a local variable and then picking the second instance. However that doesn't work and I have no idea why. Can anyone shed some light on what I'm doing wrong?

Thank you.
Posts: 5
Reputation: 410

Post » Tue Apr 02, 2013 12:16 am

Fighter is overlapping Fighter
-> compare instance variable "team" <> "team"
->Set state to "attack"

This should set the initiating fighter sprite to "attack" as long as its "team" doesn't match the one its colliding into
Posts: 934
Reputation: 13,795

Post » Tue Apr 02, 2013 12:32 am

Well I've tried that, but it doesn't seem to work either. Here is a snapshot:

It seems that I am accessing the same instance and the condition is always false.
Posts: 5
Reputation: 410

Post » Tue Apr 02, 2013 6:07 am

You need yo put event where you pick instance 1 to same level with pick 0 event.
Posts: 756
Reputation: 7,292

Post » Tue Apr 02, 2013 8:51 am

Nope won't work.
You have to see the event like a filter or as I like to visualize it, a colander

Fighter Is overlapping Fighter will eliminate all Fighter objects that aren't overlapping at least one Fighter object other than itself.
Then Pick Fighter instance 0 will elimitate all other objects.
So Pick Fighter instance 1 afterward will just invalidate the event since it will return false (you don't have the instance 1 anymore in your colander).

So in short... you can't really use them like that in your situation.

However you can use the IID shortcut
You can do[code]Sprite(0).team != Sprite(1).team[/code]

So one way to achieve what you want to do is:
[code]+ Fighter: Is overlapping Fighter:
    // First we build a list of IID
    -> Array: Set size to (0,1,1)

    + System: Foreach Fighter
        -> Array: push back Fighter.IID on X axis

    // Then we need to pick all to be able to use the IID instead of the picked indexes
    + System: Pick all Fighter
    + System: Repeat Array.width times
        Local number A = 0 // IID of the first term of the comparaison
        -> System: Set A to Array.At(loopindex)

        + System: Repeat Array.width times
            Local number B = 0 // IID of the second term of the comparaison
            -> System: Set B to Array.At(loopindex)

            + System: A != B
            + System: Fighter(A).team != Fighter(B).team
            + System: distance(Fighter(A).X,Fighter(A).Y,Fighter(B).X,Fighter(B).Y) < Fighter.Width * sqrt(2)
            + System: Pick Fighter instance A
               -> Fighter: set State to "attack"
               -> System: Stop loop // here since we found a match we stop the inner most loop[/code]

Note that there's one little problem with this implementation:
I'm grouping all the Fighters that overlap with other fighters by building a list of IID in an array.
Then I make a team comparaison between all of them.
Which is wrong! Since you only want to check Fighters that overlaps each others. If you have two groups of fighter in two different area that overlap each other you would want to treat them separately.
To kind of adress this issue, I'm using a distance comparaison (in the last subevent)
But it's a bit imprecise. What you would want in fact, to be able to run the overlap check for each possible pair.

One way to do that is to use Family. You check for each Fighter if it overlaps a family containing the fighters. This way you can easily evaluate each pair.

Another way to do that is to handle collisions by yourself. An easy collision check algo is a circle collision. You just have to check if the distance between the object is lower than the sum of the radius of each object in the comparaison pair.

And still another way is to use two different object (let's call them col1 and col2) but with the same collision. You pair them together in the same container so they follow each other and you check overlap between col1 and col2 of each object. This way you can more easily isolate treat each overlap pair separately.
That's equivalent of using family in the principles

Anyway that's the gist of it (:
Yann2013-04-02 09:03:15
Posts: 1,482
Reputation: 16,457

Post » Tue Apr 02, 2013 2:22 pm

Thanks for the descriptive explanation Yann, I really appreciate it.

I would've used Families to solve my problem, but unfortunately I am currently using the free version of Construct 2 and that's not possible there.

I decided to go with your 3rd suggestion, which was to use my own collision and here is what I've come up with:

And I think that works pretty well. You can check what is the end result http://barnanimals.comoj.com/.

If you see anything wrong with my approach, please let me know.
Posts: 5
Reputation: 410

Post » Tue Apr 02, 2013 8:27 pm

(y) Yann
Posts: 568
Reputation: 5,079

Return to How do I....?

Who is online

Users browsing this forum: dokthor, JaredX, Monkin8r and 9 guests