I have a method here that will either add or subtract the location to get to the set location that a person needs to get to if the box needs to move to the left it works great but if it needs to move to the right it doesn't seem to work I know there is a problem with it I just can't figure it out
public void doMovements(float delta) {
if (!movements.isEmpty()) {
Vector2 vec = movements.get(0);
if (pos.x > vec.x)
pos.x -= VELOCITY * delta;
else if (pos.x < vec.x)
pos.x += VELOCITY * delta;
System.out.println(pos.x);
if (pos.x - vec.x < CLOSE_VEC) {
movements.remove(movements.get(0));
System.out.println(movements.size());
}
}
rect.y = pos.y;
rect.x = pos.x;
}
I need to get from point a to point b if the box has to move left it works perfectly but if it has to move right it breaks thanks for helping!
If you calculated delta by the difference of two values, it is probably negative sometimes. They way you have it written, the code assumes that delta is always positive. Have you made sure that the delta is an absolute value.
If delta is positive and negative, then you don't need two separate statements. You do with just one:
pos.x += VELOCITY * delta;
Just make sure that delta is negative when it should be, and positive when it should be
I figured out the problem I was checking if it was at the correct lane incorrectly
I needed to change
if (pos.x - vec.x < CLOSE_VEC) {
To
if (!(pos.x - vec.x < 0) && pos.x - vec.x < CLOSE_VEC) {
I need to make sure that the value isn't negative so the rectangle can move right.
Related
I have recently started programming games in java. I come from a C# / XNA background and i already have experience in game development.
However I have a problem in my java game. I have a bouncing script which makes a in-game "particle" bounce upon collision with a solid surface, such as the ground.
Here is a snippet of the code that manages the bouncing.
private final void respondY(Rectangle r)
{
if(!r.intersects(getBounds())) // If not colliding, return
return;
if(Yvel > 0) // If falling...
{
if(r.y < Y + Height) //Another collision test
{
Y = r.y - Height; // Set Y to top of object
Yvel *= -bounce; // Bounce (Here is the problem)
onFloor = true;
}
}
else if(Yvel < 0) // If hit ceiling
{
if(Y < r.y + r.height) // Collision test
{
Y = r.y + r.height; // Set Y to bottom of object
Yvel = 0; // No bouncing here
}
}
}
The problem is that the object bounces upon the floor as it should, but after a while the object bounces constantly at the same height where I want it to stop bouncing when it got to that constant height.
NOTE:
Yvel is a int that is the vertical velocity of the object
Bounce is a float that controls how "bouncy" a object is. e.g. 0.5 means that it bounces half as high as it fell
Thanks in advance! Please note that this is my first post so if I make mistakes please point them out in a constructive manner.
The float (and double) types are imprecise. This especially causes problems when dealing with very small numbers - in fact there's a smallest representable number and a finite quantity of possible numbers that can be represented (and bit like quantum physics). The number stored by a float is actually the closest number possible to represent to the calculation result.
What's happening is the velocity calculation never reaches zero, because the result of multiplying the smallest number float can represent by a value >= .5 is itself.
I would force it to zero by putting a low threshold on the calculation result:
Yvel = Yvel * -bounce;
if (Yvel < .000001F)
Yvel = 0;
I started learning java just over a year ago so i'm still fairly new.
I'm trying to make an object travel from one point to another at a constant net velocity no matter where the second point is in the frame. Currently it's working fairly well as long as I run the method every few frames.
The only problem is that it it will only move horizontally unless the second point is approximately between 45 and 135 degrees or between 225 and 315 degrees (1/2π and 3/2π or 5/2π and 7/2π).
It may be because of the 'if' statements meant to stop it from dividing by 0 but it doesn't seem like it. Also if there is any way to simplify those equations or remove 'if' statements I wouldn't mind some advice there too.
Note: vel is the net velocity the objects travel at and Prime.mx and Prime.my is the location of the target point.
public void target()
{
if (Prime.mx > x)
{
if (Math.abs(x-Prime.mx) != 0)
x = Math.round(Math.round((x + (vel*Math.cos(Math.atan(Math.abs(y-Prime.my)/Math.abs(x-Prime.mx)))))));
}
if (Prime.mx < x)
{
if (Math.abs(x-Prime.mx) != 0)
x = Math.round(Math.round((x - (vel*Math.cos(Math.atan(Math.abs(y-Prime.my)/Math.abs(x-Prime.mx)))))));
}
if (Prime.my > y)
{
if (Math.abs(x-Prime.mx) != 0)
y = Math.round(Math.round((y + (vel*Math.sin(Math.atan(Math.abs(y-Prime.my)/Math.abs(x-Prime.mx)))))));
}
if (Prime.my < y)
{
if (Math.abs(x-Prime.mx) != 0)
y = Math.round(Math.round((y - (vel*Math.sin(Math.atan(Math.abs(y-Prime.my)/Math.abs(x-Prime.mx)))))));
}
}
I use Math.round twice because the first brings it to a float from a double and the second makes it an int. I need the x and y as ints so the paint method can draw the objects.
I found a few simillar problems on the site but the closest one was in python and and the anwer didn't seem applicable to my problem.
I believe you are overcomplicating this. If your starting point is (sx, sy) and your destination is (dx, dy) then you can easily calculate any point (x, y) that is p distance along the line (0.0 <= p <= 1.0). You can use this to move at velocity v. So I suggest finding your end point and then using simple arithmetic to move on the x and y axis.
float dx = dist * Math.cos(angle);
float dy = dist * Math.sin(angle);
for (float p = 0.0; p <= 1.0; p = Math.min(1.0, p + dist / v) {
x = sx + p * (dx - sx);
y = sy + p * (dy - sy);
}
The Math.min expression in the for loop ensures that you end up exactly at the destination point.
If you already have the destination point then it's just as easy. Instead of finding dx and dy from dist and angle you find dist from dx and dy using pythagoras.
More than solution these are some advices.
First, implement all you coordinate variables as floats to prevent rounding precision loss errors and round only right before painting.
Second, define float dx = Prime.mx - x; float dy = Prime.my - y; distance to target from current point (to use later). I would use Math.atan2(dy,dx) to compute angle between current point and target. Then use that angle to increment coordinates like this:
x += Math.cos(angle)*vel;
y += Math.sin(angle)*vel;
Third, check if your object is at target using (dx*dx + dy*dy <= radius*radius) for suitable radius (can be 1).
Also note that if the y axis goes down, then the angle will be CW (clock-wise) instead of CCW (counter-clock-wise).
I have encountered some issues regarding angles. I have an angle A and another angle B, I want to animate A the shortest way so that it reaches B. The first confusion for me is that angles go from 0 to 180, and 0 to -180. Not sure what the pros of that is. Anyway, I will give a for instance:
float a = -35;
float b = 90;
For each update I want to either add 1 or subtract 1 degree from a, until it reaches b, and I want to make sure it goes the shortest way.
Here's my code, which seems to be working. But it does not seem very efficient:
b += 360;
if (b > a) {
if (b - a < 180) {
a += 1;
} else {
a -= 1;
}
} else {
if (a - b < 180) {
a -= 1;
} else {
a += 1;
}
}
Is there a better/easier way to do it?
So you want the shortest route from a to b.
Since we are looking at a difference lets subtract:
float d = a-b;
If the value of the result is greater than 180 then we want to subtract 360.
if (d > 180) {
d -= 360;
} else if (d<-180) {
d += 360;
}
Now d is the total distance to travel. You can compare that with 0 to see which way to go. You can also do nice things like move further the larger d is. For example to make it always move 10% of the way (note that this series will never end as it will constantly approach by smaller and smaller amounts so you need to cope with that scenario):
a += d/10;
You also need to consider frame rate if you want a smooth animation.
If you work out tpf (time per frame) as a floating point fraction of a second.
long frameTook = lastFrame - System.currentTimeMillis();
long lastFrame = System.currentTimeMillis();
float tpf = frameTook / 1000;
You can now do a constant animation (where degreesPerFrame is the speed of animation) using:
float move = degreesPerFrame * tpf;
Check we aren't going to move past the destination, if we are just move to it.
if (move > FastMath.abs(d)) {
a = b;
} else {
if (d>0) {
a+=move;
} else {
a-=move;
}
}
I have given a diagram of my current small problem that I need help with. My main purpose is to keep the point from going outside the circle. Nothing else.
The center of the circle is positioned at (x, y).
I only solved a little bit of the problem, and that is the collision detection part of my problem, as given below:
public void bound(Point p, Circle c){
double distance = Math.hypot(p.x - c.x, p.y - c.y);
if (distance >= c.radius){
//Clueless from here on out.
}
}
The part where I left a comment is the spot I couldn't figure anything out. I did tried to set the point's velocityX and velocityY to 0, but I realized the point will just stay put whenever it touches the circle.
So, I'm sort of stuck.
I have resolved this issue.
public void reflect(Hole h){
//R = -2*(V dot N)*N + V
//N is normalized.
double nx = (this.position[0]+this.diameter/2) - (h.x+16);
double ny = (this.position[1]+this.diameter/2) - (h.y+16);
double nd = Math.hypot(nx, ny);
if (nd == 0)
nd = 1;
nx /= nd;
ny /= nd;
double dotProduct = this.speed[0]*nx+this.speed[1]*ny;
this.speed[0] += (float)(-2*dotProduct*nx);
this.speed[1] += (float)(-2*dotProduct*ny);
}
public void reflectResponse() {
for (int i = 0; i <= 1; i++) {
position[i] -= speed[i];
speed[i] *= 0.992f;
}
}
I tried Oli Charlesworth's method from the comments, but it made things more... "complicated" than I expected. Someone else mentioned I used a completely 100%, vector-based algorithm, since I'm relying a lot on vector-based movements.
TIPS TO THOSE WHO DO READ THIS:
If you're working on object movements and collisions with vectors, seek vector-based algorithms.
If you're working with angles (either degrees or radians), use Oli Charlesworth's method.
So i'm just trying to make a ball bounce around the screen which should slow down due to gravity and reflect (bounce) from the wall like a normal ball would.
Can someone give some basics and VERY simple implementation of this?
Other examples seem a bit "overdone" and seem to go beyond what I want to do.
I've tried this:
public void updateLogic() {
if (x < -1) {
xPos += (-x * gravity);
} else if (x > 1) {
xPos -= (x * gravity);
}
if (y > 1) {
yPos += (y * gravity);
} else if (y < -1) {
yPos -= (-y * gravity);
}
}
This is the closest I got by myself.
By the way the x and y values are from the accelerometer.
Any help would be much appreciated, thanks!
I think you'll need 3 things for this, forces (x and y, which you have), velocities (call them xVel and yVel) and positions (xPos and yPos which you also have). The position of the ball is updated (in the simplest way) by:
xPos += dt*xVel;
yPos += dt*yVel;
xVel += dt*x;
yVel += dt*y;
The variable 'dt' is the timestep, which controls how fast the ball will move. If this is set too large, though, the program will be unstable! Try dt = 0.001 or so to start and gradually set it higher.
Then, to get the ball to reflect from the walls, just flip the velocity if it hits a wall:
if (xPos > xMax) {
xPos = xMax;
xVel *= -1.0;
} else if (xPos < 0.0) {
xPos = 0.0;
xVel *= -1.0;
}
and the same for y. The 'xPos = ...' is just to stop the ball going off the edge of the screen. If you'd like the ball to bounce a little less every time it hits a wall, change the '-1.0' to '-0.9' or something (this is the coefficient of restitution).
Hopefully that should be all. Good luck!
Some comments on your actual code:
Both of these lines do exactly the same thing:
yPos -= (-y * gravity);
yPos += (y * gravity);
likewise, both of these lines do the same thing:
xPos += (-x * gravity);
xPos -= (x * gravity);
You are not handling the cases -1 <= x <= 1 or -1 <= y <= 1
Some comments on the concepts:
Start with one ball.
You want the ball to have two separate velocities (both either positive or negative), one in the x-direction and one in the y-direction. Every frame, add those velocities to the ball's position.
Then add collision detection. Check each frame if the center of the ball is outside the screen. If it is, make it bounce (the easiest way to do this is to make the ball's y-velocity positive when it goes off the most-negative y-value displayed on the screen; and do similarly for the other screen-edges).
Improve the collision detection: see if you can figure out how to check if any part of the ball it outside the screen (hint: to check if the ball is off the left-side of the screen, you only need to check the left-most coordinate of the ball)
Then take gravity into consideration - gravity will be a constant number subtracted from the y-velocity every frame, until the y-velocity hits 0.
Youtube video
Source code available at github.
Your x coordinate should not be affected by gravity.
I would advise against using accelerometers until you understand how the physics work for the simple case.
Break it up into stages. First, ensure that you can get the ball falling at a constant velocity.
Once you have that working, worry about the gravity causing the velocity to increase.
Once you have that working, worry about the intersection with walls and velocity changes. A simple algorithm for bouncing off the walls would be to multiply the x velocity by -1 when you hit a vertical wall, and multiply the y velocity by -1 when you hit a horizontal wall.