# Question about functions.

Get help using Construct 2

### » Fri Jul 24, 2015 10:19 am

I use functions quite frequently to do some stuff in game. But they only trigger once. How do I use / or is it possible to use functions to make something happen during a specified amount of time. Like a slow fade in of an object? I don't have C2 in front of me at the moment, so just theory crafting. Would something like this work?

On "function"
Every 0.1 seconds
Opacity < 100 - add 1 to Opacity.

Or use while? or something similar?
Follow my progress on Twitter
or in this thread Archer Devlog
B
35
S
15
G
17
Posts: 944
Reputation: 12,210

### » Fri Jul 24, 2015 11:09 am

One option, though it can get tricky, is to have the function conditionally call itself after a short delay.

On "fade_in":
--- IF opacity < 100:
--- --- Add 1 to opacity.
--- --- Wait 0.5 seconds.
--- --- Call function "fade_in"

When the function is first called, it will do nothing if the opacity is 100, but if opacity is less than 100, it will increase the opacity by 1, and queue itself to be called again in half a second.

This situation, where a function calls itself, is called a "recursive" function call, or just "recursion".
This can be a really handy way of doing things, but just as you need to be careful with loops, to avoid infinite loop bugs, you also need to be careful with recursive function calls, to avoid infinite recursion. If you get an infinite recursion problem, you'll usually get an error message mentioning something along the lines of "Maximum call stack size exceeded".

This isn't the only way to get functions to act repeatedly over time, but it is one that can be pretty useful in the right situations.

Hope that helps out
B
26
S
17
G
8
Posts: 323
Reputation: 6,021

### » Fri Jul 24, 2015 11:49 am

Ahhhh thanks a lot! Just what i Needed! I have a few cases where this might be useful. Didn't think about calling the function itself at the end

Keeps things tidy, and limits the amount of listeners and Top level events, so i guess quite good for optimisation purposes as well.

Easily controllable with function params as well so very flexible. Thanks a lot!

On "fade_in":
--- IF opacity < 100:
--- --- Add function.Param(0) to opacity.
--- --- Wait function.Param(1) seconds.
--- --- Call function "fade_in" function.Param(0),function.Param(1)

Perfect!
Follow my progress on Twitter
or in this thread Archer Devlog
B
35
S
15
G
17
Posts: 944
Reputation: 12,210

### » Fri Jul 24, 2015 1:18 pm

Be careful. This is called recursion, which can break if you recurse too many times. You'd be better served in this example by using the Timer behaviour and using a function to set up the call with a zero period to start the timer code which does all of the fading. ( I have an example, but I can't upload to my own site at the moment. I'll update as soon as I can.)

Edit: https://www.dropbox.com/s/o2bshwcck53dw ... .capx?dl=0
B
71
S
21
G
220
Posts: 3,648
Reputation: 123,725

### » Fri Jul 24, 2015 2:41 pm

@blackhornet I see what you mean, but then i have to put a timer on every object i want to fade, and copy the events for every object i want to fade, and also you can't put behaviours on layers in case i want to fade a whole layer. Or you have to do a workaround to create a "hidden" object instance with a timer for things you want to fade.
Follow my progress on Twitter
or in this thread Archer Devlog
B
35
S
15
G
17
Posts: 944
Reputation: 12,210

### » Fri Jul 24, 2015 2:44 pm

You can use Families to give all Sprites the fade behaviour, and you'd need a different function for layers anyway. The point is you do not want to a call a function recursively if you can avoid it, and you can.
B
71
S
21
G
220
Posts: 3,648
Reputation: 123,725

### » Fri Jul 24, 2015 3:49 pm

I agree with blackhornet, the maximum call stack can be easily reached if you having multiple objects fading simultaneously with tiny increment in opacity.
B
67
S
28
G
24
Posts: 970
Reputation: 18,675

### » Tue Aug 04, 2015 3:15 pm

Hey again @tunepunk,

As @Blackhornet and @Magistross mentioned, recursion is likely not what you want for this situation.

I gave my example in terms of the opacity scenario you mentioned only for illustrative purposes, I wouldn't recommend actually using recursion to handle opacity.

My fault, I misunderstood.
I understood you were interested in having a function act in a self-contained manner over time, but I didn't realize you were interested specifically in controlling opacity.

As Magistross mentions, with too much recursion you can run out of call stack space. This is what I meant in my first post when I mentioned the "Maximum call stack size exceeded" error.

Triggering smooth transitions
To trigger a smooth change over time, you can use an extra instance variable to store the desired target value, (such as "100" for opacity), and then every tick, move the actual opacity value towards that target value by an increment, (such as 2).

So if you have a sprite that starts with 0 opacity, and the target is set to 0 as well, the sprite stays at 0 opacity.
If you then set the target value to 100, the sprite's opacity will start counting up to 100, at a rate of 2 per tick.

As Blackhornet mentioned you can use families to make it easier to get this behavior to work across a variety of similar objects.

Layers, Sprites, & Families
A single family will only work on a set of objects that all belong to the same plugin type, such as Sprite.
To get a family that affects sprites to affect layers, you can create a sprite object called "layerTool" (or whatever you want) and put a layerTool object on each layer you wish to control. Set the "Visibility" of the layerTool objects to 0 and then create events for them that set their corresponding layers to match their opacity every tick.

Now you should be able to control layer opacity with the same family events that control sprite opacity.
B
26
S
17
G
8
Posts: 323
Reputation: 6,021

### » Tue Aug 04, 2015 3:55 pm

You could also use the Litetween behavior

on function "fade in"
sprite set target value "opacity" 100
sprite start litetween

it will animate till it reaches 100 based on its property settings (eg: lerp, duration etc)

litetween allows you to specify a "value" as well that be used for anything that needs to change over time.

So you can say something like , set sprite.width to Sprite.LiteTween.Value to use in in circumstances beyond just the litetween basic properties as well
B
83
S
39
G
15
Posts: 984
Reputation: 16,741

Return to How do I....?

### Who is online

Users browsing this forum: No registered users and 13 guests