Reputation: 1235
I have the following rotation function:
public void rotate( Actor a ) {
float rotateBy = 30.0f,
newX = ( a.getX() * ( float ) Math.cos( rotateBy ) ) - ( a.getY() * ( float ) Math.sin( rotateBy ) ),
newY = ( a.getX() * ( float ) Math.sin( rotateBy ) ) + ( a.getY() * ( float ) Math.cos( rotateBy ) ),
moveByX = a.getX() - newX, // delta
moveByY = a.getY() - newY, // delta
duration = 1.0f; // 1 second
a.addAction(
Actions.sequence(
Actions.parallel(
Actions.rotateBy( rotateBy, duration ),
Actions.moveBy( moveByX, moveByY, duration )
)
)
);
}
But it seems the moveByX and moveByY values are not accurate.
The goal is to figure out what the new x,y would be after rotation, and move up by that much so that it still maintains the same y as before it was rotated.
Also, my Actor's draw method:
@Override
public void draw( Batch batch, float parentAlpha ) {
batch.draw( texture, getX(), getY(), getWidth()/2, getHeight()/2, getWidth(), getHeight(), getScaleX(), getScaleY(), getRotation() );
}
Upvotes: 1
Views: 1365
Reputation: 110
This is the way I would do it: first the origin of the actor must be the center of the square, then rotate the actor on its center and you will see something like this
The red line represent the y-offset that the actor needs to be moved up in order to follow the floor, as you can see this y-offset increases and decreases (so maybe you can't use Actions.moveBy because this move it along a linear way and your path isn't linear, see the blue line) so
Vector2 pos = new Vector2();
public void rotate(float delta, Actor a) {
a.rotateBy(angularSpeed*delta);
pos.x += linearSpeed*delta;
a.setPosition(pos.x,pos.y+yOffset(a.getRotation());
}
yOffset is the function that describes the lenght of the red line based on the square rotation angle:
public float yOffset(float angle) {
angle %= Math.PI/2;
return (float) Math.abs(squareSize*(Math.sin((Math.PI/4+angle))-Math.sin(Math.PI/4)));
}
All angles are in radians.
Upvotes: 1