Best practice when setting threshold values for rotations

Godot Version

4.2

Question

I’m making a top down shooter in 2D and I want to set the animation frame(and a bunch of other stuff) based on the rotation degrees. I’ve used if/elifs or used match previously for similar things but when I have to set a min and max threshold, they result in messy and difficult to manage code that looks like:

if rotation_degrees >= 0 and rotation_degrees <= 30:
    anim.set_frame(0)
    # Plus everything else I need to set
elif rotation_degrees > 30 and rotation_degrees <= 60:
    anim.set_frame(1)
   # etc

I have 10+ frames I’d like to map out for the entire 360 degree rotation and I have to imagine there’s a better and more manageable way. Doing it the way I’ve done it before is a pain to setup and a nightmare to change if I remove or add one frame since I have to change every threshold.

Appreciate any help!

Well technically it’s enough to do one check per line:

if rotation_degrees <= 30: # this will be 0 - 30 (provided rotation_degrees can't be a negative value)
    #do stuff
elif rotation_degrees <= 60: # this will be 31 - 60
    #do stuff
elif rotation_degrees <= 90: # this will be 61 - 90
    #do stuff
# etc...

Or you could do something like, I don’t know if it would work for you:

var number_of_frames = 10
for i in range(number_of_frames):
    if rotation_degrees <= (i + 1) * (360 / number_of_frames):
        anim.set_frame(i)
        break
1 Like

Huh, never thought of doing it with one line like that but I see now that the previous check would exclude the min while setting the max(or vice versa), making it more manageable.
The loop is very concise and that’s along the lines of how I thought it could be done. I’ll try both, thanks a lot!

1 Like

First you need to make sure rotation_degrees is between 0 and 360. If the frames are 30 degrees apart, you can simply get the frame like this without any if-statements.

rotation_degrees = fposmod(rotation_degrees, 360.0)
anim.set_frame( int(rotation_degrees * (12.0 / 360.0)) )

Alternatively, this can be written as

rotation = fposmod(rotation, TAU)
anim.set_frame( int(rotation * (12.0 / TAU)) )
2 Likes

That worked perfectly! Exactly as I had hoped and it’s so clean(not that Monday’s solution wasn’t). Thank you so much!
In case anyone in the future want to know how it can be implemented:

RS_Angle = RS_Vec.angle()
rotation = RS_Angle
rotation_degrees = fposmod(rotation_degrees, 360.0)
anim.set_frame( int(rotation_degrees * (12.0 / 360.0)) )
1 Like