2013-02-27 3 views
2

Я пытаюсь внедрить сенсорную прокрутку в игру libgdx. У меня широкий образ, который является панорамой комнаты. Я хочу иметь возможность прокручивать изображение, чтобы пользователь мог видеть его по комнате. У меня есть так, что я могу прокручивать определенное расстояние, но когда регистрируется новое событие touchDragged, изображение возвращается в исходное положение.touch scrolling with 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 не является мировыми координатами, но я попытался непроектировать камеру без эффекта.

Я боролся с этим в течение нескольких недель, и я был бы очень признателен за помощь в этом.

Заранее спасибо.

ответ

6

недавно я сделал что-то, как то, что вы хотите. Это мой Входной класс, который я использую для перемещения карты, вы только нужно изменить мою "сцену.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, и это работает, но я могу добавить нового актера на сцену и прокрутить его вместе с фоном. – jonnypotwash

+0

Я добавляю функцию cameraOutOfLimit. Надеюсь, это будет полезно. – drinor

+0

Это работало очень хорошо в сочетании с жестомListener, предложенным P.T. ниже. – jonnypotwash

0

Я не использовал его сам, но я хотел бы начать, глядя на код:

вы смотрели на код http://libgdx.l33tlabs.org/docs/api/com/badlogic/gdx/scenes/scene2d/ui/FlickScrollPane.html

Престола ли: touchDragged

+0

Спасибо, это выглядит интересно, я смотрел на ScrollPane но отбрасываются. у него были бы прокрутки, которые не то, что я хотел, но похоже, что у них их нет, поэтому они могут быть идеальными. – jonnypotwash

+0

В худшем случае вы можете найти код, близкий к тому, что вы хотите достичь ... –

+0

Just обнаружил блог Badlogic Games с конца июня, в котором говорится, что FlickScollPane больше не используется, но ScrollPane имеет все свои способности, а чертежи прокрутки необязательны, поэтому похоже, что Scrollpane - это способ идти сейчас. – jonnypotwash

1

Вам нужно сделать намного больше вычислений в обратном вызове touchDragged, вы не можете просто передать, какие координаты экрана были затронуты камерой. Вам нужно выяснить, как далеко пользователь перетащил свой палец и в каком направлении. Абсолютные координаты не сразу полезны.

Рассмотрите возможность перетаскивания с верхнего правого или перетаскивания сверху вниз. В обоих случаях вы хотите (я полагаю) переместить камеру на то же расстояние, но абсолютные значения координат экрана в обоих случаях будут очень разными.

Я думаю, что проще всего это просто отслеживать previousX и previousY (инициализировать их в методе touchDown. Затем вызовите cam.translate() с дельтой (deltaX = screenX - previousX, например), во время touchDragged. А также обновить previous* в touchDragged.

в качестве альтернативы, вы можете посмотреть на некоторые из причудливых InputProcessor оберток libgdx обеспечивает (см https://code.google.com/p/libgdx/wiki/InputGestureDetection).

1

Простой ответ:

Declare 2 поля для удержания нового и старого местоположения перетаскивания:

Vector2 dragOld, dragNew; 

Когда вы только что коснулись, вы установили оба из них равным касанию, или ваша камера будет прыгать.

if (Gdx.input.justTouched()) 
{ 
    dragNew = new Vector2(Gdx.input.getX(), Gdx.input.getY()); 
    dragOld = dragNew; 
} 

Update dragNew каждый кадр и просто вычитать векторы друг от друга, чтобы получить й и у для перевода камеры.

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

Это все, что я использую, чтобы перетащить свою орто-камеру вокруг, просто и эффективно.

+0

Gdx.input.justTouched() не работает в одном из моих устройств. Любая альтернатива – iappmaker

1

Ответ Используется drinor, но добавил строку на «приземление) функцию, чтобы она не перезагрузить камеру каждый раз, когда вы начинаете снова перетаскивая:

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