How to make a Entity move towards a x and y? - java

I am looking for a way to make my Entity(A bullet) move towards a x and y,which is where the player was when the bullet was fired. so In my entity class i have -
float xSpeed = 1.0F;
float ySpeed = 0.0F;
if I wanted to move the entity in a diaganal line I would make xSpeed and ySpeed = 1.0F
How would I make it move in the dir of another x and y?
Thanks for the help
EDIT --
Solved,thanks for the help
To anyone else who finds this question needing help,here is my code-
float xSpeed = 0;
float ySpeed = 0;
then I have some maths to make it so they move at the same speed
ySpeed = ySpeed * (float) (2.5 / Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed));
xSpeed = xSpeed * (float) (2.5 / Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed));
and this code to set the xSpeed and ySpeed,based on a x and y you want to move towards
xSpeed = (Game.PlayerX - x) / 3;
ySpeed = (Game.Playery - y) / 3;
and then,finaly,add xSpeed and ySpeed to the x and y of your entity
this.x += xSpeed;
this.y += ySpeed;

The usual way is to set the relative x and y speeds to cover the required x and y distances in the allotted travel time:
float xSpeed = (targetLocation.x - currentLocation.x) / travelTime;
float ySpeed = (targetLocation.y - currentLocation.y) / travelTime;
If you want to travel at a predetermined speed, rather than in a predetermined travel time, do the above computations with travelTime set to some arbitrary value (1.0f would work fine, so you could simply eliminate the division). Then compute this factor:
float factor = desiredSpeed / Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed);
(Note that you'll be dividing by zero if xSpeed and ySpeed are both 0, but that simply indicates that the current and target locations are identical. If that's a possible condition, you should include an appropriate check.) Finally, readjust xSpeed and ySpeed by the factor:
xSpeed *= factor;
ySpeed *= factor;
Note that by setting travelTime to 1, this is just a sneaky way of multiplying the predetermined speed by the sine and cosine of the angle that the travel direction makes with the x axis without mentioning trigonometry at all. :)

You need to define the speed of the object, and the direction. Then you can use simple trig to determine the x/y displacement per step.
If you use your current algorithm your object will change speeds depending on its direction, which is probably not what you want to do.
Linear direction:
speed x = 1
speed y = 0
Total speed = 1
Diagnol direction:
speed x = 1
speed y = 1
Total speed = 2
See the problem? Your speed should be constant regardless of direction.
Use what's called a Vector to describe your object's direction and speed.
class Vector {
int x; int y; float angle; float magnitude;
}
The x,y, angle and magnitude describe a triangle. The movement you want will be a point on the line of the hypotenuse of the triangle, modified by the time step your engine is using.
edit -
Imagine a Circle that has a radius of 1 unit, with it's origin at 0, 0.
Draw a line from the origin to the left side. You get a line 1 unit long, that intersects the circle at (1,0)
Now, draw a line from the origin at a 45 degree angle to the edge of a circle.
You'll also get a line 1 unit long, however the X/Y coordinate where the line intersects the circle will be (0.7,0.7) NOT (1,1).
I do not have an ide in front of me, so please someone edit if my math is wrong here, but I beilive you'll want something like this:
newPositionX = currentX + ( cos ( angle ) * speed * timeStep )
newPositionY = currentY + ( sin ( angle ) * speed * timeStep )

Related

How to create the illusion of particles been left behind in libgdx

I am making an endless runner game were the camera is static and the environment is moving from top to bottom, the player is a rocket facing upwards that can only move left or right. When the player collides with an obstacle it spawns particles to show an explosion. What i want is to show the illusion of the particles been left behind as the camera is moving up. But since my camera is static i have to move them backwards myself to give an illusion of the camera going up how do i go about doing that?
Here is my code:
public Particle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
rotDirection = MathUtils.random.nextBoolean() ? -1 : 1;
dx = MathUtils.cos(MathUtils.random(MathUtils.PI2));
dy = MathUtils.sin(MathUtils.random(MathUtils.PI2));
xSpeed = MathUtils.random(MIN_SPEED, MAX_SPEED);
ySpeed = MathUtils.random(MIN_SPEED, MAX_SPEED);
rotation = MathUtils.random(360);
rotationSpeed = MathUtils.random(MIN_ROT_SPEED, MAX_ROT_SPEED);
}
public void update(float delta){
x += dx * xSpeed * delta;
y += dy * ySpeed * delta;
rotation += rotDirection * rotationSpeed * delta;
}
You are using randoms to set dy and ySpeed.
Then you change the y value using these 2 random values and deltaTime.
If you want to move the particle in a specific direction you cannot use random values to move it.
Try having a float yMoveSpeed and add it to y.
public void update(float delta){
x += dx * xSpeed * delta;
y += dy * ySpeed * delta;
rotation += rotDirection * rotationSpeed * delta;
y += yMoveSpeed * delta;
}
That should at least make it move in a direction.
Another solution could be to use the particle system and editor bundled with libgdx. (in gdx-tools)
Game From Scratch tutorial

Java Game - moving an object in a straight line to another point

Here is what I have so far:
int vx = (playerx - x);
int vy = (playery - y);
double distance = Math.sqrt((vx * vx) + (vy * vy));
double doublex = ((vx / distance));
double doubley = ((vy / distance));
dx = (int) Math.floor(doublex + 0.5);
dy = (int) Math.floor(doubley + 0.5);
x += dx;
y += dy;
I just want x and y to move straight towards playerx and playery but it moves only at a slope of 0, 1, or undefined.
I suspect it because you x and y are int and you have moving such a short distance that you will only be (1, 1), (1, 0) or (0, 1).
You need to allow it to move further that 1, or use a type which more resolution. e.g. double.
BTW: Instead of using Math.floor I believe a better choice is
dx = (int) Math.round(doublex);
You are dividing horizontal distance and vertical distance by total distance, this will always result in a number between 1 and -1 so each time it moves it will move by either nothing or by 1 in a direction. I guess this is in pixels?
Each time the move happens you should keep track of the actual distance moved and the desired distance moved because, for example, you may be trying to move 0.4 along the y axes in every loop, and it will never move because that will always round down. So if in the second loop you know you should have moved by 0.8 in total, you can round up to one, and leave the desired set to -0.2 and keep looping.
A solution similar to Bresanham's Line Algorithm can be implemented. IE:
function line(x0, y0, x1, y1)
real deltax := x1 - x0
real deltay := y1 - y0
real deltaerr := abs(deltay / deltax) // Assume deltax != 0 (line is not vertical),
// note that this division needs to be done in a way that preserves the fractional part
real error := deltaerr - 0.5
int y := y0
for x from x0 to x1
plot(x,y)
error := error + deltaerr
if error ≥ 0.5 then
y := y + 1
error := error - 1.0
Source: Bresanham's Line Algoithm

How do I create an orbit in libgdx?

I'm making a space game, and I'd like to make a small drone ship orbit my bigger player ship. I'm not entirely sure how to make it orbit in a perfect circle. So far I can make it move in a diamond shape, but my attempts to correct for the circle shape have ended in failure.
Basically, I'm doing something like this:
float centerX = ship.getX() + (ship.getWidth() / 2);
float centerY = ship.getY() + (ship.getHeight() / 2);
float droneX = drone.getX();
float droneY = drone.getY();
float radius = drone.getRadius();
float xDiff = Math.abs(droneX - centerX);
float yDiff = Math.abs(droneY - centerY);
float moveByX = Math.abs(radius / (xDiff == 0 ? 1 : xDiff) / smoother);
float moveByY = Math.abs(radius / (yDiff == 0 ? 1 : yDiff) / smoother);
And then I move the drone by the moveByX and moveByY values. It works fine in a diamond shape, as I mentioned, but how can I improve this to calculate the correct circular pattern?
Okay, since you're using x and y differences, it will only go in a straight line, which explains the diamond pattern. In order to get the circle, you'll have to break out trigonometry.
float angle; //angle in radians
float droneX = drone.getRadius() * Math.sin(angle);
float droneY = drone.getRadius() * Math.cos(angle);
After that you can use your movement code. And angle should probably be kept on the drone, and in radians.
CBredlow was able to give me enough information to solve the question - I wasn't able to accept his answer, as it was a comment, but the solution is this:
// this is degrees per second
float speed = 10f;
float rate = 5f;
float circleX = (float) (Math.cos(drone.getAngle()) *
(ship.getWidth() / 1.25) + centerX);
float circleY = (float) (Math.sin(drone.getAngle()) *
(ship.getHeight() / 1.25) + centerY);
float angle = drone.getAngle() + (speed * (rate/1000)) % 360;
if (angle >= 360) {
angle = 0;
}
drone.setAngle(angle);
drone.setX(circleX);
drone.setY(circleY);
Thanks!

Wanted to make an object bounce inside a circle, ended up making the object move along the rim of the circle

Here's the code in question:
public void calculate() {
// Center of circle is at (250, 250).
//THIS ALGORITHM IS NOW PROVEN TO BE WORSE THAN I FEARED...
/* What it does:
* Moves object around in a circle.
* Does not move the object towards the center.
* Object always stays on the rim of the circle.
*
* Algorithm I used. (DOES NOT WORK):
* N is normalized vector.
* R = -2*(V dot N)*N + V
*/
vx += Accelero.X * 0.1;
vy += Accelero.Y * 0.1;
double nx = x - 250;
double ny = y - 250;
double nd = Math.hypot(nx, ny);
if (nd == 0)
nd = 1;
nx /= nd;
ny /= nd;
double dotProduct = vx * nx + vy * ny;
vx += (float) (-2 * dotProduct * nx);
vy += (float) (-2 * dotProduct * ny);
x -= vx * 2;
y -= vy * 2;
vx *= 0.99;
vy *= 0.99;
}
And this is what happens.
The black line you see is where the purple object (box) moves. It just so happens to be right on the circle line I drew with Canvas.drawCircle().
I don't understand why reflection didn't work. If an object is to hit a circular wall, shouldn't it reflect the object's direction of velocity, which is what the algorithm was meant to be? Or I used the wrong algorithm?
Any help is appreciated. Thanks in advance.
Can you do bouncing off a straight wall of arbitrary angle? That should be the first step. (You may find that a polar representation of the velocity vector is easier to work with.)
Once you've got that working, it should be fairly straightforward: bouncing off a circle is like bouncing off a tangent of that circle that touches it at the point of contact.
You can calculate this tangent by observing that it's perpendicular to the radius vector in the point of contact (that is the vector that points from where the object is to the centre of the circle)
Is there a vector-based implementation of this, without relying on angles?
Yes, see 2-Dimensional Elastic Collisions without Trigonometry, illustrated in this KineticModel. Your implementation appears to be missing the tangential component. See Ensemble#collideAtoms() for details.
This is what I've got, and I'm going to share my findings to all of you.
public void calculate() {
// Center of circle is at (250, 250). Radius is 40.
//THIS ALGORITHM IS PROVEN TO BE BETTER THAN I FEARED...
/* What it does:
* Moves object around in a circle, if object is
* inside of circle.
* Does not move the object towards the center,
* nor outwards. This is crucial.
* Object always stays on the rim of the circle,
* if the collision detection allows it to.
*
* Algorithm I used. (DOES WORK, NOT EXPECTING THIS THOUGH.):
* N is normalized vector.
* R = -2*(V dot N)*N + V
*/
double nx = x - 250;
double ny = y - 250;
double nd = Math.hypot(nx, ny);
if (nd < 40){
vx += Accelero.X * 0.1;
vy += Accelero.Y * 0.1;
x -= vx;
y -= vy;
vx *= 0.9;
vy *= 0.9;
return;
}
vx += Accelero.X * 0.1;
vy += Accelero.Y * 0.1;
if (nd == 0)
nd = 1;
nx /= nd;
ny /= nd;
double dotProduct = vx * nx + vy * ny;
vx += (float) (-2 * dotProduct * nx);
vy += (float) (-2 * dotProduct * ny);
x -= vx * 2;
y -= vy * 2;
vx *= 0.99;
vy *= 0.99;
}
I embedded a collision detection inside my function, basically making this function not as efficient as possible. Ignore that, for it's not the main focus.
The circle's radius is 40, the (x,y) position is (250,250).
Only when the object is either on the circle, or further away from the center of circle, should we calculate the collision response, which is given by the algorithm R = -2*(V dot N)*N + V, where normal vector N is already normalized.
The algorithm is indeed correct, it's the boolean condition of my collision detection is what causes the object to stay on the rim of the circle and go round-a-bout on it.
I didn't say the other algorithm, which #trashgod had provided is wrong. It's because of some weird issue that somehow causes the object to move unusually. I would guess it's the API I'm using's fault, which it didn't allow doubles, but I may be incorrect. I just couldn't find the source of the problem. Which I'm also happy to not look into it further anymore.
The collision detection boolean condition itself could change everything, if it was slightly altered. If it wasn't for #n.m. pointing that I somehow seemed to forget a minus sign (in this case, a NOT sign), I probably would never realized how trivial it would be.

How to get coordinates of a point in a coordinate system based on angle and distance

How to get coordinates of a point in a coordinate system when all I have is the origin coordinates (x, y) and the angle from the origin to the point and the distance from the origin to the point?
You use Math.cos, Math.sin like this:
pointX = x + distance * Math.cos(angle)
pointY = y + distance * Math.sin(angle)
Note about radians / degrees
Math.cos and Math.sin assumes the argument is given in radians (0…2π). If you have the angle in degrees (0…360), you would use Math.cos(Math.toRadians(angle)) for instance.
If r is the distance from origin and a is the angle (in radians) between x-axis and the point you can easily calculate the coordinates with a conversion from polar coordinates:
x = r*cos(a)
y = r*sin(a)
(this assumes that origin is placed at (0,0), otherwise you should add the displacement to the final result).
The inverse result is made by computing the modulo of the vector (since a distance + angle make a vector) and the arctangent, which can be calculated by using the atan2 funcion.
r = sqrt(x*2+y*2)
a = atan2(y,x)
If d is the distance and A is the angle, than the coordnates of the point will be
(x+d*Cos(A), y+ d*Sin(A))
px = x + r * cos(phi)
py = y + r * sin(phi)
where [px py] is the point you are searching for, [x y] is the "origin", r is the distance and phi is the angle to the target from the origin.
EDIT: http://en.wikipedia.org/wiki/Polar_coordinate_system This link which was helpfully posted by Bart Kiers could yield some background information.
Short answer
// math equations
pointX = distance * cos(angle) + x
pointY = distance * sin(angle) + y
// java code [angle in radian]
double pointX = distance * Math.cos(Math.toRadians(angle)) + x;
double pointY = distance * Math.sin(Math.toRadians(angle)) + y;
Detailed answer
As per below diagram
// finding pointX let's start by
cos(angle) = (pointX - x) / distance
distance * cos(angle) = (pointX - x)
(pointX - x) = distance * cos(angle)
pointX = distance * cos(angle) + x
// finding pointY let's start by
sin(angle) = (pointY - y) / distance
distance * sin(angle) = (pointY - y)
(pointY - y) = distance * sin(angle)
pointY = distance * sin(angle) + y

Categories

Resources