• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Is it a normal thing when your image_index has decimal places?

K

krugen

Guest
I imported a gif. I altered its image speed for different segment of the gif. And my image_index has decimal points after a few loops. It this normal?

So let's say I stop the animation by checking the image_index and let's say the last frame is 9

if image_index == 9
{
image_speed = 0;
}

and the decimal would be something like 9.23

and I use image_index >= 9 instead and it still works but is this a normal thing?
 
Very normal (and very useful).
Yes. To add an explanation to why it's useful:

If your image_speed is larger than 0 but smaller than 1, you can display a frame of animation for longer than an ingame frame. Very useful if you're using a higher framerate like 60FPS or 144FPS but want to have a normal animation framerate such as 24FPS. You would then set image_speed to [desired animation framerate] / [game framerate]. This usually produces a non-integer value. GameMaker rounds down the number and displays that frame. This means an image_index of 9.23 would display frame 9.
 

Joe Ellis

Member
Oh yeah, if you think of the image_speed, always being a decimal, you can determine exactly when frames switch and things should happen, it's made like that on purpose

With your problem if you ever want to ask what frame the instance is currently on, just floor(image_index) cus that rounds it down ei gets rid of the decimals, and says what the actual frame is being displayed
 
S

syscall

Guest
(I read the first two comments, and I don't really understand why do you talk about image_speed when OP is asking about decimals in image_index.)

So: How come image_index appear to have decimals?

I think it is to do with rounding error (precision loss), a common issue with "real number" (double-precision floating-point number, 8 bytes, a.k.a. double) in computing, apparently in GML, every number you have in GML code is a double (real number).
To help illustrate it for you:
Code:
// 90 * 0.1 = 9.0? Right? or not...
repeat (90)
{
    image_index = image_index + 0.1;
}
show_message(string_format(image_index, 32, 32));
More info:
Using the == operator to compare floating-point numbers is, generally, a bad idea. The problem arises from the fact that, typically, results of calculations have to be ‘fitted’ into floating-point representation, which does not always match the perceived reality of what result should be produced.
What you could do is use the "floor" function in GML, to round the number down (ignoring decimals), this will give you the integer part of the real number (as Joe Ellis said above).
Or, you could do something a bit clever:
Code:
#macro Epsilon 0.1 // TODO: Set this to a double whose hex representation is 0x1 on little-endian machine! (4.9406564584124654E-324)
if (abs(image_index - 9) < Epsilon) // "image_index == 9"
{
    image_speed = 0;
    show_message("Condition was true; image speed has been set to 0");
}
else
{
    show_message("Condition was false; image speed not modified");
}
Epsilon is your tolerance value, a minimum difference before a pair of real numbers are considered to be equal.
I am still newish in GM, so I don't know how do you define complex number in GML... But, there you go.

Also, remember, the "string" function will round down the number to the nearest 2 decimals, so if you show_message such number, you will get stuff like "9.23" in your case because as explained above, a double rounding error.
Hopefully you learned something new from me.
 
Last edited by a moderator:
Top