Java 使用libgdx触摸滚动

Java 使用libgdx触摸滚动,java,libgdx,Java,Libgdx,我正在尝试在libgdx游戏中实现触摸滚动。我有一个很宽的图像,是一个房间的全景。我希望能够滚动图像,以便用户可以看到周围的房间。我有它,这样我可以滚动一定的距离,但当一个新的触摸拖动事件被注册时,图像会移回原始位置 这就是我实现它的方式 public class AttackGame implements ApplicationListener { AttackInputProcessor inputProcessor; Texture backgroundTexture; Texture

我正在尝试在libgdx游戏中实现触摸滚动。我有一个很宽的图像,是一个房间的全景。我希望能够滚动图像,以便用户可以看到周围的房间。我有它,这样我可以滚动一定的距离,但当一个新的触摸拖动事件被注册时,图像会移回原始位置

这就是我实现它的方式

public class AttackGame implements ApplicationListener {

AttackInputProcessor inputProcessor;
Texture backgroundTexture; 
TextureRegion region;
OrthographicCamera cam;
SpriteBatch batch;
float width;
float height;
float posX;
float posY;

@Override
public void create() {
    posX = 0;
    posY = 0;
    width = Gdx.graphics.getWidth();
    height = Gdx.graphics.getHeight();  
    backgroundTexture = new Texture("data/pancellar.jpg");
    region = new TextureRegion(backgroundTexture, 0, 0, width, height);
    batch = new SpriteBatch();

}

@Override
public void resize(int width, int height) {
    cam = new OrthographicCamera();
    cam.setToOrtho(false, width, height);
    cam.translate(width / 2, height / 2, 0);
    inputProcessor = new AttackInputProcessor(width, height, cam);
    Gdx.input.setInputProcessor(inputProcessor);

}

@Override
public void render() {

    Gdx.gl.glClearColor(0,0,0,1);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    
    batch.setProjectionMatrix(cam.combined);
    batch.begin();
    batch.draw(backgroundTexture, 0, 0, 2400, 460);
    batch.end();

}

@Override
public void pause() {
    // TODO Auto-generated method stub

}

@Override
public void resume() {
    // TODO Auto-generated method stub

}

@Override
public void dispose() {
    backgroundTexture.dispose();

}
}

在输入处理器中

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {

    cam.position.set(screenX, posY / 2, 0);
    cam.update();
    return false;
}
在这个问题的帮助下,我走了这么远。然而,这并不能真正解决我的问题

我认为问题在于触控拖动的corodinates不是世界坐标,但我尝试过取消投影相机,但没有效果

我已经为此挣扎了几个星期,我真的非常感谢在这方面的帮助


提前感谢。

我自己没有使用过,但我会先看一下以下代码:

你有没有看一下密码


请参阅:
touchDrawed

您需要在
touchDrawed
回调中进行更多计算,您不能将触摸到的任何屏幕坐标传递给相机。您需要了解用户将手指拖了多远,以及拖向了什么方向。绝对坐标不是立即有用的

考虑从右上角向下拖动或从左上角向下拖动。在这两种情况下,您都希望(我假定)将相机移动相同的距离,但在这两种情况下,屏幕坐标的绝对值将非常不同

我认为最简单的方法是只跟踪
previousX
previousY
(在
tounddown
方法中初始化它们。然后用delta调用
cam.translate()
deltaX=screenX-previousX
),并更新
触摸拖动
中的
上一个*


或者,您可以查看libgdx提供的一些更高级的
InputProcessor
wrappers(请参阅)。

我最近做了一些您想做的事情。这是我用于移动地图的输入类,您只需更改“cam”的“stage.getCamera()”:

public class MapInputProcessor implements InputProcessor {
    Vector3 last_touch_down = new Vector3();

    ...

    public boolean touchDragged(int x, int y, int pointer) {
        moveCamera( x, y );     
        return false;
    }

    private void moveCamera( int touch_x, int touch_y ) {
        Vector3 new_position = getNewCameraPosition( touch_x, touch_y );

        if( !cameraOutOfLimit( new_position ) )
            stage.getCamera().translate( new_position.sub( stage.getCamera().position ) );

        last_touch_down.set( touch_x, touch_y, 0);
    }

    private Vector3 getNewCameraPosition( int x, int y ) {
        Vector3 new_position = last_touch_down;
        new_position.sub(x, y, 0);
        new_position.y = -new_position.y;
        new_position.add( stage.getCamera().position );

        return new_position;
    }

    private boolean cameraOutOfLimit( Vector3 position ) {
        int x_left_limit = WINDOW_WIDHT / 2;
        int x_right_limit = terrain.getWidth() - WINDOW_WIDTH / 2;
        int y_bottom_limit = WINDOW_HEIGHT / 2;
        int y_top_limit = terrain.getHeight() - WINDOW_HEIGHT / 2;

        if( position.x < x_left_limit || position.x > x_right_limit )
            return true;
        else if( position.y < y_bottom_limit || position.y > y_top_limit )
            return true;
        else
          return false;
}


    ...
}
公共类MapInputProcessor实现InputProcessor{
Vector3 last_touch_down=新Vector3();
...
公共布尔值(整数x,整数y,整数指针){
移动摄像机(x,y);
返回false;
}
私人摄像机(点触摸x、点触摸y){
Vector3 new_position=getNewCameraPosition(触摸x,触摸y);
如果(!cameraOutOfLimit(新位置))
stage.getCamera().translate(新的_position.sub(stage.getCamera().position));
最后一次触摸。设置(触摸x,触摸y,0);
}
专用矢量3 getNewCameraPosition(整数x,整数y){
矢量3新位置=最后一次触摸;
新的位置sub(x,y,0);
new_position.y=-new_position.y;
新的位置。添加(stage.getCamera().position);
返回新的位置;
}
专用布尔cameraOutOfLimit(矢量3位置){
int x_left_limit=窗口宽度/2;
int x_right_limit=terrain.getWidth()-窗口宽度/2;
int y_bottom_limit=窗高/2;
int y_top_limit=terrain.getHeight()-窗口高度/2;
if(位置xx_右极限)
返回true;
else if(position.yy_top_limit)
返回true;
其他的
返回false;
}
...
}

这就是结果:

简单的答案:

声明两个字段以保存新的和旧的拖动位置:

Vector2 dragOld, dragNew;
当您刚刚触摸时,将这两个设置为与触摸位置相等,否则您的凸轮将跳动

if (Gdx.input.justTouched())
{
    dragNew = new Vector2(Gdx.input.getX(), Gdx.input.getY());
    dragOld = dragNew;
}
更新dragNew每个帧,并简单地从彼此减去矢量,以获得平移相机的x和y

if (Gdx.input.isTouched())
    {
        dragNew = new Vector2(Gdx.input.getX(), Gdx.input.getY());
        if (!dragNew.equals(dragOld))
        {
            cam.translate(dragOld.x - dragNew.x, dragNew.y - dragOld.y); //Translate by subtracting the vectors
            cam.update();
            dragOld = dragNew; //Drag old becomes drag new.
        }
    }

这是我用来拖动正交摄像机的全部,简单而有效。

使用了drinor的答案,但添加了“触地”功能,因此不会在每次再次拖动时重置摄像机:

@Override
        public boolean touchDown(int screenX, int screenY, int pointer, int button) {
            last_touch_down.set( screenX, screenY, 0);
            return false;
        }

谢谢,这看起来很有趣。我看了ScrollPane,但放弃了它,它会有滚动条,这不是我想要的,但它看起来没有滚动条,所以可能是完美的。在最坏的情况下,你可以找到一些接近你想要实现的代码…刚刚发现一个六月底的Badlogic游戏博客,上面写着FlickScoll窗格已不再使用,但ScrollPane具有所有功能,scrollbar Drawable是可选的,因此看起来ScrollPane是现在的发展方向。这看起来可能是答案,请您将cameraOutOfLimit的实现包括在内,因为这是我遇到问题的部分。我尝试过ScrollPane,它可以工作,但我可以向场景中添加一个新演员,并使其与背景一起滚动。我添加了cameraOutOfLimit函数。我希望它会有所帮助。这与P.T.建议的gestureListener结合使用效果非常好。Gdx.input.JustTouch()在我的设备1中不起作用。有其他选择吗