Trying to shrink light source over time

Godot Version

v4.2.1.stable.official [b09f793f5]

Question

I just started learning programming and godot about a week ago.
I want to implement a light source which would shrink over time and then disappear.
First I tried to use a While loop for it, but results are not what I expected:
func _ready():
texture_scale = 15.0
while texture_scale > 0.0:
texture_scale -= 0.5
But with this code it wouldn’t function properly, not shrinking the light source, and the engine would spew out tons of errors: E 0:00:00:0621 intersects_transformed: Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.
<C++ Source> core/math/rect2.cpp:113 @ intersects_transformed()
If I just do texture_scale - 0.5 the app freezes completely

I also tried doing it under _process(delta) function with this code, using if nest:
texture_scale -= 0.5
if texture_scale < 0: #If code to not make it go below 0
texture_scale = 0
It seemed to work, but I don’t think its a right way to do it, plus i’m not sure I’m able to delete light source with this script afterwards.

Why can’t I use while loop on it?

The _ready function is called once when the scene enters the tree. If you put a while loop there, it will run until completion during the first frame. So what you’re doing is setting the texture_scale to 15.0, then immediately changing it to 14.5, then immediately changing it to 14.0, and so on.

Also, floating point precision is limited, which might lead to rounding errors that prevent the value from hitting exactly 0.0. If, for example, the variable would be 0.00000000001, then you will do another loop and push the scale into the (forbidden) negative territory.

If you put code in the _process function, it will run every frame (which, at 60 FPS is still pretty fast: your scale would reach zero after just half a second). Also, the way you do it, you should see errors, because you’re only fixing up the scale after it dips below 0.0. Checking if the scale is at least 0.5 before reducing it, is a better way of doing this:

func _process(delta):
    if texture_scale > 0.5:
        texture_scale -= 0.5
    else:
        # delete texture

You should also consider that _process will be run as often as possible, so the shrinking speed of your light source will vary depending on the hardware used to run the game and how many frames it can render each second. So it might be better to reduce the scale by delta (i.e. the portion of a second passed since rendering the last frame) instead of a static 0.5, you’re doing now. You can also multiply it to the existing value, in which case 0.5 represents the intended change in scale after one second:

func _process(delta):
    var decrement_for_this_frame := 0.5 * delta
    if texture_scale > decrement_for_this_frame:
        texture_scale -= decrement_for_this_frame
    else:
        # delete texture
1 Like