table1.addListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
scroll=y;
System.out.print(scroll);
return true;
}
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer) {
table1.setPosition((scroll+(y)));
}});
I want to scroll my table up and down by dragging my table (like Facebook on phone) I can't make this math thing on the Y I don't know why when I drag it it goes crazy.
Parameters x and y in the methods of InputListener are local coordinates (i.e. relative to your table), so you need to convert them to table's parent coordinate system:
table.addListener(new InputListener() {
Vector2 vec = new Vector2();
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
table.localToParentCoordinates(vec.set(x, y));
return true;
}
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer) {
float oldTouchY = vec.y;
table.localToParentCoordinates(vec.set(x, y));
table.moveBy(0f, vec.y - oldTouchY);
}
});
By the way, using ScrollPane will probably be much better and convenient solution in your case: https://github.com/libgdx/libgdx/wiki/Scene2d.ui#scrollpane
Upd:
Actually, since you only need deltaY you can do this without converting coordinates:
table.addListener(new InputListener() {
float touchY;
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
touchY = y;
return true;
}
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer) {
// since you move your table along with pointer, your touchY will be the same in table's local coordinates
float deltaY = y - touchY;
table.moveBy(0f, deltaY);
}
});
Related
Is there a way for an image to move to a different position when the user clicks on that image.
public Players() {
deck.displayHand();
stage = new Stage(new ScreenViewport());
Image card1 = new Image(sprite);
card1.addListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
}
});
}
#Override
public void draw(Batch batch, float parentAlpha) {
stage.act();
stage.draw();
}
I know I have to add a listener but I'm quite confuse what to do after. The objective is for the user to touch the card image and it would move to a different location.
Move to a predefined position when you/user click on that image :
Add an Action to that image(Actor child),
Let's assume predefined position is x_pos,y_pos and movement time is t in sec
card1.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
card1.addAction(Actions.moveTo(x_pos, y_pos,t));
}
});
Objective is to touch the card/image and it would move to a different location according to the user touch :
card1.addListener(new DragListener(){
#Override
public void drag(InputEvent event, float x, float y, int pointer) {
card1.moveBy(x - card1.getWidth() / 2, y - card1.getHeight() / 2);
super.drag(event, x, y, pointer);
}
});
You need to set your stage as InputProcessor
Gdx.input.setInputProcessor(stage);
Image is an Actor so you can add Actions to it.
card1.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
card1.addAction(Actions.moveTo(100, 100, .5f, Interpolation.circleIn));
}
});
I have a problem with Table attributes on Libgdx my code:
Table root = new Table();
root.setFillParent(true);
stage.addActor(root);
Table table = new Table(MyGdxGame.gameSkin);
table.setBackground(new NinePatchDrawable(getNinePatch(("background.jpg"))));
root.add(table).grow().pad(25.0f);
Label label = new Label("Marsel\nTale", MyGdxGame.gameSkin, "title");
label.setColor(Color.WHITE);
label.setScale(.9f,.9f);
table.add(label);
table.row();
TextButton playButton = new TextButton("Tournament",MyGdxGame.gameSkin);
playButton.addListener(new InputListener(){
#Override
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
game.setScreen(new ChampionScreen(game));
}
#Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
return true;
}
});
table.add(playButton);
TextButton optionsButton = new TextButton("Options",MyGdxGame.gameSkin);
optionsButton.addListener(new InputListener(){
#Override
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
game.setScreen(new OptionScreen(game));
}
#Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
return true;
}
});
table.add(optionsButton).padBottom(3.0f);
I'm not able to modify the structure of my table, I want to put playButton and optionButton in the bottom.
There should be a method called bottom() that you can use on the buttons like:
table.add(playButton).bottom();
More information can be found in this helpful article: https://github.com/libgdx/libgdx/wiki/Table
I have tried using an InputListener on an Actor but it seems that the touchUp does not get called. Every other method does work for me.
stage = new Stage(new ScreenViewport());
Widget actor = new Widget();
actor.setFillParent(true);
actor.addListener(new InputListener() {
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("", "");
}
});
stage.addActor(actor);
Gdx.input.setInputProcessor(stage);
stage = new Stage(new ScreenViewport());
Widget actor = new Widget();
actor.setFillParent(true);
actor.addListener(new InputListener() {
#Override
public void touchDown(InputEvent event, float x, float y, int pointer, int button) {
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("", "");
}
});
stage.addActor(actor);
Gdx.input.setInputProcessor(stage);
I have an Stage class that handles touch input.
In the Screen class I set the stage as InputProcessor:
stageTest = new StageTest(new ScreenViewport());
Gdx.input.setInputProcessor(stageHUD);
But now I want to add a force to an Box2d object always a gesture input happens.
public class ActSwipe extends Actor {
private int tmpPointer;
private float
tmpX,
tmpY,
deltaX,
deltaY,
rad;
protected float
forceX,
forceY;
public ActSwipe() {
this.setName("SwipeAction");
this.setTouchable(Touchable.enabled);
this.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if(tmpPointer == 0) {
tmpPointer = pointer;
tmpX = x;
tmpY = y;
}
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
if (tmpPointer == pointer) {
tmpPointer = 0;
deltaX = x - tmpX;
deltaY = y - tmpY;
rad = (float) Math.atan2(deltaY, deltaX);
forceX = (float) Math.cos(rad);
forceY = (float) Math.sin(rad);
}
}
});
}
}
You can implement InputProcessor (or extend InputAdapter) in your screen and override its methods with your code.
Then use InputMultiplexer like this:
InputMultiplexer multiplexer = new InputMultiplexer();
Gdx.input.setInputProcessor(multiplexer);
multiplexer.addProcessor(this);
multiplexer.addProcessor(stage)
In the overridden methods you need to make sure that an object that was hit is an object that should be handled by your input processor and not the one from the scene. If so, return true from the method, so the event won't be passed to the latter.
I have a scrollPane with several actors inside. each actor has a touch event registered to set a new screen, but users will obviously want to be able to scroll through the list of actors without the touches registering. how do I go about this? the actors are registering touch events as below...
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
octave3Btn.getColor().a = 0.25f;
return true;
}
public void touchUp(InputEvent event, float x, float y, int pointer, int button){
octave3Btn.getColor().a = 1f;
launcher.setScreen(new ListNotesScreen(NoteNameAssets.octave3NoteNameArray,ImageAssets.octave3BtnTextureArray,manager, launcher));
}
Use the touchDragged callback to know whether there was a drag in between, or not.
private boolean wasDragged = false;
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
octave3Btn.getColor().a = 0.25f;
wasDragged = false;
return true;
}
public boolean touchDragged(InputEvent event, float x, float y, int pointer) {
// you can use a simple flag here, or better calculate the distance
// and set the flag when the distance surpassed a certain limit
wasDragged = true;
}
public boolean touchUp(InputEvent event, float x, float y, int pointer, int button) {
octave3Btn.getColor().a = 1f;
if (!wasDragged) {
launcher.setScreen(new ListNotesScreen(...));
}
}
This should probably take small errors into account. You would probably not set the flag in case there was a drag event for 1px. Better calculate the distance that the touch was dragged in between touchDown and touchUp and then switch the screen in case distance < 10 for example.
In my opinion, the best solution is to use clicked() instead of touchUp(). I know this question is 3 years, I write it for "future generations" :)
myButton.addListener(new ClickListener()
{
#Override
public void clicked(InputEvent event, float x, float y)
{
//do your stuff
super.clicked(event, x, y);
}
});