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?
I was just helping a guy with that, how about this:
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:
[icode]bullet.velocity.setAngle(45).nor().scl(10);[/icode] should do the trick.
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.
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?
If velocity starts at (or is ever) (0, 0), then yes, scl(rate) will do nothing. So a better setVelocity would be this:
public void setVelocity(float angle, float rate) {
/*
* Sets velocity to length <speed> at 0 degrees (flat along x-axis),
* then sets the angle (preserving the length of <speed>)
*/
this.angle = angle;
velocity.set(rate, 0).setAngle(angle);
}
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)