【问题标题】:android: move to touch location after release with libgdx/universal-tween-engineandroid:使用 libgdx/universal-tween-engine 发布后移动到触摸位置
【发布时间】:2012-06-26 03:40:56
【问题描述】:

我正在学习将 libgdx 与 Universal-tween-engine 一起使用,但无法弄清楚如何触摸(或单击桌面应用程序)屏幕上的一个点并让纹理一直移动到在到达终点之前不保持触摸或单击处于活动状态的触摸位置。

当触摸事件启动时,动画开始并且图形向该位置移动。如果启动触摸和拖动,图形将跟随手指/鼠标指针。如果我触摸一个点,图形将向该点移动,直到触摸被释放。然后它会停在释放触摸时的位置。

我正在寻找触摸和释放并将该图形移动到触摸点,并且我可能不了解有关补间引擎实现的某些内容。我在下面粘贴了补间代码。

    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;
                    }
            }

    }

最初,我在isTouched() 的条件中添加了补间代码,并且没有使用newXnewYanimateOn 变量。我认为使用isTouched() 只设置新的坐标和动画状态会使循环触发补间。旧代码如下所示:

    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);
    }

我也尝试过使用justTouched(),但图形只会向触摸点略微移动。

我已经为此苦苦挣扎了几个小时,如果有人能指出我正确的方向,我将不胜感激。

谢谢。

【问题讨论】:

    标签: android libgdx tween


    【解决方案1】:
    Tween.registerAccessor(Plane.class, new TextureAccessor());
    TweenManager planeManager = new TweenManager();
    

    这两行应该放在create() 方法中,而不是render() 之一!在这里,您在每一帧上都实例化了一个新的经理,您只需要一个经理,仅此而已,而不是一大群人!

    此外,您需要在每一帧更新管理器,而不仅仅是在 animateOn 为真时,否则您需要保持手指按下...

    正确的代码如下,从中学习,你会更好地理解 Tween Engine 的工作原理:)

    // 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);
        }
    }
    

    【讨论】:

    • 感谢您的回复和正确答案。在我的手机上进行测试时,我会遇到内存问题,并摆脱了遍布各处的多个补间管理器。那个 animateOn 是一个基于回合的模块的开始,我可能应该把它排除在外。感谢您的帮助和很棒的图书馆。
    【解决方案2】:

    我试图以错误的方式实现此行为。我需要使用来自GestureListenertouchDown(),而不是使用isTouchedjustTouched()

    我在主 libgdx 项目的主类(实现 ApplicationLisetener 的那个)内部创建了一个实现 GestureDetector 的类(称为 touchListener()),并将 x 和 y 捕获代码放在 toucDown 中(我注意到tap() 也被触发)。我将补间函数(实际补间、对registerAccessor() 的调用以及新补间管理器的创建)移动到touchListener()update() 方法中。

    我在主 libgdx 类的 render() 循环内添加了对 touchListener() 更新函数的调用。

    我怀疑我这样做是最好的方法,但我希望它对将来的其他人有所帮助。

    【讨论】:

    • 这不是最好的方法,实际上它可以工作,因为你很幸运 :) 你真的不应该在触摸监听器中创建一个新的补间管理器。在一个项目中只需要一个经理。它就像 Spritebatch 或相机。您只需创建它们的一个实例 :) 查看我的答案以获得正确的解决方案,它将指导您使用补间引擎。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多