Velocity never hitting 0 when key released in Java - java

I am trying to make it so if you are, lets say, moving right and you let go of your arrow key, you will slow down then stop, not just stop immediately. Here is how I am doing this:
//If you clicked right arrow key and you're not going
//Faster then the max speed
if(moveRight && !(vel.x >= 3)){
vel.x += movementSpeed;
//If you let go of arrow key, slow down at 3/2 the speed you were moving
}else if(vel.x >= 0 && !moveRight){
vel.x -= movementSpeed * 1.5f;
}
However, for some reason, this sometimes works. Other times, you will notice that the velocity is at about 0.00523329 or something very small like that. I don't understand why because the else if statement says to slow down until you are equal to 0 essentially. I need the velocity to reach 0. Any help in this regard is extremely appreciated!

else if statement says to subtrack movementSpeed * 1.5f, nothing more.
Code below always prints 0.0:
boolean moveRight = false;
Velocity vel = new Velocity();
vel.x = 4;
float movementSpeed = 3;
while (vel.x != 0) {
if(moveRight && !(vel.x >= 3)) {
vel.x += movementSpeed;
}
else if(vel.x >= 0 && !moveRight) {
vel.x -= movementSpeed * 1.5f;
}
if (vel.x <= 0) {
vel.x = 0;
}
}
System.out.println(vel.x);
Maybe you forgot about loop. Please, paste more code.

Related

Is there a better way to do lots of if else statements for joystick input

I am making an input for an controller and translating is to WASD input. It took me many if else statements and I thought it could use some improvements. What are possible solutions to make it shorter or make it better.
import java.awt.*;
import java.awt.event.KeyEvent;
public class Translator {
private Robot r;
public Translator(){
try {
r = new Robot();
} catch (Exception e){
e.printStackTrace();
}
}
public void KeyHandler(double x, double y, boolean pressing){
ReleaseAll();
if((x > 1250 && x <2750) && y < 500){
r.keyPress(KeyEvent.VK_W);
} else if ((x > 1250 && x <2750) && y >3500){
r.keyPress(KeyEvent.VK_S);
} else if(x < 600 && (y > 1000 && y < 3000 )){
r.keyPress(KeyEvent.VK_A);
} else if(x > 3250 && (y > 1000 && y < 3000 )){
r.keyPress(KeyEvent.VK_D);
}else if(x < 1500 && y < 1000){
r.keyPress(KeyEvent.VK_A);
r.keyPress(KeyEvent.VK_W);
} else if(x > 2750 && y < 1000){
r.keyPress(KeyEvent.VK_D);
r.keyPress(KeyEvent.VK_W);
} else if(x > 2750 && y > 3000){
r.keyPress(KeyEvent.VK_D);
r.keyPress(KeyEvent.VK_S);
} else if(x < 1500 && y > 3000){
r.keyPress(KeyEvent.VK_A);
r.keyPress(KeyEvent.VK_S);
} else {
ReleaseAll();
}
if(pressing){
r.keyRelease(KeyEvent.VK_E);
}
}
private void ReleaseAll(){
r.keyRelease(KeyEvent.VK_W);
r.keyRelease(KeyEvent.VK_A);
r.keyRelease(KeyEvent.VK_S);
r.keyRelease(KeyEvent.VK_D);
}
}
This might not be a direct answer to your question but it might help somewhat, it depends on how much energy you would like to put into changing the way you check the x and y positions.
But I am thinking that a classic search algorithm would be suited for the task. In your case, you are essentially checking every single possible outcome one by one, a comparison would be to search a list for say a specific string by going over each value one by one.
What your could do is instead to check whether your values are less or greater than the middle value. This would leave you with just half the values to check in the next iteration, and then you keep narrowing the scope down until you in which "section" of possible values the input belongs to.
What I am talking about here is called "Binary Search", the fact that you have 2 dimension in you data does makes things more complicated, and it would be up to you to also adapt the algorithm in order for it to work on your dataset of possible values in both x and y.
You can find a more extensive explanation of different search-algorithms here:
https://stackabuse.com/search-algorithms-in-java/

Writing Java long If/Else Loops in a shorter way

Hi guys i currently have a assignment which i just finished but their is one detail i dont love about it. Is there a way to shorten if else loops
Currently i have wrote
if (x >=300) {
set y = 1;
}
else if(x >=200) {
set y = 2;
}
else if (x >=150) {
set y = 3;
}
else if (x>=100) {
set y = 4;
}
else if (x >=50) {
set y = 5;
}
else if (x >=25) {
set y = 6;
}
Probably me just being pedantic, thanks in advance
You could shorten it to
y = x>=300 ? 1 : x>=200 ? 2 : x>=150 ? 3 : x>=100 ? 4 : x>=50 ? 5 : 6;
but while that may be more compact, it is also subjectively less readable. For additional informatione, see here.
This looks like a place where you could use the switch statement. However, the switch statement is designed to handle known values rather than inequalities. If you don't like the way the chain of if-else statements looks, you could do it all in an inline expression (Ternary Operator), but that makes it hard to read.
I'd say keep the code the way it is unless there's a good reason to change it. If you're only going to have one code statement after each statement, then you can eliminate the curly braces {} to make the code look a little cleaner:
if (x >= 300) set y = 1;
else if (x >= 200) set y = 2;
else if (x >= 150) set y = 3;
else if (x >= 100) set y = 4;
else if (x >= 50) set y = 5;
else if (x >= 25) set y = 6;

Java LibGDX Multi Touch Movement

What is the problem? I am using this code to movement for two players. But it is not working. Player1 is more quick than player2. How can I fix?
for (byte i = 0; i < 20; i++) {maxDistance = 10 * Gdx.graphics.getDeltaTi
me();
if (Gdx.input.isTouched(i) && Gdx.input.getY()<= 400) {
player1TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
camera.unproject(player1TouchPosition);
}
player1Tmp.set(player1TouchPosition.x, player1TouchPosition.y).sub(player1Rectangle.x, player1Rectangle.y);
if (player1Tmp.len() <= maxDistance) {
player1Rectangle.x = player1TouchPosition.x;
player1Rectangle.y = player1TouchPosition.y;
} else {
player1Tmp.nor().scl(maxDistance);
player1Rectangle.x += player1Tmp.x;
player1Rectangle.y += player1Tmp.y;
}
if (Gdx.input.isTouched(i) && Gdx.input.getY() >= 401) {
player2TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
camera.unproject(player2TouchPosition);
}
player2Tmp.set(player2TouchPosition.x, player2TouchPosition.y).sub(player2Rectangle.x, player2Rectangle.y);
if (player2Tmp.len() <= maxDistance) {
player2Rectangle.x = player2TouchPosition.x;
player2Rectangle.y = player2TouchPosition.y;
} else {
player2Tmp.nor().scl(maxDistance);
player2Rectangle.x += player2Tmp.x;
player2Rectangle.y += player2Tmp.y;
}
}
Two errors jump out at me:
You used getY() instead of getY(i) in a couple of places, so the criteria are mixed up for any pointer besides the most recent one.
You wrapped it all in a loop that runs 20 times, so you are moving each player 20 times a frame instead of one time each, at most. The movement should be applied outside the loop.
This problem is more complicated than it initially looks, because you have to deal with rejecting extra fingers on either side of the screen. Suppose pointer 1 is a finger on the top half of the screen. If pointer 2 is a finger on the top half, you want to reject it, but if it's on the bottom half, you want to use it to move player 2. If pointers 1 and 2 are both on the top, you want to accept pointer 3 only if it's on the bottom but you want to always reject it if pointers 1 and 2 are on opposite sides.
Furthermore, if only one finger is down, but it slides across the boundary to the other side, you want to be sure you don't let it start controlling the opposite player.
Here's one possible strategy. Track the first pointer down on each side and reset it whenever the tracked pointer is released. Only update target positions for the two currently tracked pointers.
private int player1Pointer = -1, player2Pointer = -1;
// render():
//stop tracking released fingers
if (player1Pointer >=0 && !Gdx.input.isTouched(player1Pointer))
player1Pointer = -1;
if (player2Pointer >=0 && !Gdx.input.isTouched(player2Pointer))
player2Pointer = -1;
//check for new pointers and update target positions
for (int i = 0; i<20; i++){
if (!Gdx.input.isTouched(i))
continue;
if (Gdx.input.getY(i) <= 400){ //bottom, player 1
if (player2Pointer == i)
continue; //player 2 slid finger across boundary, ignore it
if (player1Pointer < 0)
player1Pointer = i; //first finger down on this side of screen, track it
if (player1Pointer == i){ //this is the tracked finger, update target
player1TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
camera.unproject(player1TouchPosition);
}
} else { //top, player 2
if (player1Pointer == i)
continue;
if (player2Pointer < 0)
player2Pointer = i;
if (player2Pointer == i){
player2TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
camera.unproject(player2TouchPosition);
}
}
}
//update movement toward targets
maxDistance = 10 * Gdx.graphics.getDeltaTime();
temp.set(player1TouchPosition.x, player1TouchPosition.y).sub(player1Rectangle.x, player1Rectangle.y);
if (temp.len() <= maxDistance) {
player1Rectangle.x = player1TouchPosition.x;
player1Rectangle.y = player1TouchPosition.y;
} else {
temp.nor().scl(maxDistance);
player1Rectangle.x += temp.x;
player1Rectangle.y += temp.y;
}
temp.set(player2TouchPosition.x, player2TouchPosition.y).sub(player2Rectangle.x, player2Rectangle.y);
if (temp.len() <= maxDistance) {
player2Rectangle.x = player2TouchPosition.x;
player2Rectangle.y = player2TouchPosition.y;
} else {
temp.nor().scl(maxDistance);
player2Rectangle.x += temp.x;
player2Rectangle.y += temp.y;
}

Collision Detection Error

I am currently working on a relatively simple platform game that has an odd bug. You start the game by falling onto the ground (you spawn a few blocks above the ground), but when you land your feet get stuck INSIDE the world and you can't move until you jump. Here's what I mean:
http://i.imgur.com/IKLZY.png
The player's feet are a few pixels below the ground level. However, this problem only occurs in 3 places throughout the map and only in those 3 select places. I'm assuming that the problem lies within my collision detection code but I'm not entirely sure, as I don't get an error when it happens.
public boolean isCollidingWithBlock(Point pt1, Point pt2) {
//Checks x
for(int x = (int) (this.x / Tile.tileSize); x < (int) (this.x / Tile.tileSize + 4); x++) {
//Checks y
for(int y = (int) (this.y / Tile.tileSize); y < (int) (this.y / Tile.tileSize + 4); y++) {
if(x >= 0 && y >= 0 && x < Component.dungeon.block.length && y < Component.dungeon.block[0].length) {
//If the block is not air
if(Component.dungeon.block[x][y].id != Tile.air) {
//If the player is in contact with point one or two on the block
if(Component.dungeon.block[x][y].contains(pt1) || Component.dungeon.block[x][y].contains(pt2)) {
//Checks for specific blocks
if(Component.dungeon.block[x][y].id == Tile.portalBlock) {
Component.isLevelDone = true;
}
if(Component.dungeon.block[x][y].id == Tile.spike) {
Health.health -= 1;
Component.isJumping = true;
if(Health.health == 0) {
Component.isDead = true;
}
}
return true;
}
}
}
}
}
return false;
}
What I'm asking is how I would fix the problem. I've looked over my code for quite a while and I'm not sure what's wrong with it. Also, if there's a more efficient way to do my collision checking then please let me know!
I hope that is enough information, if it's not just tell me what you need and I'll be sure to add it.
Thank you!
The problem probably isn't your collision check, but your logic of what to do on collision. Your character is falling into the block which once in there is always colliding with the block. So it won't be able to jump (since you check for collision when jumping I guess). When you check for collision you have to make sure your character doesn't fall into the block by pre-checking and adjusting.
if (will collide) {
put beside block
}
You're probably doing something like
if (colliding) {
stop moving
}
When putting beside though, you have to check which way you're moving and that you don't move into blocks.

2D Collision Detection between squares, simple but more specific than boolean + immune to large spacial jumps

Would like to know which direction player hits terrain tile from (just a simple up/down, left/right). Everything I find is either too simple, or is much more complex and seemingly way too much for what I need, like with AABB (granted it's hard to tell, my brain has trouble digesting what amounts to really long equations). What I've got so far is the result of spending better part of today reading and experimenting:
public int move(double toX, double toY) {
int col = COLLISION_NONE; //these are bit flags, in case I collide with a block to my right as well as below me
double nextX = mX+(toX*main.getDelta()); //delta regulates speed
double nextY = mY+(toY*main.getDelta());
if(mTerrainCollision){
int w = GameView.GameLoop.TILE_WIDTH;
int h = GameView.GameLoop.TILE_HEIGHT;
for(int i = -2; i <= 2; i++) //broad tile picking will be optimized later, better trace around players path
for(int j = -2; j <= 2; j++) {
GameTerrain.Block block = main.mTerrain.get(((int)Math.round(mX)/w)+i,((int)Math.round(mY)/h)+j);
if(block.type != GameTerrain.BLOCK_TYPE_NONE) {
if(nextX+w >= block.x() && mX+w <= block.x()){ //COLLISION ON THE RIGHT?
if(mY+h > block.y() && mY < block.y()+h) { //<THIS is a problem line, see below
nextX = block.x() - w;
xMomentum = 0;
col |= COLLISION_RIGHT;
}
}
else if(nextX < block.x()+w && mX >= block.x()+w){ //COLLISION ON THE LEFT?
if(mY+h > block.y() && mY < block.y()+h) { //same as above, make sure were on the same plane
nextX = block.x() + w;
xMomentum = 0;
col |= COLLISION_LEFT;
}
}
if(nextY+h >= block.y() && mY+h <= block.y()){ //COLLISION ON THE BOTTOM?
if(mX+w > block.x() && mX < block.x()+w) { //make sure were on the same plane
nextY = block.y() - h;
yMomentum = 0;
col |= COLLISION_DOWN;
}
}
else if(nextY < block.y()+h && mY >= block.y()+h){ //COLLISION ON THE TOP?
if(mX+w > block.x() && mX < block.x()+w) { //make sure were on the same plane
nextY = block.y() + h;
yMomentum = 0;
col |= COLLISION_UP;
}
}
}
}
}
mX = nextX;
mY = nextY;
return col;
}
It works... mostly. Player won't phase through blocks even after long sleeps making the delta skyrocket. The collision detection itself works unless the player's previous position (mX/mY) are not on the same plane as the block we're checking (see commented line with "THIS..."). Say we're perfectly diagonal to a block and moving straight for it, player will zip right through. I've been scratching my head for a while now trying to figure out how to go about solving this last issue, preferably without a major rehaul of everything, but if it had to come to that oh well! I'm only interested in simple collision data for things like "Did I touch a floor this frame? Ok I can jump", "Am I touching a wall right now? Ok I can wall jump, but not if I also touched a floor", etc.
Grow the wall's AABB by the size of the object's AABB (keeping the center of the wall's AABB fixed), construct a line segment from the object's before and after positions (use the center of the object's AABB), then do a segment-AABB intersection test.

Categories