I'm creating a jigsaw puzzle game where you can drag and drop puzzle pieces.
I wanted to add rotation by increments of 90 degrees on a double-tap. When moving a rotated puzzle piece, weird movement upon dragging occurs.
e.g. After rotating it clock-wise 90 degrees, and then moving it the puzzle piece will not follow the mouse and instead rotates on an outwards spiral on any mouse movement.
Each rotation has its own weird movement, but when rotated 360 degrees the movement is o.k again.
Why is this?
It seems like the listeners x and y input is causing the problem. public void touchDragged (InputEvent event, float x, float y, int pointer)
I think when rotating an actor something else also needs to be done as well, but I can't figure out what...
The puzzle piece actor which inherits Group and has it's own overridden listener.
override fun doubleTap() {
super.doubleTap()
/*addAction(Actions.rotateBy(-90f, .25f))*/
rotateBy(-90f)
}
I expect the puzzle piece to always follow the mouse pointer.
I found the answer.
Apparently when rotating Actors its coordinate system rotates with it.
I solved the problem with this code:
override fun touchDragged(event: InputEvent?, eventOffsetX: Float, eventOffsetY: Float, pointer: Int) {
val cos = cos(self.rotation * MathUtils.degreesToRadians)
val sin = sin(self.rotation * MathUtils.degreesToRadians)
val tox = (eventOffsetX - self.grabOffsetX)
val toy = (eventOffsetY - self.grabOffsetY)
var deltaX = 0f
var deltaY = 0f
if (abs(cos) == 1f) {
deltaX = tox * cos
deltaY = toy * cos
} else {
deltaX = toy * -sin
deltaY = tox * sin
}
self.moveBy(deltaX, deltaY)
}
If anyone have an explanation I would love to hear it.
Related
Hello I'm trying to make a billiards game using libgdx. I'm using 3d models for the balls and an Orthographic Camera to view them. I am having trouble getting them to roll correctly after rolling on a different axis. Here is a clip of what they look like when they're rolling.
As you can see they appear to be rotating as if they were on their starting axis. Is there any way to rotate it so that it looks like it's actually rolling. I am also not very familiar with transformation matrices or quaternions so im not too sure where to go.
Edit: Updated for clarity
Here is the code I use to update the rotation
public boolean update() {
if (!visible) {
return false;
}
Vector2 vBall = ballBody.getLinearVelocity();
float vAngle = ballBody.getAngularVelocity();
isMoving = true;
float x = ballBody.getPosition().x * SCALE;
float y = ballBody.getPosition().y * SCALE;
Vector2 axisInPlane = new Vector2(y - center.y, x - center.x).rotateRad(Math.PI/2f);
Vector3 axis3D = new Vector3(axisInPlane.x,axisInPlane.y,0f);
ball3D.transform.rotate(axis, (float) Math.toDegrees(dist / RADIUS_PX));
ball3D.transform.setTranslation(mapX(x), mapY(y), 0);
Just to be sure, center is an arbitrary fixed point where there is no rotation and all rotations are derived from this distance/angle as the ball has no slippage.
So you can directly get the axis with
Vector2 axisInPlane = new Vector2(y - center.y, x - center.x).rotateRad(Math.PI/2f);
Vector3 axis3D = new Vector3(axisInPlane.x,axisInPlane.y,0f);
Also Math.toDegree takes radians as an argument, not a float, so dist/RADIUS_PX will be off, you have to supply as a fraction of 2PI (360 degs in radians). Also this should be the circumference of the ball not the radius. I don't know what class ball3D is but I would check that ball3D.transform.rotate does take degrees as an argument and if it does replace that line with
float rotateRadians =(float) Math.toDegrees((dist/CIRCUMFERENCE_PX)*Math.PI*2f);
ball3D.transform.rotate(axis, rotateRadians );
I'm making a top down shooter game. I've got my character moving. All I want to do next is make a bullet shoot from the center of my character to the direction my cursor is at. How would i go about doing this?
I'm really struggling to think of the code i need to make this work.
This will involve simple vector math. There are tons of resources online about this. Here's the basic gist:
1) First, calculate the angle (in radians) between your character and your target (in this case the mouse location). You can use Math.atan2() to perform this calculation.
var angle:Number = Math.atan2(mouseY - playerY, mouseX - playerX);
2) Next, use that angle to create a vector (x,y delta) which represents the direction of travel for your bullet. You use Math.cos() and Math.sin() to compute the x and y value:
var speed:Number = 5;
var vector:Point = new Point(Math.cos(angle) * speed, Math.sin(angle) * speed);
3) Now you can update the bullets position each frame by that vector:
bullet.x += vector.x;
bullet.y += vector.y;
4) And if you want to make your bullet sprite point in the direction of travel, convert that angle to degrees and set the bullet sprite's rotation:
var degrees:Number = angle * (180 / Math.PI);
bullet.rotation = degrees;
Note that for the purpose of the math here, 0 degrees is considered to be right-facing along the x-axis, not up-facing like you might naturally think of 0 degrees (at least I do). What this means is your sprites unrotated orientation should be facing right-ward.
I'm working on a new game written with LibGdx Engine and Java.
I've got a problem with some of the physics in this game.
I want to shoot the arrow in a ballistic trajectory (angry bird style)
and can't find the equation to do so .
I am using these velocity equations:
float velx = (float) (Math.cos(rotation) * spd);
float vely = (float) (Math.sin(rotation) * spd);
I add this to the current position and the arrow shoots in one direction - straight.
I thought maybe changing the rotation would help me achieve what I want (a ballistic path).
It does help, but I want to have the trajectory as well.
I saw this
ProjectileEquation class that someone already posted but didn't know how to work with it:
public class ProjectileEquation
{
public float gravity;
public Vector2 startVelocity = new Vector2();
public Vector2 startPoint = new Vector2();
public Vector2 gravityVec = new Vector2(0,-10f);
public float getX(float n) {
return startVelocity.x * (n ) + startPoint.x;
}
public float getY(float n) {
float t = n;
return 0.5f * gravity * t * t + startVelocity.y * t + startPoint.y;
}
}
I'm looking for some help to help me use this class for ballistic trajectories.
This is how I tried using it:
for(int i =0;i<30;i++)
{
Texture f = ResData.Square_1;
ProjectileEquation e= new ProjectileEquation();
e.gravity = 1;
e.startPoint = new Vector2(bow.getX(),bow.getY());//new Vector2(-bow.getX(),-bow.getY()); //My bow is opposite so it suppose to work fine
e.startVelocity = getVelocityOf(bow.getRotation());
Vector3 touchpos = new Vector3();
s.draw(f,e.getX(i) ,e.getX(i),5,5);
}
The ProjectileEquation class you post looks like it'll calculate the X and Y position given a time delta, so the float you pass in should be the time delta since you started the arrow moving (in seconds).
That code will not give you the angle of the arrow though. To find that, I would suggest you keep hold of the previous X and Y, then you can use Math.atan2() to calculate the angle based on the previous XY and the current XY. Google atan2 for a load of info on how to use it.
The very best way to do this however would be to use Box2d and model the scene correctly. Then you wouldn't have to get involved in the maths at all. I read somewhere that that's what Angry Birds uses, and is an excellent choice for modelling these sorts of physics games.
I hope your game goes well.
I have my player movieclip on the stage, and when the mouse is clicked a bullet is fired and projected at the correct angle to point itself at the mouse location. I also want a "mirroring" enemy, that fires at the complete opposite direction when the player does.
For example, when the player shoots upwards, the enemy should shoot down. Likewise, shooting to the right will cause the enemy to shoot to the left.
Is there a formula to convert the rotation in degrees to it's complete opposite?
Using Matrix is a very simple and exact solution. just multiple a or c with -1 ( to flip vertical and horizontal ).
Sample code:
var _tmpMatrix:Matrix = sprite.transform.matrix;
_tmpMatrix.a *= -1;
if ( _tmpMatrix.a < 0 ) {
_tmpMatrix.tx = sprite.width + sprite.x;
} else {
_tmpMatrix.tx = 0;
}
sprite.transform.matrix = _tmpMatrix;
Wouldn't adding or subtracting 180 degrees point in the opposite direction?
or
obj.scaleX = -1;
will do the same thing. =)
Hey gang. Stumped on something.
I have a disc I am rotating with the mouse with event.MOUSE_MOVE, like a jog wheel on some audio equipment. Everything almost works as expected, but the problem I am experiencing is that the disc always jumps to the point where the user clicks on the disc. I need the point on the disc that the user clicks on to remain under the mouse while the user spins the disc but I can't seem to come up with the correct math to make it happen. Here's the code i am using:
var xd = (_knob.x - _stageRef.stage.mouseX);
var yd = (_knob.y - _stageRef.stage.mouseY);
var radAngle = Math.atan2(yd, xd);
_knob.rotation = int(radAngle * 360/(Math.PI * 2) - 90);
_knob is a vector circle wrapped in a movieclip, with the circle centered on the movieclip's reg point. _stageRef represents the main stage.
Any help would be awesome. I've scoured the interweb and can't come up with anything.
Thx!
You are setting _knob rotation to the angle between _knob and mouse cursor. So if rotation was 0, and angle 45, rotation becomes 45, therefore it jumps. What you need is measure changes in this angle, not setting it instantly:
var _mouseAngle:Number;
function getMouseAngle():Number
{
var xd = (_knob.x - _stageRef.stage.mouseX);
var yd = (_knob.y - _stageRef.stage.mouseY);
return Math.atan2(yd, xd);
}
function onMouseDown(event:MouseEvent):void
{
_mouseAngle = getMouseAngle();
}
function onMouseMove(event:MouseEvent):void
{
var newAngle:Number = getMouseAngle();
_knob.rotation += (newAngle - _mouseAngle) * 180.0 / Math.PI; //EDIT: forgot to convert into degrees
_mouseAngle = newAngle;
}
(Code not tested)