What for each does
For each will run a loop containing all of the conditions and actions after it for each instance of the object specified, picking only one of those instances each time.
for each sprite
- rotate 5 degrees
Let's assume there are 10 instances of a sprite for this tutorial. What happens here is Construct picks one of the sprites, forgets the others, then runs the actions. Since there are 10 sprites, the actions are performed 10 times, but since construct picks only one of the sprites each time, all of the sprites are only rotated 5 degrees.
The event above is an example of when NOT to use for each, because you would get the same effect as if you deleted the for each sprite condition, and it would be faster and more efficient as well because construct would rotate them all at once instead of one by one individually. Here's an example of when you would want to use for each.
for each sprite
- Create object "selectioncircle" at sprite.X, sprite.Y
In this example, construct will run the actions once for each sprite. This way construct creates a selection circle for each sprite, and since only one sprite is on the selected object list when it runs the loop, it also knows where to place the selection circle when using sprite.X and sprite.Y. The result is 10 selection circles created, each at a sprite's location.
If you did not use for each sprite in the example above, it would pick all of the sprites, create one selection circle and place it at one sprite.
How for each loops run
Construct not only runs the events for each sprite selected in the for each loop, but it also checks any conditions after the for each condition for each object. Here I show the number of times Construct runs each condition and action.
For each sprite - 1
if sprite is visible - 10
- actions - 10
In this example, construct checks if each sprite is visible one by one. This is less efficient than checking them all at once which construct does if you place the "if sprite is visible" condition before the for each condition like so.
if sprite is visible - 1
For each sprite - 1
- actions - 10
Another benefit of putting the if sprite is visible condition before the for each condition is it reduces the number of loops run by the for each condition to the minimum number required. If there are 5 visible sprites, then the event above would run this many times:
if sprite is visible - 1
For each sprite - 1
- actions - 5
For each is useful if you need to run the actions once each time for each object, but should not be used when you can do all of the actions at once.
Also note that any subevents of an event with a for each condition will be run for each instance of the for each loop.
For each is often unnecessary for setting instance values
Another example when not to use it:
for each sprite
- set sprite instance variable to sprite.x
If you're setting a instance variable, you generally don't need to use for each, even if the result will be different for each sprite. In the example above, even without the for each condition, setting the sprite's instance variable to sprite.x will result in each sprite having its instance variable set to its own x position.
Automatic placement of instances
In this example:
for each sprite
if selectioncircle value 'spriteuid' is equal to sprite.UID
- set selection circle position to sprite.X, sprite.Y
Construct will pick one sprite each loop, check all selection circles for if their private variable is set to the sprite's UID, then set the position of that selection circle. However, this is actually another example that may be unnecessary, as construct has another automatic loop that can come in handy.
If you have the action:
Set selectioncircle position to sprite.x, sprite.y
Construct, without a for each condition, will automatically place each instance of selectioncircle to another instance of sprite, instead of all of the instances of selectioncircle at one instance of sprite. This can be very useful for placing sprites that do not require a specific instance, such as health bars, shadows or selection rings.
In summary
For each will run all conditions, actions and subevents after it for the number of times equal to the number of instances picked, picking one of those instances each time.