Sprite Object variable change 'Trigger once' issue

Bugs will be moved here once resolved.

Post » Thu Mar 23, 2017 12:59 am

Problem Description
When trying to send a trigger to using variable change and 'Trigger once while true' method, I am unable to use actions to set variables, or use other plugins (eg Browser) to do other things within that trigger.

Attach a Capx
https://www.dropbox.com/s/06yqofly0lm9z ... .capx?dl=0

Description of Capx
The capx creates 3 circle Sprites (2 frames of animation). It creates a 'name' instance variable, and they are named 'a', 'b', and 'c'.

It also creates 2 box sprites which are 'touch triggers'. The left box sprite is trigger1, and the right is trigger2.

A Browser object is also used to debug, and this makes the bug more obvious.

These two triggers try to do the same thing: it switches the sprite's animation to frame 1. However, trigger1 won't work because of the method it tries to use, while trigger2 works, but is only done so for demonstration purposes, as it is not possible to achieve a certain behaviour using only the methods used in trigger2.

Steps to Reproduce Bug
  • Load the capx
  • Open up a Console to see the messages from the Browser object.
  • Click on the right green box (trigger2) first. Notice the change of the two blue circles to frame 1. This trigger also tries to display the name of the sprite via Browser console. However, the console only displays the first Sprite's name.
  • Restart the capx.
  • This time click on the left blue box (trigger1). Nothing happens. What trigger1 is trying to do is use System actions to and expressions to query the Sprite.X, and set the animation frame based on it. But this isn't happening.

Observed Result
System actions and commands, including the Browser object (and based on my main project, other plugins as well), don't seem to be evaluated correctly in the 'trigger context'. As the Browser console seems to point out, the evaluation of triggers seem to occur in a different timeframe that not all sprites are being registered as being triggered.

Expected Result
I expect that each sprite evaluates system expressions (even calls to functions) in the same way as normal triggers do.

Affected Browsers
  • Chrome: (YES)
  • FireFox: (YES)

Operating System and Service Pack
Windows 7 Pro SP1

Construct 2 Version ID
Release 241
B
41
S
12
G
1
Posts: 68
Reputation: 2,955

Post » Thu Mar 23, 2017 12:27 pm

I suppose that you with 'bug' refer to the bug that you created. Lets walk trough the events.

Events 2 sets the instance variable 'trigger' for all sprites to "trigger1" when that trigger is touched.
Events 4 sets the instance variable 'trigger' for all sprites to "trigger2" when that trigger is touched.

So far ok, and i expect intended.

Event 6 picks all sprites with instance variable 'trigger' set to "trigger1".
And due event 2, that are ALWAYS ALL sprites.
Now in event 7, you say: set sp to Sprite.X>100. That returns 1 or 0. Which is fine.
But you dont refine the picklist. So to which of all the picked sprites should Sprite.X refer to ?
Since you have a list of sprites, and you address only one of them, it usually picks the oldest sprite, but in reality this picking is rather arbitrary.
So in your case, this 'Sprite.X' refers to the sprite with index zero in the picklist, and that sprite sits at x=50.
The logical expression will therefor ALWAYS return zero, and as a consequence sp is ALWAYS zero.

The 'trigger once' works as expected.

The browser log has the same problem. All sprites are picked, which sprite should it log ?

The for each in event 2 and 4 are not needed. The Sprites are not picked. That makes them un-referenced, and that is the same as a 'pick all'. They get no personal values, so you can set the instance variable 'trigger' for all in one action, without the 'for each' loop.
B
33
S
18
G
28
Posts: 2,493
Reputation: 20,950

Post » Thu Mar 23, 2017 8:51 pm

99Instances2Go wrote:But you dont refine the picklist. So to which of all the picked sprites should Sprite.X refer to ?
...
The browser log has the same problem. All sprites are picked, which sprite should it log ?


Hi @99Instaces2Go, thanks for replying and clearing this up.

In regards to the SOL/picklist, my expected behaviour was that the trigger is sent to all sprites, but each sprite, on their own, will process the trigger individually. So, for triggers like Event # 6, I instinctively read that the Sprite object is the one that was triggered, and thus that is the picked Sprite for that trigger.

The for each in event 2 and 4 are not needed. The Sprites are not picked. That makes them un-referenced, and that is the same as a 'pick all'. They get no personal values, so you can set the instance variable 'trigger' for all in one action, without the 'for each' loop.


Yes, now that I know that the trigger is not contextualised for each instance that makes sense. However, the main reason for looping through instances was to (hopefully) trigger individual Sprites.

So what I'm learning from this is: 'Trigger once while true' doesn't pick the Sprites based on the moment of trigger (ie pick each Sprite which had been triggered indvidually). It's basically a 'pick all with a given set variable', so that I have to explicitly to a pick condition inside the trigger.

Thanks for very much for your time to open the scene up and examine. Much appreciated. :-)

(Note that I had experimented a bit more with other solutions, and I did come to use Rex's FSM to use as an individualised trigger. Rex's FSM is actually the kind of behaviour that I expected, because while you can send triggers to all instances, each instance processes the trigger on its own; it's automatically in its own context. But I think I will revise my events to use C2's trigger method as it saves me from doubling up on events.)
B
41
S
12
G
1
Posts: 68
Reputation: 2,955

Post » Thu Mar 23, 2017 9:58 pm

So what I'm learning from this is: 'Trigger once while true' doesn't pick the Sprites based on the moment of trigger (ie pick each Sprite which had been triggered indvidually).

Not sure if you understand the meaning and use of 'Trigger once while true'. (i write a lazy T1wt from now on)

T1wt is usually added to one or more conditions in an event, and usually as last condition.
It just makes an event that is continuously true run its actions only once.
It resets when the event is untrue.

Example in super pseudo code.

Say a condition like
If 1 = 1 ?
______actions

That is always true. And it will run its actions every tick, continuously, for ever and one day.

So ....
If 1 = 1 ?
Trigger once while true
______actions

Will run the actions only once and only once only. Since that condition can not ever be set untrue, well not unless Sabrina González Pasterski invents new math.

Or ... more of the same ...

Global variable 'score' = 10 (number)

if score = 10 ?
Trigger once while true
_________actions

This will run its actions only once when 'score' = 10, even if 'score' = 10 for the next 10 years.
But. If you set score to 9, the T1wt gets reset, and the next time you make 'score' again = 10, it will run its actions again only once. The value of 'score' can be changed and therefor the conditions can be made untrue/true.

General use.

Say you have an animation contain 10 frames. You set its animation speed to 10 frames/second.
And each time it shows frame 1, you want to play a little sound. Lets assume the game runs at 60 frames / second. That means that each animation frame sits there for 6 frames in a row, before going to the next frame.
In that case a condition 'animation frame' = 1 ? , will run 6 times in a row, stuttering that audio.

Solve this by using T1wt.

'animation frame' = 1
Trigger once while true
________________ play sound 'plok'

When the animation frame = 2, the condition is untrue, and from there it waits again to become true (=1), to run its action only once again.

Special case to use.

Trigger once while true
_____________________actions

This runs its action only once (used if you want to set up things only once). Since it is not paired up with a condition that can be made untrue again, it will effectively run only once during its lifetime. It is of course essential the same as

If 1 = 1 ?
Trigger once while true
______actions

And that makes the circle round again.
B
33
S
18
G
28
Posts: 2,493
Reputation: 20,950

Post » Tue Apr 18, 2017 4:23 pm

As far as I can tell, everything is working correctly. The project is a bit obfuscated though which makes it harder to understand. You could do the same with much simpler events.

faulknermano wrote:Click on the right green box (trigger2) first. Notice the change of the two blue circles to frame 1. This trigger also tries to display the name of the sprite via Browser console. However, the console only displays the first Sprite's name.

All three sprites meet the "trigger = trigger2" condition, so the event runs with them all picked. You log the name, and C2 arbitrarily picks the first one. Then you test which are to the right of X=50, two of them are, so those two change frame. Everything has worked correctly.

This time click on the left blue box (trigger1). Nothing happens. What trigger1 is trying to do is use System actions to and expressions to query the Sprite.X, and set the animation frame based on it. But this isn't happening.

Again, all three sprites meet the "trigger = trigger1" condition, so the event runs with them all picked. You log the name and the same thing happens as before, it just chooses the first one. Then in a sub-event you evaluate "Sprite.X > 100". Since Sprite.X must evaluate to a single number, C2 again arbitrarily picks the first one, which has an X of 50. Therefore it evalutes "50 > 100" and returns 0 for false. The next condition tests if the result was 1, which it isn't, so the event doesn't run.

None of this has anything to do with "Trigger once". I think you're just confused about what that condition does. A more accurate name for it might be "did this event not run last tick". That is pretty much all it does.
Scirra Founder
B
397
S
236
G
88
Posts: 24,417
Reputation: 194,538


Return to Closed bugs

Who is online

Users browsing this forum: No registered users and 2 guests