Java-Gaming.org Hi !
 Featured games (91) games approved by the League of Dukes Games in Showcase (804) Games in Android Showcase (237) games submitted by our members Games in WIP (867) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 [libgdx] Moving a sprite at a changing angle  (Read 5658 times) 0 Members and 1 Guest are viewing this topic.
opilkin

Senior Newbie

 « Posted 2014-06-02 22:37:31 »

I've managed to move my sprites from point A to point B thanks to the universal tween engine.
However, I want sprites to move at a constant speed, without a specific end value. This is something the tween engine can't do (to the best of my knowledge). Moreover, I want to continuously change the angle at which the sprite is travelling. I plan on using the tween engine for angle interpolation because I will have an end value for this property.
So far all I could think of was doing some math and then constantly update my sprites' X and Y coords. I'm also reading up on Matrix3 class to see if it could be of use.

I'm working with many 2D sprites that I want to move differently in various directions. What's the best way to go about achieving this?

Any help is welcome.
Thanks!
BurntPizza

« JGO Bitwise Duke »

Medals: 486
Exp: 7 years

 « Reply #1 - Posted 2014-06-03 02:17:40 »

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17 `class Bullet extends Sprite { // as an example      Vector2 velocity; // initialized elsewhere   public void update(float delta) {      /*      Do any stuff with velocity like Euler integration etc here      */      Vector2 vdt = velocity.cpy().scl(delta);      translate(vdt.x, vdt.y);      setOriginCenter();      setRotation(velocity.angle());   }}`

In render() you draw it with sprite.draw(batch);
Rotation and everything is handled internally.

Just change the velocity and the sprite will change direction it's moving.

For instance, to have the "bullet" move at a 45 degree angle upwards at 10 units/sec:

 `bullet.velocity.setAngle(45).nor().scl(10);`
should do the trick.

You could easily tween the setAngle().
opilkin

Senior Newbie

 « Reply #2 - Posted 2014-06-03 20:31:26 »

Very cool! Thanks. I'm gonna be playing around with this. Didn't think to check the Vector2 class implementation.
opilkin

Senior Newbie

 « Reply #3 - Posted 2014-06-04 23:00:04 »

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17 `class Bullet extends Sprite { // as an example      Vector2 velocity; // initialized elsewhere   public void update(float delta) {      /*      Do any stuff with velocity like Euler integration etc here      */      Vector2 vdt = velocity.cpy().scl(delta);      translate(vdt.x, vdt.y);      setOriginCenter();      setRotation(velocity.angle());   }}`

In render() you draw it with sprite.draw(batch);
Rotation and everything is handled internally.

Just change the velocity and the sprite will change direction it's moving.

For instance, to have the "bullet" move at a 45 degree angle upwards at 10 units/sec:

 `bullet.velocity.setAngle(45).nor().scl(10);`
should do the trick.

You could easily tween the setAngle().

I got a little lost. Would've been easier to grasp this if I was paying attention in my high school math class, years ago

Here's my train of thought:
Velocity is initialized without any values. It is then continuously assigned an angle by the tween engine (up to 45). This specifies the direction of the vector (right?). I logged the velocity at this point, and its x,y values were growing fast and far. So normalizing should help here. However, after normalizing velocity, the x,y values were just 0s. Assuming it would have worked correctly, all that was left is to multiply by the rate; rate is also assigned by the tween engine (up to 10). The last step didn't do anything to the velocity x,y fields because obviously they were 0s after normalization.
Finally we copy the velocity vector into some temp(vdt?) vector and multiply it by delta. Then translate the sprite by the temp vector's coords.

Do I understand everything correctly so far?

Now, the structure of my code is a little different. I don't have everything stuffed into my update method.
I perform the angle and rate changes in one separate method. In that same method I perform the velocity calculation. This method is used by the tween engine which of course gets updated in the update method.

 1  2  3 `public void setVelocity(float angle, float rate) {      this.angle = angle;      velocity.setAngle(angle).nor().scl(rate);`

The translation happens in the update method.

 1  2  3  4  5  6 `public boolean update(float delta) {      vdt = velocity.cpy().scl(delta);      translate(vdt.x, vdt.y);                //origin is set to the centre elsewhere, and I don't need the sprite to rotate, so I excluded those 2 lines                tween.update(delta);`

It's not working, but it's most likely because I don't understand something. Does what I wrote make sense?
BurntPizza

« JGO Bitwise Duke »

Medals: 486
Exp: 7 years

 « Reply #4 - Posted 2014-06-04 23:16:29 »

If velocity starts at (or is ever) (0, 0), then yes, scl(rate) will do nothing. So a better setVelocity would be this:

 1  2  3  4  5  6  7  8 `public void setVelocity(float angle, float rate) {      /*       * Sets velocity to length at 0 degrees (flat along x-axis),       * then sets the angle (preserving the length of )       */      this.angle = angle;      velocity.set(rate, 0).setAngle(angle);}`

The update is this:

Positionn+1 = Positionn + Velocityn * Î”Time

This is one of the parts of Euler integration and obviously that can be coded a myriad of ways.

My approach with Vector2 is to copy velocity (since we don't want to change the actual velocity) and scale (multiply) it by the delta, then add it to position (translate).
The temporary vector is not even necessary if you don't like it: (I'm actually not sure why I didn't do this originally)

 1  2 `translate(velocity.x * delta, velocity.y * delta);tween.update(delta);`

Also, if you're not rotating the sprite, then setOriginCenter() is also not needed.

EDIT: a primer on numeric integration such as this: http://gafferongames.com/game-physics/integration-basics/
opilkin

Senior Newbie

 « Reply #5 - Posted 2014-06-05 00:07:16 »

Wonderful, thank you! Now it works
Pages: [1]
 ignore  |  Print

 Riven (439 views) 2019-09-04 15:33:17 hadezbladez (5297 views) 2018-11-16 13:46:03 hadezbladez (2213 views) 2018-11-16 13:41:33 hadezbladez (5565 views) 2018-11-16 13:35:35 hadezbladez (1156 views) 2018-11-16 13:32:03 EgonOlsen (4592 views) 2018-06-10 19:43:48 EgonOlsen (5467 views) 2018-06-10 19:43:44 EgonOlsen (3128 views) 2018-06-10 19:43:20 DesertCoockie (4023 views) 2018-05-13 18:23:11 nelsongames (4741 views) 2018-04-24 18:15:36
 A NON-ideal modular configuration for Eclipse with JavaFXby philfrei2019-12-19 19:35:12Java Gaming Resourcesby philfrei2019-05-14 16:15:13Deployment and Packagingby philfrei2019-05-08 15:15:36Deployment and Packagingby philfrei2019-05-08 15:13:34Deployment and Packagingby philfrei2019-02-17 20:25:53Deployment and Packagingby mudlee2018-08-22 18:09:50Java Gaming Resourcesby gouessej2018-08-22 08:19:41Deployment and Packagingby gouessej2018-08-22 08:04:08
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org