Search code examples
javamathlibgdxtransferangle

Moving a point (vector) on an angle + Libgdx


i wanna move a point (Vector2) on an angle. i have my angle. but i'm not good in math or libgdx. for getting angle i use this :

degrees = (float) ((Math.atan2(touchPoint.x - x,
                -(touchPoint.y - y)) * 180.0d / Math.PI) + 240.0f);

now, i want to move vector. but i really don't know what i must do... i looked at questions but there was just somethings about changing angle, not transfer. i think there must be a function for this in libgdx. please help.

UPDATE :

public class Games implements ApplicationListener {

SpriteBatch spriteBatch;
Texture texture;
float x = 160;
float y = 5;

Vector2 touch;
Vector2 movement;
Vector2 position;
Vector2 dir;
Vector2 velocity;

float speed;
float deltaTime;

@Override
public void create() {
    spriteBatch = new SpriteBatch();
    texture = new Texture(Gdx.files.internal("images/1.png"));

    touch = new Vector2();
    movement = new Vector2();
    position = new Vector2();
    dir = new Vector2();
    velocity = new Vector2();

    speed = 5;
    deltaTime = Gdx.graphics.getDeltaTime();
}

public void render() {
    Gdx.gl.glClear(Gdx.gl10.GL_COLOR_BUFFER_BIT);
    deltaTime += 0.5f;

    spriteBatch.begin();

    begin(deltaTime);
    spriteBatch.draw(texture, position.x, position.y);

    spriteBatch.end();
}

private void begin(float deltaTime) {
    touch.set(Gdx.input.getX(), Gdx.input.getY());

    position.set(x, y);
    dir.set(touch).sub(position).nor();
    velocity.set(dir).scl(speed);
    movement.set(velocity).scl(deltaTime);
    position.add(movement);
}

Solution

  • If I am understanding your question correctly, you are looking for a direction vector?

    If that is a correct understanding, you can do something like this:

    // Declared as fields, so they will be reused
    Vector2 position = new Vector2();
    Vector2 velocity = new Vector2();
    Vector2 movement = new Vector2();
    
    Vector2 touch = new Vector2();
    Vector2 dir = new Vector2();
    
    // On touch events, set the touch vector, then do this to get the direction vector
    dir.set(touch).sub(position).nor();
    

    Which will give you a normalized direction vector from the position to the touch point.

    You can then scale it to the speed you want to move, then use it to update your position.

    velocity = new Vector2(dir).scl(speed);
    

    And on each frame, do something like this

    movement.set(velocity).scl(deltaTime);
    position.add(movement);
    

    Update

    Here's how it would look like in a full class:

    class Game extends ApplicationAdapter {
    
        Vector2 position = new Vector2();
        Vector2 velocity = new Vector2();
        Vector2 movement = new Vector2();
        Vector2 touch = new Vector2();
        Vector2 dir = new Vector2();
    
        Vector3 temp = new Vector3();
    
        float speed = 100;
    
        OrthographicCamera camera;
    
        SpriteBatch batch;
        Texture texture;
        Sprite sprite;
    
        @Override
        public void create () {
            camera = new OrthographicCamera();
            camera.setToOrtho(false);
    
            batch = new SpriteBatch();
    
            texture = new Texture(Gdx.files.internal("data/badlogicsmall.jpg"));
    
            sprite = new Sprite(texture);
    
            Gdx.input.setInputProcessor(new InputAdapter() {
                @Override
                public boolean touchDown (int screenX, int screenY, int pointer, int button) {
                    camera.unproject(temp.set(screenX, screenY, 0));
                    touch.set(temp.x, temp.y);
                    return true;
                }
            });
        }
    
        @Override
        public void render () {
            Gdx.gl10.glClear(GL10.GL_COLOR_BUFFER_BIT);
            update(Gdx.graphics.getDeltaTime());
            batch.begin();
            sprite.draw(batch);
            batch.end();
        }
    
        @Override
        public void dispose() {
            texture.dispose();
            batch.dispose();            
        }
        public void update (float deltaTime) {
            position.set(sprite.getX(), sprite.getY());
            dir.set(touch).sub(position).nor();
            velocity.set(dir).scl(speed);
            movement.set(velocity).scl(deltaTime);
            if (position.dst2(touch) > movement.len2()) {
                position.add(movement); 
            } else {
                position.set(touch);
            }               
            sprite.setX(position.x);
            sprite.setY(position.y);
        }
    }
    

    Note, you could do away with the position Vector2 and just use the x and y directly, but I like to use use a Vector2 because it is a bit cleaner.