[Solved] How to animate arch path of thrown object?

Started by isatche, Tue 08/09/2020 13:46:59

Previous topic - Next topic

isatche

 :-D Hello,

I would like my character to throw something and that something to be animated to follow arch path. Fly up away from player and fall down.
Is there a simple way to animate an object like that?

Thank you!

Snarky

The best way is probably to adjust the object's (let's say it's a ball) x/y coordinates directly in repeatedly_execute(), using a simple motion vector and force equation.

You could define the motion vector as two variables: dx and dy. Each game loop, you change the object coordinates by the motion vector:

Code: ags
bool ballBeingThrown;
int dx, dy;

function repeatedly_execute()
{
  if(ballBeingThrown)
  {
    oBall.X = oBall.X + dx;
    oBall.Y = oBall.Y + dy;
  }
}


When the character throws the ball, you set the direction and turn on the throw:

Code: ags
// This is the function for the player triggering the throw
function hTarget_AnyClick()
{
  dx = 5;
  dy = -8;
  ballBeingThrown = true;
}


Now the ball is thrown upwards and to the right. Right now it just continues in a straight line forever, though.

To add gravity (or any other force acting on the motion), you need to adjust the motion vector each game loop. In this case, we make gravity a constant downward force by adding a constant to dy. Let's also make it stop once it hits some limits. Updated version:

Code: ags
bool ballBeingThrown;
int dx, dy;

function repeatedly_execute()
{
  if(ballBeingThrown)
  {
    dy = dy + 2;
    oBall.X = oBall.X + dx;
    oBall.Y = oBall.Y + dy;

    // Ball hits the wall or floor 
    if(oBall.X > 200 || oBall.Y > 160)
      ballBeingThrown = false;
  }
}


We're ignoring air resistance and stuff like that, but it's not too difficult to add. You can also make the ball bounce, roll, etc. fairly easily.

isatche

#2
Thank you!
This worked perfectly!

I have to note that for some reason it didn't want to work when I used repeatedly_execute, but it started working when I changed it to repeatedly_execute_always.
Maybe it's just some mess I made earlier?
Thanks again!

Khris

The difference between the two is that rep_ex only runs while the game isn't blocked, so it depends on the situation in which you set the bool to true.

isatche

While on topic,
how do I slow down the animation?
It works great, but it's too fast.
What can I add to repeatedly_execute so it executes a but slower?

Thank you!

Khris

You could change the game's speed during the throw:

Code: ags
  SetGameSpeed(24); // default is 40


Snarky

Glad it worked!

Slowing down the game speed is an interesting approach, but it may have a lot of side effects (including worse responsiveness and jerkier animation, and it also affects any other animations running at the same time). You could also make it move at half the speed by only updating the position every second game loop, but still at the cost of jerkier animation.

In general, I think it would be better to simply make the values of dx, dy and "gravity" (which is set to 2 pixels/loop^2 in the current example) smaller. But once the numbers get small, it starts to get hard to adjust them precisely using integers. In that case, you would have to switch to floats for both the acceleration, motion vector and position coordinates, and then round off the position to the nearest int when actually placing the object.

Crimson Wizard

Quote from: Snarky on Fri 11/09/2020 21:09:54
In general, I think it would be better to simply make the values of dx, dy and "gravity" (which is set to 2 pixels/loop^2 in the current example) smaller. But once the numbers get small, it starts to get hard to adjust them precisely using integers. In that case, you would have to switch to floats for both the acceleration, motion vector and position coordinates, and then round off the position to the nearest int when actually placing the object.

I too think it's best to just use floats, and only convert to integer coordinates when you position object on screen.

SetGameSpeed changes FPS, which means that the game get redrawn less often, and tracks player input less often (can miss short presses/clicks), and of course everything else also start running slower.

Khris

I'm assuming this is during a cutscene, that's why I suggested lowering the speed: nothing else will be affected.

My initial thought was also to move to floats and reduce the values, however I'm pretty sure that won't work as expected (at least not that easy); lowering the values will change the flight path unless you also change the gravity, which would make the ball more "floaty".

SMF spam blocked by CleanTalk