I'm doing a simple breakout game and I have some problem to understand how I should handle speed and direction of the ball to move it in different diagonal paths. I'm using this code in an update method:
xPos += xSpeed * direction;
yPos += ySpeed * direction;
If I use different vaules of xSpeed = 2 and YSpeed = 1 I can change to different diagonal paths, but I still want the same speed. If I increase value of xSpeed = 4 to get another diagonal path, then the speed is also increased, and I want the ball to move in the same speed. For the value of direction I use 1 or -1. But I guess it would be better to change the value of direction to get diagonal paths in degrees? In a breakout game the ball has to bounce back in the oppesite direction. I'm not good in math, so I would preciate some help to solve this. Any ideas how I can improve my code?
You could use sine and cosine functions to get the relative movement in x and y axis.
Like:
xPos += speed * Math.sin(movementAngle);
yPos += speed * Math.cos(movementAngle);
Using the above (polar coordinates) in various animations has the advantage of ease in modyfing direction or velocity of movement (which are speed and movementAngle variables respectively). When using cartesian coordinates (x and y position), change in either velocity or direction of movement would require non-obvious changes to both x and y.
Formulas in the solution above are nothing more than conversion from polar to cartesian coordinates.
Edit: to get the more "natural" behaviour, when movementAngle of 0 means moving right, PI/2 - up, PI - left and 3*PI/2 - right, use the following:
xPos += speed * Math.cos(-1*movementAngle);
yPos += speed * Math.sin(-1*movementAngle);
Related
I have run into a problem making a first person camera on LWJGL 2. I am using the following code to rotate the camera (up down left and right) based on how the mouse moves. This is basically what every other tutorial has, however, its movement is flawed and ends up spiraling out of control.
float mouseDX = Mouse.getDX();
float mouseDY = Mouse.getDY();
rotation.x = mouseDX;
rotation.y = mouseDY;
glRotatef(rotation.y, 1, 0, 0);
glRotatef(rotation.x, 0, 1, 0);
Rotation is a Vector3f
I am aware that the rotation.y is rotating the x access and the x is rotating the y. I am not totally sure why but it doesn't work for me unless its this way. The problem may be related to this.
Here is a video I made showing what I mean:
https://www.youtube.com/watch?v=V6Iu5oQuWo4&feature=youtu.be
In the video I attempt to show that both the x and y rotation work fine separately, but when used together they don't work at all.
I know this is only a small section of my code, but it is the only part dealing with rotation so the problem must be there somewhere.
The flaw that stands out to me is the value by which you rotate.
Mouse.getDY returns the change in y pixels so if you move your mouse half way down the screen you will move typically 300 pixels (800x600).
Now you also have glRotatef which rotates by radians which compared are tiny compared to degrees.(360 degrees -> 6.28 radians)
Now take 300 hundred pixels, use it as the number of radians to rotate by and you get 17188.7 degrees of rotation.
And that's the cause of your spiralling (47 revs/few milliseconds)
What you will need to do if divide your dy and dx by a good couple of hundred.
And you can also still use degrees by using Math.toRadians in the glRotatef method
I want to calculate velocity for ball to hit target(my ball/finger).
x and y of my ball are know and are changing while I'm moving my finger but assume that it is not changing (X and Y are some random number) and ball that should reach my finger is coming from left upper corner (x=0,y=0).
How to calculate velocityX and velocityY for that ball in order to hit me ?
You could set velocityX to negative if the ball is X is greater then the target's X else set velocity to a positive number if it is less then the target's X. This would make the ball move towards the X coordinate of the target. Just do the same for the y Axis and the ball should move towards the target. However, this may cause the ball to "shake" when it reaches the target so, in order to fix this, set velocityX and velocity to 0 when it reaches the target.
Hope this helped.
I'm writing a game in Java using OpenGL (the LWJGL binding, to be specific). Each entity, including the camera, has a quaternion that represents it's rotation. I've figured out how to apply the quaternion to the current OpenGL matrix and everything rotates just fine. The issue I'm having is getting the camera to rotate with the mouse.
Right now, every frame, the game grabs the amount that the mouse has moved on one axis, then it applies that amount onto the quaternion for the camera's rotation. Here is the code that rotates the quaternion, I'll post it since I think it's where the problem lies (although I'm always wrong about this sort of stuff):
public void rotateX(float amount){
Quaternion rot = new Quaternion(1.0f, 0.0f, 0.0f, (float)Math.toRadians(amount));
Quaternion.mul(rot, rotation, rotation);
rotation.normalise();
}
This method is supposed to rotate the quaternion around the X axis. 'rotation' is the quaternion representing the entity's rotation. 'amount' is the amount that I want to rotate the quaternion (aka the amount that the mouse was moved). 'rot' is a normalized vector along the X axis with a w value of the amount converted to radians (I guess the goal here is to give it an angle- say, 10 degrees- and have it rotate the quaternion along the given axis by that angle). Using Quaternion.mul takes the new quaternion, multiplies it by the rotation quaternion, and then stores the result as the rotation quaternion. I don't know if the normalization is necessary, since 'rot' is normal and 'rotation' should already by normalized.
The rotateY and rotateZ methods do the same thing, except for changing the vector for 'rot' (0.0, 1.0, 0.0 for y and 0.0, 0.0, 1.0 for z).
The code appears to work fine when the game starts and the camera is looking down the negative Z axis. You can spin all the way around on the Y axis OR all the way around the X axis. But as soon as you try to rotate the camera while not looking down the Z axis, everything gets really screwy (I can't even describe it, it rotates very oddly).
My end goal here is to have something to use for controlling a ship in a space with no up vector. So when you move the mouse on the Y axis, no matter what angle the ship is at, it changes the pitch of the ship (rotation along the X axis). Similarly, when you move the mouse on the X axis, it changes the yaw (rotation along the Y axis). I might be going about this the wrong way and I probably just need a push (or shove) in the right direction.
If you need more details on anything (how my rendering is done, any other maths that I'm trying to do) just ask and I'll put it up. I understood everything when I was using euler angles (which apparently are a big no-no for 3D application development... wish somebody would have told me that before I sunk a lot of time into getting them to work) but as soon as I switched over to quaternions, I got in over my head really fast. I've spent the past few months just playing with this code and reading about quaternions trying to get it to work, but I haven't really gotten anywhere at all :'(
Very, very frustrating... starting to regret trying to make something in 3D >_<
Quaternion rot = new Quaternion(1.0f, 0.0f, 0.0f, (float)Math.toRadians(amount));
OK, this is flat-out wrong.
The constructor that takes four floats assumes that they represent an actual quaternion. What you give that constructor is not a quaternion; it's a vec3 axis and an angle that you expect to rotate around.
You can't shove those into a quaternion class and expect to get a legitimate quaternion out of it.
Your quaternion class should have a constructor or some other means of creating a quaternion from an angle and an axis of rotation. But according to the documentation you linked to, it does not. So you have to do it yourself.
A quaternion is not a vec3 axis with a fourth value that is an angle. A unit quaternion representation a change in orientation is a vec3 that is the axis of rotation * the sine of half of the angle of rotation, and a scalar component that is the cosine of half the angle of rotation. This assumes that the angle of rotation is clamped on the range [-pi/2, pi/2].
Therefore, what you want is this:
float radHalfAngle = ... / 2.0; //See below
float sinVal = Math.Sin(radHalfAngle);
float cosVal = Math.Cos(radHalfAngle);
float xVal = 1.0f * sinVal;
float yVal = 0.0f * sinVal; //Here for completeness.
float zVal = 0.0f * sinVal; //Here for completeness.
Quaternion rot = new Quaternion(xVal, yVal, zVal, cosVal);
Also, converting amount to radians directly doesn't make sense, particularly so if amount is just a pixel-coordinate delta that the mouse moved. You need some kind of conversion scale between the distance the mouse moves and how much you want to rotate. And toRadians is not the kind of scale you want.
One more thing. Left-multiplying rot, as you do here, will perform a rotation about the camera space X axis. If you want a rotation about the world-space X axis, you need to right-multiply it.
I want to know how is it possible,I could have an Object drawn at a certain point and move to the point that is touched on the screen. I am trying to use it for my game where when the user touches on the screen, the gun fires from the position of the player, but the player is stationary.
Thanks in advance.
P.S.
Is there a visual graphic of some sort that shows where every plot is on android.
I don't know what kind of library you're using to draw all of your things, but that basically doesn't matter since you only need to know two things in order to do this:
Without going into specifics on vector geometry:
1. You need to calculate the direction (x and y component) that the projectile moves in depending on your mouses position. You get this direction by simply subtracting the position of the mouse from the position of the player:
//x component of direction
float direction_x = mousePosition.x - playerPosition.x;
//y component of direction
float direction_y = mousePosition.y - playerPosition.y;
In order to just get a direction instead of adding a velocity component to this vector, you need to normalize it (so it has a length of 1):
float length =(float) Math.sqrt(direction_x*direction_x + direction_y*direction_y);
direction_x /= length;
direction_y /= length;
You then need to update the projectiles position by adding the direction_x and direction_y components to it, multiplied by the speed that you want the projectile to have (This process is called linear interpolation, by the way):
projectile_x += direction_x*speed;
projectile_y += direction_y*speed;
If you have some way of measuring the time between two frames, the speed variable should depend on the elapsed time between those frames, in order to create smooth movements on different platforms.
Ok so I am working on a game in Android and right now I have a bitmap that I have drawn at the center of the screen. I can rotate the bitmap left and right by certain degrees using the Matrix class. The bitmap is a picture of a ship so when the user wants to move forward, I want the ship to move at the current angle that the ship is rotated at. Any ideas about how I should go about doing this?
Ok well with a bunch of trial and error and some reading up on trig I have managed to solve my own question. The vector that holds the current location of the ship has an X and a Y. What I then need to do, was based on the current rotation of the ship calculate a speed vector and then add that speed vector to the position vector.
speedX = (float) Math.sin(rotation*(Math.PI/180)) * speed;
speedY = (float) -Math.cos(rotation*(Math.PI/180)) * speed;
x += speedX;
y += speedY;
The rotation is in degrees so they needed to be converted to radians. Also speed is the actual speed of the ship and is applied to each speed vector. Hope that will help someone having the same problem.