libgdx - 触摸并拖动不起作用(滞后并在2处显示)

时间:2015-10-05 22:40:45

标签: android libgdx touch

所以我编辑了这篇文章并使用当前代码进行了更新。 当我在LetterActor中将unproject设置为false时,我可以拖动字母但不正确,它们会落在我的手指后面,并且不会在我释放触摸的地方结束。 当我触摸它时,字母/演员也被画在两个地方。它在两个位置之间闪烁。

当我将unproject设置为true时,屏幕上根本没有显示任何内容。

我错过了什么?

如果我正确地进行unproject,则会将您从屏幕上的coirdinates带到游戏坐标,游戏坐标是游戏的内部表示。但是你必须定义游戏坐标和屏幕坐标如何相互关联或者如何取消项目知道该怎么做?这是怎么做到的? 当你再次画到屏幕上时,你不应该再投影吗?

我认为: 1.取消项目以获取事件的内部游戏坐标 2.使用新事件更新内部游戏表示 3.重新获得屏幕坐标的项目

package com.xxxx.yyyy;

import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;

public class LetterActor extends Actor
{
    private Texture texture;
    private Vector3 touchPosition = new Vector3();
    private Camera camera;
    private boolean unproject = true;

    public LetterActor(Texture letterTexture, Camera theCamera)
    {
        texture = letterTexture;
        camera = theCamera;

        touchPosition.set(0, 0, 0);
        camera.unproject(touchPosition);

        setSize(texture.getWidth(), texture.getHeight());

        addListener(new InputListener()
        {
            @Override
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
            {
                touchPosition.set(x, y, 0);
                if (unproject)
                {
                    camera.unproject(touchPosition);
                }
                setPosition(touchPosition.x, touchPosition.y);

                return true;
            }

            @Override
            public void touchUp(InputEvent event, float x, float y, int pointer, int button)
            {
                touchPosition.set(x, y, 0);
                if (unproject)
                {
                    camera.unproject(touchPosition);
                }
                setPosition(touchPosition.x, touchPosition.y);
            }

            @Override
            public void touchDragged(InputEvent event, float x, float y, int pointer)
            {
                touchPosition.set(x, y, 0);
                if (unproject)
                {
                    camera.unproject(touchPosition);
                }
                setPosition(touchPosition.x, touchPosition.y);
            }
        });
    }

    @Override
    public void draw(Batch batch, float alpha){
        batch.draw(texture, getX(), getY(), getWidth(), getHeight());
    }

    @Override
    public void act(float delta){
        //setBounds(getX(), getY(),getWidth(), getHeight());
    }
}



package com.xxxx.yyyy;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;

public class LetterLoader {

    public static Texture[] loadLetters()
    {
        Texture[] letters = new Texture[26];

        for (int i = 0; i < 26; i++)
        {
            char letter = (char) (i + 65);
            letters[i] = new Texture(Gdx.files.internal("bigletters/" + letter + ".png"));
        }

        return letters;
    }
}





package com.xxxx.yyyy;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.utils.viewport.ExtendViewport;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.Touchable;

public class WordPuzzle extends ApplicationAdapter
{
    private final static float SCALE = 4f;
    private final static float INV_SCALE = 1.f / SCALE;

    private final static float VP_WIDTH = 1280 * INV_SCALE;
    private final static float VP_HEIGHT = 720 * INV_SCALE;

    private OrthographicCamera camera;
    private ExtendViewport viewport;
    private Stage stage;

    private LetterActor letterActor;

    @Override
    public void create()
    {
        camera = new OrthographicCamera();
        viewport = new ExtendViewport(VP_WIDTH, VP_HEIGHT, camera);
        stage = new Stage();
        stage.setViewport(viewport);
        Gdx.input.setInputProcessor(stage);
        Texture[] textures = LetterLoader.loadLetters();
        for (int i = 0; i < textures.length; i++)
        {
            letterActor = new LetterActor(textures[i], camera);
            letterActor.setTouchable(Touchable.enabled);
            stage.addActor(letterActor);
        }
    }

    @Override
    public void render()
    {
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

        stage.act(Gdx.graphics.getDeltaTime());
        stage.draw();
    }


    @Override public void resize(int width, int height)
    {
        viewport.update(width, height, true);
    }

    @Override public void dispose()
    {
        stage.dispose();
    }
}

1 个答案:

答案 0 :(得分:1)

在你原来的问题中,绘制位置的翻转可能是你一遍又一遍地调用setBounds。我不确定。

回答新问题:如果您没有使用Scene2D,则需要通过取消投影将屏幕坐标转换为世界坐标。这是由相机完成的。摄像机保存定义世界坐标系如何投影到屏幕坐标系的数据,因此可以进行计算以来回投影和取消投影。但是你错了,你需要在对新坐标作出反应后投射到屏幕坐标。当它将场景投影到屏幕时,它会在着色器中处理,除非使用自定义着色器,否则您不必担心它。您只需使用世界坐标,只需在移动屏幕坐标时取消投影。

但是,之前我错过的是您使用Stage及其关联的InputListener。屏幕在将屏幕坐标提供给InputListener之前取消投影,因此您根本不必担心未投影或投影!

我原来回答的相关信息:

从班级中删除actorXactorY,因为它们是多余的。请改用getX()getY()setX()setY()setPosition()等。

您也不需要一遍又一遍地呼叫setBounds。在实例化类时,只需调用setSize()一次。只要您拨打setPosition(),边界就会自动更新。 (我注意到你设置的边界是纹理大小的两倍。也许你正在补偿它没有正确投影?)

对于draw方法,您应该使用getX()getY(),我认为您还希望将其绘制为与其边界相同的大小,因此也使用{{ 1}}和getWidth()

getHeight()