Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: bx83 on Sun 21/07/2019 09:12:04

Title: Float to Int error
Post by: bx83 on Sun 21/07/2019 09:12:04
mouse.x and mouse.y are integers (I assume)
oEPS.X and oEPS.Y (X and Y of bottom left corner of an Object) are integers (I assume)
EPS_Width and EPS_Height are floats.

Error I get is: [line 9] Type mismatch: cannot convert 'float' to 'int'
What is wrong (apart from hundreds float<->int conversions) with this code?

This is a basic programming question... but it's also driving me insane, so I had to ask.

PS. what I'm trying to do is say: 'if the mouse is in the area of an object's dimensions, 1 quarter in, please set the ThreeCowEmotions switch to true'.
If anyone has a quicker way of doing this, I'm all ears.


function room_load() {
    EPS_Width = IntToFloat(Game.SpriteWidth[oEPS.Graphic]);
    EPS_Height = IntToFloat(Game.SpriteHeight[oEPS.Graphic]);

...

function room_RepExec() {
    if (EmotionsSwitch) {
      if (mouse.x >= FloatToInt(oEPS.X + (EPS_Width/4))) {
        if (mouse.x =< FloatToInt((oEPS.X + EPS_Width) - (EPS_Width/4))) {
          if (mouse.y >= FloatToInt(oEPS.Y - (EPS_Height/4) ) - (EPS_Width/4)) {
            if (mouse.y =< FloatToInt((oEPS.Y - EPS_Height) - (EPS_Width/4))) {
              Display("cowemotions true at %d, %d", oEPS.X, oEPS.Y);
              ThreeCowEmotions=true;
              EmotionsSwitch=false;
            }
          }
        }
      }
    }
Title: Re: Float to Int error
Post by: eri0o on Sun 21/07/2019 11:18:18
The mouse is just 1 pixel position, what do you mean by 1/4 in? What is oEPS? Is it an object? Object have x and y as integers. Probably missing IntToFloat (oEPS.x) ?
Title: Re: Float to Int error
Post by: Matti on Sun 21/07/2019 11:26:07
You need one float value after FloatToInt, right now you have a float and an integer value there.
So instead of
Code (ags) Select
FloatToInt(oEPS.X + (EPS_Width/4)
it should be
Code (ags) Select
oEPS.X + FloatToInt(EPS_Width/4)

I don't really get why you want to use floats anyway, what is the purpose? Like eri0o just wrote: The mouse can't have a position between two pixels, it's just one exact pixel position.
Also, I don't get why you bring in EPS_Width in lines 11 and 12, shouldn't you only check for EPS_Height there?

If I'm not mistaken about what you're trying to accomplish, then this should work:

Code (ags) Select

    if (EmotionsSwitch) {
      if (mouse.x >= oEPS.X + oEPS.Width/4) {
        if (mouse.x <= oEPS.X + oEPS.Width - oEPS.Width/4) {
          if (mouse.y >= oEPS.Y - oEPS.Height + oEPS.Height/4) {
            if (mouse.y <= oEPS.Y - oEPS.Width/4) {
              Display("cowemotions true at %d, %d", oEPS.X, oEPS.Y);
              ThreeCowEmotions=true;
              EmotionsSwitch=false;
            }
          }
        }
      }
    }


EDIT:

In my understanding what bx83 is trying to achieve is this: There's an object (green) and something should happen when the players clicks the middle part of it (yellow, 1/4 height and width from the sides):

[imgzoom]http://ags.pics/D6rj.png[/imgzoom]
Title: Re: Float to Int error
Post by: bx83 on Sun 21/07/2019 13:28:04
That was exactly what I was doing.

Finished code (with no floats, got confused):



    if (EmotionsSwitch) {
      if ( (mouse.x >= (oEPS.X + (EPS_Width/4))) && mouse.x <= ((oEPS.X + EPS_Width) - (EPS_Width/4)) ) {
        if ( (mouse.y >= ((oEPS.Y - EPS_Height) + (EPS_Height/4))) && (mouse.y <= (oEPS.Y - (EPS_Height/4))) ) {
            Display("cowemotions true at %d, %d", mouse.x, mouse.y);
            ThreeCowEmotions=true;
            EmotionSwitch=false;
        }
      }
    }

Title: Re: Float to Int error
Post by: Khris on Sun 21/07/2019 21:26:16
Just for reference,
if (mouse.x >= FloatToInt(oEPS.X + (EPS_Width/4))) {
should've been:
if (mouse.x >= FloatToInt(IntToFloat(oEPS.X) + (EPS_Width/4.0))) {
Title: Re: Float to Int error
Post by: Laura Hunt on Mon 22/07/2019 08:02:21
Quote from: Khris on Sun 21/07/2019 21:26:16
FloatToInt(IntToFloat(oEPS.X)


(https://i.imgur.com/qcEFs0a.gif)
Title: Re: Float to Int error
Post by: Gilbert on Mon 22/07/2019 11:58:19
Yes. It may look silly, but you have to make sure the types of the variables match when performing arithmetics. One purpose of this is to avoid bugs/errors/quirks/desserts caused by ambiguity.
Just take the 'EPS_Width/4' part as an example. If EPS_Width is supposed to be a float it would be ambiguous on whether this is an integer division (with result truncated to an integer) or a decimal division, as the number 4 is an integer, which may bring huge difference in your calculations depending on what you are doing (and will be very hard to debug). So, if you just want (a) integer division on that one, just change EPS_Width to integer before the division 'FloatToInt(EPS_Width)/4', or if you want (b) a decimal division you need to use instead 'EPS_Width/4.0' as the number 4.0 is a float (OR if you want to do it the evil way, 'EPS_Width/IntToFloat(4)' :=), or, if you want to (c) perform decimal division and then truncate or round the number into an integer you have to use 'FloatToInt(EPS_Width/4.0, eRoundDown)' or 'FloatToInt(EPS_Width/4.0, eRoundNearest)', etc.

Confused? Let's illustrate this with an example, say, EPS_Width = 6.4, then the results of the above cases are as follows:
(a)  FloatToInt(EPS_Width)/4 = FloatToInt(6.4)/4 = 6/4 = 1    (6/4 = 1.5, but in integer division the result is truncated to an integer)
(b)  EPS_Width/4.0 = 6.4/4.0 = 1.6
(c)  FloatToInt(EPS_Width/4.0, eRoundDown) = FloatToInt(6.4/4.0, eRoundDown) = FloatToInt(1.6, eRoundDown) = 1
and FloatToInt(6.4/4.0, eRoundNearest) = FloatToInt(1.6, eRoundNearest) = 2
Title: Re: Float to Int error
Post by: Laura Hunt on Mon 22/07/2019 12:07:02
Quote from: Gilbert on Mon 22/07/2019 11:58:19
Yes. It may look silly, but you have to make sure the types of the variables match when performing arithmetics. One purpose of this is to avoid bugs/errors/quirks/desserts caused by ambiguity.
Just take the 'EPS_Width/4' part as an example. If EPS_Width is supposed to be a float it would be ambiguous on whether this is an integer division (with result truncated to an integer) or a decimal division, as the number 4 is an integer, which may bring huge difference in your calculations depending on what you are doing (and will be very hard to debug). So, if you just want (a) integer division on that one, just change EPS_Width to integer before the division 'FloatToInt(EPS_Width)/4', or if you want (b) a decimal division you need to use instead 'EPS_Width/4.0' as the number 4.0 is a float (OR if you want to do it the evil way, 'EPS_Width/IntToFloat(4)' :=), or, if you want to (c) perform decimal division and then truncate or round the number into an integer you have to use 'FloatToInt(EPS_Width/4.0, eRoundDown)' or 'FloatToInt(EPS_Width/4.0, eRoundNearest)', etc.

Confused? Let's illustrate this with an example, say, EPS_Width = 6.4, then the results of the above cases are as follows:
(a)  FloatToInt(EPS_Width)/4 = FloatToInt(6.4)/4 = 6/4 = 1    (6/4 = 1.5, but in integer division the result is truncated to an integer)
(b)  EPS_Width/4.0 = 6.4/4.0 = 1.6
(c)  FloatToInt(EPS_Width/4.0, eRoundDown) = FloatToInt(6.4/4.0, eRoundDown) = FloatToInt(1.6, eRoundDown) = 1
and FloatToInt(6.4/4.0, eRoundNearest) = FloatToInt(1.6, eRoundNearest) = 2

That's so cool, thanks SO MUCH for the explanation!  ;-D

(Not to mention that I'm an idiot and I thought that the conversion integer - float - integer was being applied only to oEPS.X so of course I was like "...why" but obviously it's not, I just missed a bracket. Still, what a fantastic explanation, thanks again.)
Title: Re: Float to Int error
Post by: Snarky on Mon 22/07/2019 14:28:32
All well and good, but it doesn't change the fact that instead of:

Quote from: Khris on Sun 21/07/2019 21:26:16
if (mouse.x >= FloatToInt(IntToFloat(oEPS.X) + (EPS_Width/4.0))) {

Khris's code could more concisely (and efficiently) be written as:

if (mouse.x >= oEPS.X + FloatToInt(EPS_Width)/4) {


Since there is only one term that could have a decimal part, and that gets truncated when you do the FloatToInt() anyway (which uses eRoundDown by default), there's no reason to do the whole operation in float.