我正在尝试在libgdx游戏中实现触摸滚动。我有一个宽广的图像,是一个房间的全景。我希望能够滚动图像,以便用户可以在房间周围看到。我有它,所以我可以滚动一定的距离但是当注册一个新的touchDragged事件时,图像会移回原来的位置。
这就是我实施它的方式
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();
}
}
在InputProcessor中
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
cam.position.set(screenX, posY / 2, 0);
cam.update();
return false;
}
我在这个问题LibGdx How to Scroll using OrthographicCamera?的帮助下得到了这一点。但它并没有真正解决我的问题。
我认为问题在于touchDragged corodinates不是世界坐标,但我尝试不投影相机而没有效果。
我几周来一直在努力解决这个问题,我真的很感激这方面的帮助。
提前致谢。
答案 0 :(得分:6)
我最近做了你想要的事情。这是我用来移动地图的输入类,你只需要为你的'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;
}
...
}
结果如下:http://www.youtube.com/watch?feature=player_embedded&v=g1od3YLZpww
答案 1 :(得分:1)
你需要在touchDragged
回调中做更多的计算,你不能只是将触及的任何屏幕坐标传递给相机。您需要弄清楚用户拖动手指的方式 far 以及方向。绝对坐标不是立即有用的。
考虑从右上角向下拖动或从左上角向下拖动。在这两种情况下,您希望(我推测)将相机移动相同的距离,但在这两种情况下,屏幕坐标的绝对值会有很大差异。
我认为最简单的方法就是跟踪previousX
和previousY
(在touchDown
方法中初始化它们。然后使用delta(cam.translate()
调用deltaX = screenX - previousX
},例如),在touchDragged
期间。还要更新previous*
中的touchDragged
。
或者,您可以查看libgdx提供的一些更好的InputProcessor
包装器(请参阅https://code.google.com/p/libgdx/wiki/InputGestureDetection)。
答案 2 :(得分:1)
简单回答:
声明2个字段以保存新旧拖动位置:
Vector2 dragOld, dragNew;
刚刚触摸时,将两者设置为等于触摸位置,否则凸轮会跳跃。
if (Gdx.input.justTouched())
{
dragNew = new Vector2(Gdx.input.getX(), Gdx.input.getY());
dragOld = 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.
}
}
这就是我用来拖动我的正交凸轮,简单而有效。
答案 3 :(得分:1)
使用了drinor的答案,但在&#34; touchDown)功能上添加了一行,因此每次再次开始拖动时都不会重置相机:
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
last_touch_down.set( screenX, screenY, 0);
return false;
}
答案 4 :(得分:0)
我自己没有用过它,但我会从查看代码开始:
您是否查看了http://libgdx.l33tlabs.org/docs/api/com/badlogic/gdx/scenes/scene2d/ui/FlickScrollPane.html
的代码请参阅:touchDragged