【问题标题】:touch scrolling with libgdx使用 libgdx 进行触摸滚动
【发布时间】:2013-02-13 10:45:46
【问题描述】:

我正在尝试在 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();

}

}

在输入处理器中

@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 不是世界坐标,但我尝试取消投影相机但没有任何效果。

我已经为此苦苦挣扎了几个星期,非常感谢您对此提供帮助。

提前致谢。

【问题讨论】:

    标签: java libgdx


    【解决方案1】:

    使用了 drinor 的答案,但在“touchDown”功能上添加了一行,因此每次重新开始拖动时它都不会重置相机:

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

    【讨论】:

      【解决方案2】:

      简单回答:

      声明2个字段来保存新旧拖动位置:

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

      这就是我用来拖动我的正射凸轮的全部,简单而有效。

      【讨论】:

      • Gdx.input.justTouched() 在我的设备 1 中不起作用.. 任何替代方案
      【解决方案3】:

      我最近做了一些你想做的事。这是我用于移动地图的 Input 类,您只需为您的 '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

      【讨论】:

      • 这看起来可能是答案,请您包括您对 cameraOutOfLimit 的实现,因为这是我遇到问题的部分。我尝试了一个滚动窗格,这很有效,但我可以在场景中添加一个新的 Actor 并让它与背景一起滚动。
      • 我添加了 cameraOutOfLimit 函数。我希望它会有所帮助。
      • 这与 P.T. 建议的手势监听器结合使用非常好。下面。
      【解决方案4】:

      您需要在touchDragged 回调中进行更多计算,您不能只将触摸到的任何屏幕坐标传递给相机。您需要弄清楚用户拖动手指的距离多远,以及向哪个方向拖动。绝对坐标不是立即有用的。

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

      我认为最简单的方法是跟踪previousXpreviousY(在touchDown 方法中初始化它们。然后在touchDragged 期间使用增量调用cam.translate()(例如deltaX = screenX - previousX) . 并且还要更新touchDragged中的previous*

      或者,您可以查看 InputProcessor libgdx 提供的一些更高级的包装器(请参阅 https://code.google.com/p/libgdx/wiki/InputGestureDetection)。

      【讨论】:

        【解决方案5】:

        我自己没用过,不过先看看下面的代码:

        你看过http://libgdx.l33tlabs.org/docs/api/com/badlogic/gdx/scenes/scene2d/ui/FlickScrollPane.html的代码吗

        见:touchDragged

        【讨论】:

        • 谢谢,这看起来很有趣。我查看了 ScrollPane 但丢弃了它会有滚动条,这不是我想要的,但这看起来它没有它们所以可能是完美的。
        • 在最坏的情况下,您可以找到一些接近您想要实现的代码...
        • 刚从 6 月底发现了一个 Badlogic Games 博客,其中指出 FlickScollPane 已不再使用,但 ScrollPane 具有它的所有功能,并且滚动条可绘制对象是可选的,所以看起来 Scrollpane 是现在要走的路。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多