Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android: move to touch location after release with libgdx/universal-tween-engine

I'm learning to use libgdx with universal-tween-engine and haven't been able to figure out how to touch (or click on the desktop app) a point on the screen and have a texture move all the way to the touched location without keeping the touch or click active until the end-point is reached.

When the touch event is initiated, the animation begins and the graphic moves towards the location. The graphic will follow the finger/mouse-pointer if a touch and drag is initiated. If I touch a point, the graphic will move towards the point until the touch is released. Then it stops where it was when touch is released.

I'm looking to touch-and-release and have that graphic move to the touched point, and am probably not understanding something about the tween engine implementation. I've pasted the tweening code below.

    public void render() {

            camera.update();

            batch.setProjectionMatrix(camera.combined);
            batch.begin();
            batch.draw(texture.getTexture(), texture.getBoundingBox().x, texture.getBoundingBox().y);
            batch.end();

            Tween.registerAccessor(Plane.class, new TextureAccessor());
            TweenManager planeManager = new TweenManager();

            float newX = 0;
            float newY = 0;
            boolean animateOn = false;

            if(Gdx.input.isTouched()) {
                    newX = Gdx.input.getX();

                    newY = Gdx.input.getY();

                    animateOn = true;
            }

            if (animateOn == true && (texture.getX() != newX || texture.getY() != newY)) {
                Tween.to(texture, TextureAccessor.POSITION_XY, 10)
                    .target(newX, newY)
                    .ease(TweenEquations.easeNone)
                    .start(planeManager);

                    planeManager.update(1);

                    if (texture.getX() == newX && texture.getY() == newY) {
                        animateOn = false;
                    }
            }

    }

Originally, I had the tweening code inside the conditional for isTouched() and didn't use the newX, newY or animateOn variables. I thought using isTouched() to only set the new coordinates and animation state would then make the loop trigger the tween. The older code looked like this:

    if(Gdx.input.isTouched()) {
            newX = Gdx.input.getX();

            newY = Gdx.input.getY();

            Tween.to(texture, TextureAccessor.POSITION_XY, 10)
                .target(newX, newY)
                .ease(TweenEquations.easeNone)
                .start(planeManager);

            planeManager.update(1);
    }

I've also tried using justTouched(), but the graphic would only move very slightly toward the touched point.

I've been struggling with this for a few hours, I'd really appreciate it if anyone could point me in the right direction.

Thanks.

like image 243
nils Avatar asked Feb 21 '23 01:02

nils


1 Answers

Tween.registerAccessor(Plane.class, new TextureAccessor());
TweenManager planeManager = new TweenManager();

These two lines should go in the create() method, not the render() one! Here, you're instantiating a new manager on every frame, you only need one manager, that's all, not an army of them!

Also, you need to update the manager on every frame, not just when animateOn is true, else you'll need to keep your finger pressed...

The correct code is as follows, learn from it, you'll get a better understanding of how the Tween Engine works :)

// Only one manager is needed, like a Spritebatch
private TweenManager planeManager;

public void create() {
    Tween.registerAccessor(Plane.class, new TextureAccessor());
    planeManager = new TweenManager();
}

public void render() {
    // The manager needs to be updated on every frame.
    planeManager.update(Gdx.graphics.getDeltaTime());

    camera.update();

    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    batch.draw(texture.getTexture(), texture.getBoundingBox().x, texture.getBoundingBox().y);
    batch.end();

    // When the user touches the screen, we start an animation.
    // The animation is managed by the TweenManager, so there is
    // no need to use an "animateOn" boolean.
    if (Gdx.input.justTouched()) {
        // Bonus: if there is already an animation running,
        // we kill it to prevent conflicts with the new animation.
        planeManager.killTarget(texture);

        // Fire the animation! :D
        Tween.to(texture, TextureAccessor.POSITION_XY, 10)
            .target(Gdx.input.getX(), Gdx.input.getY())
            .ease(TweenEquations.easeNone)
            .start(planeManager);
    }
}
like image 188
Aurelien Ribon Avatar answered Mar 22 '23 23:03

Aurelien Ribon