I am trying to make a sprite walk to the mouse position. However, when the mouse is clicked and the sprite walks to the mouse position, it won't stop and keeps moving in the same direction.
Here's my code:
public void render(float delta) {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
if(Gdx.input.isTouched()){
projected= new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
cam.unproject(projected);
if(position.x != projected.x || position.y != projected.y){
pathX = projected.x - position.x;
pathY = projected.y - position.y;
distance = (float) Math.sqrt(pathX * pathX + pathY * pathY);
directionX = pathX / distance;
directionY = pathY / distance;
}
}
position.x += directionX * Speed * delta;
position.y += directionY * Speed * delta;
}
Please help and thank you so much.
This is basically a duplicate of How to stop drawing a SpriteBatch animation in libgdx? || how do I pause the SpriteAnimation in libGDX with a button to be able to view the current frame when pause button is pressed? , check out this article to see if it helps.
In short, you want to keep track of the player moving and when they get to the x, y coordinates of your mouse, set the moving to false. Have the logic within your render to only render when your boolean is true.
Related
Currently iam programming on a game where you move a spaceship and try to avoid asteroids. The spaceship should move when the user touches it and so follow the finger movement of the user.
The spaceship is a sprite that moves arround with:
if (Gdx.input.isTouched()) {
x = Gdx.input.getX() - width / 2;
y = -Gdx.input.getY() + height / 2;
}
The problem that i'm having right now is that the user can teleport the spaceship by touching the screen. How can i fix this? Is it possible to set a touch region?
Calculate a unit vector direction from the ship to the touch point and multiply that by a speed. You need to convert touch coordinates to world coordinates by unprojecting with the camera.
private static final float SHIP_MAX_SPEED = 50f; //units per second
private final Vector2 tmpVec2 = new Vector2();
private final Vector3 tmpVec3 = new Vector3();
//...
if (Gdx.input.isTouched()) {
camera.unproject(tmpVec3.set(Gdx.input.getX(), Gdx.input.getY(), 0)); //touch point to world coordinate system.
tmpVec2.set(tmpVec3.x, tmpVec3.y).sub(x, y); //vector from ship to touch point
float maxDistance = SHIP_MAX_SPEED * Gdx.graphics.getDeltaTime(); //max distance ship can move this frame
if (tmpVec2.len() <= maxDistance) {
x = tmpVec3.x;
y = tmpVec3.y;
} else {
tmpVec2.nor().scl(maxDistance); //reduce vector to max distance length
x += tmpVec2.x;
y += tmpVec2.y;
}
}
So I am making my bullets go to a point and travel further. Only its acting really really weird. Its like its thinking that the 0,0 location is at the top left instead of the bottom left.
This is the code:
float speed = 100;
Vector2 direction;
Vector2 thisPos = new Vector2(getX(), getY());
Vector2 mousePos;
public Bullet(){
super();
setSprite(sprite);
setX(0); setY(0);
float dx = Gdx.input.getX() - getX();
float dy = Gdx.input.getY() - getY();
mousePos = new Vector2(Gdx.input.getX(), Gdx.input.getY());
direction = new Vector2(dx, dy);
//sprite.setRotation(direction.angle(thisPos));
direction.nor();
}
public void update(){
Vector2 dirAd = new Vector2(direction);
thisPos.x += dirAd.x * speed * Gdx.graphics.getDeltaTime();
thisPos.y += dirAd.y * speed * Gdx.graphics.getDeltaTime();
setPosition(thisPos.x, thisPos.y);
super.update();
}
I hope someone can help me what I did wrong with this.
Gdx.input.getX() and getY() by definition do treat the top left as 0,0. From the getX() method:
"The screen origin is the top left corner."
You may need to look into the camera's unproject method, which takes the screen input coordinates and translates them to "world" space.
While practicing wanted to create basic game-kind-of(?) - there is just a basic shape (rectangle) and you move forward with one button, move backwards with another, and rotate it with 2 additional buttons, that shape as well should move to other direction accordingly to it's rotation. What i have done so far is:
Input handling:
if (input.isKeyDown(Input.KEY_UP)) {
rectX += Math.cos(Math.toRadians(rotation)) * (0.2*delta);
rectY += Math.sin(Math.toRadians(rotation)) * (0.2*delta);
}
if (input.isKeyDown(Input.KEY_DOWN)) {
rectX -= Math.cos(Math.toRadians(rotation)) * (0.2*delta);
rectY -= Math.sin(Math.toRadians(rotation)) * (0.2*delta);
}
if(input.isKeyDown(Input.KEY_LEFT)){
rotation-=(0.1*delta);
rectangle = rectangle.transform(Transform.createRotateTransform(rotation, rectX, rectY));
if(rotation <= 0f) {
rotation = 360f;
}
}
if(input.isKeyDown(Input.KEY_RIGHT)){
rotation+=(0.1*delta);
rectangle = rectangle.transform(Transform.createRotateTransform(rotation, rectX, rectY));
if(rotation >= 360f) {
rotation = 0f;
}
}
rectangle.setCenterX(rectX);
rectangle.setCenterY(rectY);
}
rectX, rectY are obviously center coordinates of rectangle (floats)
and rotation is... well rotation..
And I think that's it, other code isn't worth mentioning.
In my opinion this should work, but the thing is while movement direction is changin at normal speed, my rectangle is spinning wildly, probably about 100 times or so faster than its movement direction.
Delta is the number of milliseconds since the last call to update().
I am trying to get my bullets to fire towards (input coords) at a constant speed.
So far I was able to get it to shoot at the direction but the farther I click (touch, android game) the faster the bullet goes. I have tried different methods by scaling but failed miserably, I have started coding just a month ago and using this as a project to increase my knowledge of how things work before I work on a full game but having too much trouble with this.
This is what I have been using to get the bullet to move towards the direction I want it to, the codes with // in front were other samples I got while browsing through the internet in hopes of getting what I wanted. I have thought of not using velocity to set the direction, but I have no clue of another method for this.
EDIT: All in short, I cannot get all the bullets to move in the same speed, farther I click, higher velocity bullet has.
Any help guys? Thanks a bunch
Player Class :
public void update(float delta) {
if (Gdx.input.isTouched()) {
if (System.currentTimeMillis() - lastShot >= FIRE_RATE) {
bullets.add(new Bullet(position.x + 6,position.y + 6,4,4,Gdx.input.getX() / 2,Gdx.input.getY() / 2));
lastShot = System.currentTimeMillis();
}
}
for (int i=0;i<bullets.size();i++) {
bullets.get(i).update(delta);
}
}
Bullet Class :
public Bullet(float x, float y, int width, int height, float targetX, float targetY) {
this.width = width;
this.height = height;
position = new Vector2( x , y );
velocity = new Vector2( 0 , 0 );
velocity.set(targetX - position.x,targetY - position.y);
//velocity.set(targetX - position.x, targetY - position.y).nor().scl(Math.min(position.dst(targetX, targetY), speedMax));
}
public void update(float deltaTime) {
//position.add(position.x + speedMax * deltaTime * ax,position.y + speedMax * deltaTime * ay);
position.add(velocity.x * deltaTime, velocity.y * deltaTime);
//velocity.scl(1 - (0.98f * deltaTime));
// Linear dampening, otherwise the ball will keep going at the original velocity forever
}
Well, normalizing vectors should be rather straightforward. Take your components, square them, and add them together (pythagorean theorem) and then divide each component by this result. I.e. vX = (targetX - position.x)/Math.sqrt(((targetX - position.x) * (targetX - position.x)) + ((targetY - position.y) *(targetY - position.y )))
Then you can multiply vX by some constant, and do the same for a vY and then set your velocity.
So I'm trying to implement a simple mouseLook method for exploring a game world in LWJGL. For now I just want it to work on the rotation-Y axis. The movement at first was limited because of the dimensions of the screen stopped the mouse from moving. So i hid the cursor and set the x-position of the mouse to 0 after deltaX is returned. When i wrote it out on paper the calculations seem to be right I think, however when i run it, the rotation keeps snapping back to 0, and creates a jitter effect. How can i solve this?
public void rotate() { //rotate the camera
System.out.println(getGlobalDX() + " " + MouseInfo.getPointerInfo().getLocation().getX());
float speed = 0.03f;
//START OF CODE TO IGNORE
float ratioX = (float)Display.getWidth() / 360;
float ratioY = (float)Display.getHeight() / 360;
float mouseRotX = Mouse.getX() / ratioX;
float mouseRotY = Mouse.getY() / ratioY;
//END OF CODE TO IGNORE
rotY += getGlobalDX() * speed; // add the deltaX of the mouse position X and multiply it by our speed in order to rotate the camera based on the mouse
lockCursor();
}
public float getGlobalDX() { //returns the difference between the current mouse position and the mouse position during the last frame
frames += 1; //add 1 to frames variable every frame
if(frames >= 1.5) { //if 1.5 frames have passed since last method call, run method again. this is to smooth things out since it doesnt work properly every frame
float mouseX = (float) MouseInfo.getPointerInfo().getLocation().getX(); //get x pos of mouse
frames = 0; //set frames to zero
if(lastMouseX != mouseX) { //if the lastmouse position isnt equal to our current mouse position, then continue
if(mouseX == 963) { //if the mouse position is equal to the centered X position of the screen then continue
lastMouseX = (float) MouseInfo.getPointerInfo().getLocation().getX(); //set this variable to the new x position
System.out.println("returning zero"); //debug by checking if this code runs (it does)
return 0; //return 0 since we dont want to undo the position we returned last frame
}
float deltaX = (float) (mouseX - lastMouseX); // difference between current mouse position and last to get the overall change in position
lastMouseX = (float) MouseInfo.getPointerInfo().getLocation().getX(); //set to new x position
MouseInfo.getPointerInfo().getLocation().setLocation(MouseInfo.getPointerInfo().getLocation().getX()/2, MouseInfo.getPointerInfo().getLocation().getY()/2); // set mouse position to 0 for infinite movement
return deltaX; //return the overall change in position and add it to the rotation Y of our camera
} else { // return 0 if the lastMouse position is equal to the current mouse position, since there was no change in position
return 0;
}
} else { //return 0 since a frame was skipped
return 0;
}
}
Rather than resetting the position of the mouse yourself just call Mouse.setGrabbed(true) before you start using the mouse for this.