Want to move object using while-loop and trig functions. IntToFloat problems....

Started by HAL, Sat 14/02/2015 09:46:32

Previous topic - Next topic

HAL

I'm having a go at learning to animate things using parametric functions of x and y, using trigonometric functions to gain smooth curves of movement.

I'm having problems all over the place, saying it either 'cannot convert Int to Float', or 'cannot convert Float to Int'.

I've tried all sorts of variations of Ints and Floats, but nothing works.

The key issue seems to be that the Sin and Cos functions need to take float values, but I then need to bring my results back to being Int values for the co-ordinates in the Move function.

As far as I can tell, my code should get around all this. But I guess I've gone wrong somewhere.

This current coding setup is failing on line 2, saying it can't convert Int to Float.
But why does it even think 'k' is an Int in the first place? :confused:
If I change 'k' to Int, it just pushes the problem further down to lines 8 and 9.
Mega confused here :undecided:

Code: ags

   int i = 0;
   float k = 0;
   float x1;
   float y1;
   
   while(i<100)
    {
     x1 = 40*Maths.Sin(k);
     y1 = 40*Maths.Cos(k);
     
     oBird.SetPosition(555+FloatToInt(x1, eRoundNearest), 489+FloatToInt(y1, eRoundNearest));
     k = k+1;
     i = i+1;
    }


If I remember correctly, this code should only result in the bird oscillating diagonally over a straight line anyway, which is a little pointless, however if I can get to grips with this then I can start playing around with more complex trig functions to move things in spirals etc.

Thanks for any help. :smiley:

Snarky

Try:

Code: ags
float k = 0.0;


and

Code: ags
x1 = 40.0*Maths.Sin(k);
y1 = 40.0*Maths.Sin(k)


Oh, and

Code: ags
k = k + 1.0;


The trick is that even when you type out the values, there's a difference between the integer version of a number and the floating point version. To show that you want the floating point version, type out the point-zero at the end.

However, adding floating point numbers together repeatedly leads to more and more rounding errors (they add up each time), so even though it probably won't make a big difference with k here (after 50 loops it might have a value of 50.004 or something), as a general strategy I would instead just set it at the top of the loop:

Code: ags
k = IntToFloat(i);


BTW, if I remember my trig correctly, I think this will make the bird move around in a circle.

HAL

That worked!

So I just need to make sure to add a decimal .0 after assigning float values.

Great stuff, thanks a lot. :grin:

However now have another problem.

I've applied the code to an object in a room. When I enter the room, instead of a smooth movement, the object just pings over to one position and then stays there. There's no smooth movement.

I presume it's because the script breaks early for some reason? Have I put the code in the wrong place?

Oh and I've done a quick check and yeah I think this trig function does produce a circular movement.

Here's the code for the room I'm using:

Code: ags

// room script file

function room_Load()
{
  player.SetWalkSpeed(4, 3);
  player.Walk(555, 444);  
  
}

function room_LeaveRight()
{ 
  player.ChangeRoom(42, 26, 440);
}


function room_AfterFadeIn()
{
   int i = 0;
   float k = 0.0;
   float x1;
   float y1;
   
   while(i<100)
    {
          
     x1 = 40.0*Maths.Sin(k);
     y1 = 40.0*Maths.Cos(k);
     
     oBird.SetPosition(345+FloatToInt(x1, eRoundNearest), 213+FloatToInt(y1, eRoundNearest));
     
     k = k+0.1;
     i = i+1;
    }
}


This is just a bit of a test, so I don't desire to see anything other than the bird moving in a circle.

I haven't used k = IntToFloat(i) because I want it to have its own increments of 0.1. That way it'll take a good 30 cycles to reach the value of Pi, so the trig functions progress slower.

Vincent

Quote from: HAL on Sat 14/02/2015 12:11:33
That worked!
So I just need to make sure to add a decimal .0 after assigning float values.

floating-point numbers

The idea is to compose a number of two main parts:

a) A significand that contains the number's digits. Negative significands represent negative numbers.

b) An exponent that says where the decimal (or binary) point is placed relative to the beginning of the significand.
Negative exponents represent numbers that are very small (i.e. close to zero).

Such a format satisfies all the requirements:

° It can represent numbers at wildly different magnitudes (limited by the length of the exponent)
° It provides the same relative accuracy at all magnitudes (limited by the length of the significand)
° It allows calculations across magnitudes: multiplying a very large and a very small number preserves the accuracy of both in the result.

Decimal floating-point numbers usually take the form of scientific notation with an explicit point always between the 1st and 2nd digits.


Snarky

Well, that's... not very relevant. The key idea here is that even literal values have a data type, and if you don't put a decimal point on a number, it's assumed to be an int.

Quote from: HAL on Sat 14/02/2015 12:11:33
I haven't used k = IntToFloat(i) because I want it to have its own increments of 0.1. That way it'll take a good 30 cycles to reach the value of Pi, so the trig functions progress slower.

OK, sure. Personally I would still calculate it from the value of i each turn, as "k=IntToFloat(i)*0.1;" but like I said it's probably not going to make a huge difference. It's just something to keep in mind, that doing iterative calculations on a float value can lead to the build-up of rounding errors over time.

Quote from: HAL on Sat 14/02/2015 12:11:33
I've applied the code to an object in a room. When I enter the room, instead of a smooth movement, the object just pings over to one position and then stays there. There's no smooth movement.

I presume it's because the script breaks early for some reason? Have I put the code in the wrong place?

No, the problem here is that the entire loop runs within a single game cycle, and then ends. So internally, the game calculates and sets the bird-coordinate, but then it loops again and sets it to some other value, over and over until the loop ends. Only at that point does it actually draw the frame, with the bird in the final position.

There are two ways to go about fixing this:

1) Put a "Wait(1);" command inside the loop. That means it will stop there, draw the frame, and only continue on the next game cycle. However, this will also stop other scripts from running, so it will effectively pause the game while the bird is circling.
2) If you want it to run in the background and not interfere with anything else, you'll have to put it in a repeatedly_execute() function, which automatically runs once every game cycle. The logic becomes a little different (you won't need the loop any more); let us know if you can't work it out.

HAL

Quote from: Snarky on Sat 14/02/2015 14:43:18


No, the problem here is that the entire loop runs within a single game cycle, and then ends. So internally, the game calculates and sets the bird-coordinate, but then it loops again and sets it to some other value, over and over until the loop ends. Only at that point does it actually draw the frame, with the bird in the final position.

There are two ways to go about fixing this:

1) Put a "Wait(1);" command inside the loop. That means it will stop there, draw the frame, and only continue on the next game cycle. However, this will also stop other scripts from running, so it will effectively pause the game while the bird is circling.
2) If you want it to run in the background and not interfere with anything else, you'll have to put it in a repeatedly_execute() function, which automatically runs once every game cycle. The logic becomes a little different (you won't need the loop any more); let us know if you can't work it out.

Fantastic. That did it.

I used option 1 as my aim was to use the animation in some kind of cut-scene event, so the game can pause, no problem.

I didn't realise the wait() command was anything more than just a thing that makes the game do nothing for X cycles. Living and learning.

I've seen mention of the repeatedly_execute() function a few times and I thought it might serve some purpose in a situation like this. If/when I come to want to have background animations or something, I'll be sure to look into it.

Thanks very much for the help, much appreciated! :smiley:

HAL

Seems like the repeatedly_execute function is more handy in this case actually.

Got it all figured too.

I now have a bird permanently flying around performing lissajous curves. How awesome, programming's pretty fun, heh :cool:

Can you tell I'm pretty new to this still.

Thanks again. :smiley:

SMF spam blocked by CleanTalk