2013-02-27 144 views
2

我正試圖在libgdx遊戲中實現觸摸滾動。我有一個寬闊的形象,是一個房間的全景。我希望能夠滾動圖像,以便用戶可以看到房間周圍。我有它,這樣我可以滾動一定的距離,但是當一個新的touchDragged事件被註冊時,圖像會移回到原始位置。使用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(); 

} 

}

而在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不是世界座標,但我試圖unprojecting相機沒有任何效果。

我一直在爲此奮鬥了幾個星期,我真的很感謝這方面的幫助。

在此先感謝。

回答

6

我最近做了一件你想要的東西。這是我使用的移動地圖我的Input類,你只需要改變我的'舞臺。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

+0

這看起來可能是答案,你能否請你包含你的cameraOutOfLimit實現,因爲這是我遇到的問題。我已經嘗試了一個Scrollpane,並且這個方法可行,但是我可以在場景中添加一個新的Actor並讓它隨着背景一起滾動。 – jonnypotwash 2013-03-08 17:25:42

+0

我添加了cameraOutOfLimit函數。我希望這會有所幫助。 – drinor 2013-03-08 23:15:25

+0

這與P.T.提出的gestureListener結合使用效果很好。下面。 – jonnypotwash 2013-03-12 15:18:47

0

我沒有用它自己,但我會通過查看的代碼開始:

你看着http://libgdx.l33tlabs.org/docs/api/com/badlogic/gdx/scenes/scene2d/ui/FlickScrollPane.html

看到代碼:touchDragged

+0

謝謝,這看起來很有趣我看着ScrollPane中,而是被拋棄。它會有滾動條,這不是我想要的,但它看起來像沒有它們,因此可能是完美的。 – jonnypotwash 2013-02-27 15:11:24

+0

在最糟糕的情況下,您可以找到一些代碼,它接近您想要實現的目標... – 2013-02-27 15:15:04

+0

Just從6月底發現一個Badlogic Games博客,指出FlickScollPane不再使用,但ScrollPane擁有所有的功能,滾動條可繪製是可選的,所以它看起來像Scrollpane是現在出發。 – jonnypotwash 2013-02-27 15:26:26

1

你需要做在touchDragged回調中有很多計算,您不能將任何屏幕座標都傳遞給相機。你需要弄清楚用戶如何將遠遠的拖到他們的手指上,並朝着什麼方向。絕對座標不是立即有用的。

考慮從右上方拖拽或從左上方拖拽。在這兩種情況下,您都希望(我認爲)將相機移動的距離相同,但屏幕座標的絕對值在兩種情況下會有很大差異。

我認爲最簡單的做法是隻跟蹤previousXpreviousY(在touchDown方法對它們進行初始化,然後用三角(deltaX = screenX - previousX調用cam.translate(),例如),中touchDragged,而且還更新touchDraggedprevious*

或者,你可以看一些發燒友InputProcessor包裝libgdx提供(見https://code.google.com/p/libgdx/wiki/InputGestureDetection)的。

1

答案很簡單:

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

這是我用來拖動我的ortho凸輪四周,簡單而有效。

+0

Gdx.input.justTouched()在我的設備1中不工作..任何替代方法 – iappmaker 2015-06-19 04:55:54

1

使用drinor的回答倒是對「觸地線)功能,所以它不會在每次啓動再拖動時間重置相機:

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