close a dialog on background image touch libgdx - java

I'm trying to close a dialog on background touch but it always goes in the else condition
stage.addListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if(stage.hit(x,y,true).equals(bg)) {
System.out.println("in th if");
dialog.addAction(rotateTo(90, .30f, Interpolation.smooth2));
dialog.hide();
}
else {
System.out.println("int the else");
}
return true;
}
});

I think this will work, but didn't test.
Dialog is already set up to receive all touchDown input while it's visible, even if the touch is outside its bounds, so simply give it a listener that hides it if the touch is outside its bounds:
dialog.addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
if (x < 0 || x > dialog.getWidth() || y < 0 || y > dialog.getHeight()){
dialog.hide();
}
return true;
}
});
This assumes dialog is final or a member field so you can access it from the listener.
I think the reason your code doesn't work is that stage.hit(...) will always return the dialog regardless of coordinates since Dialogs are set up to absorb all input.

Related

How to detect swipe in Libgdx without triggering justTouched()?

I'm making a game where swiping and justTouched do different things. My problem is that when I swipe on the screen obviously the touchDown() method is also being triggered.
Im extending GestureAdapter:
#Override
public boolean touchDown(float x, float y, int pointer, int button) {
//move when screen is touched
if(life == 1 && overlaps == false) {
timeState = 0;
velocity.y = -120;
velocity.x = 100;
}
return super.touchDown(x, y, pointer, button);
}
#Override
public boolean fling(float velocityX, float velocityY, int button) {
if(velocityX > 10)
//do something
return super.fling(velocityX, velocityY, button);
}
You should not use just touched in this case because when player touched first time you cant know will it be just touch or swipe.
You must use justtouched with touch up method like this
when player justtouched save touched coordinates.
Check coordinates when player touched up.
If distance between this 2 points less than 50 pixels (or what limit you want to set) then you can assume its justtouched otherwise its swipe and you can do calculations about swiping.

Detect touch on rectangle that are using drawRect()

I am refering to this tutorial to make a resizable rectangle. But in my case, I need more than that.
I need to drag and move the rectangle as well without touching on the point. Is this possible?
Which part of the code should I change?
Or is there any way to detect the rectangle that is drawn by using drawRect()?
Thanks.
Use the x and y coordinates of the click event and detect if this position is in the rectangle.
yourView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
int x = event.getX();
int y = event.getY();
if(x > rectLeftX && x < rectRightX && y > rectBottomY && y < rectTopY){
/* Trigger your action here */
}
}
return true;
}
});

dragging in libgdx flickers

I want to drag an Actor around with the Mouse in LibGDX.
My code:
// overrides in the ClickListener
#Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
touching = true;
prevTouchPosition = new Vector2(x, y);
return super.touchDown(event, x, y, pointer, button);
}
#Override
public void touchDragged(InputEvent event, float x, float y,
int pointer) {
dragging = true;
lastTouchPosition = new Vector2(x, y);
super.touchDragged(event, x, y, pointer);
}
#Override
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
touching = false;
super.touchUp(event, x, y, pointer, button);
}
// the update method
#Override
public void act(float delta) {
super.act(delta);
if(dragging){
Vector2 diff = new Vector2(lastTouchPosition).sub(prevTouchPosition);
translate(diff.x, diff.y);
prevTouchPosition = new Vector2(lastTouchPosition);
dragging = false;
}
}
The more I move the Actor around the worse it gets.
The idea is to keep the last two Mouse positions and use the difference between them to update the position of the Actor.
Anything incremental like this is going to suffer from roundoff errors. Moreover, I think you don't need to update prevTouchPosition every frame; in the absence of roundoff errors, it should not be changing. Note that your code only works if the object is not rotated or scaled.
A more robust drag algorithm works as follows:
upon touch down, touch point L in object-local coordinates:
G := L
upon touch move, touch point L in object-local coordinates:
setPosition(toGlobal(L) - toGlobal(G) + getPosition())
Note that we never update G during the drag operation; it is used to remember the point on the object where it was "grabbed", and we continuously align the object so that this point is under the current touch. Here, toGlobal(L) - toGlobal(G) gives you the "delta" vector in global coordinates, which we add to the current position.
Note that I'm assuming there's no object hierarchy, so the current position is itself in global coordinates. Otherwise you'll need to take the parent's transform into account as well.

libgdx touchUp event

I'm using an actors with a stage as buttons. I can detect when touchDown/touchUp events occur just fine over the actor, but when the user taps on the actor and then proceeds to drag their finger off the actor, the touchUp event never fires. I tried to use the exit event instead, but it never fires. In my program the touchUp/touchDown events determine movement and also button color which depend on whether the button is being pressed or not. So I' left with a permanently "depressed" button until it's clicked down/up again.
Example of the code I'm using:
stage.addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
Actor actor = stage.hit(x, y, true);
if (actor != null){
System.out.println("touchDown: " + actor.getName().toString());
}
return true;
}
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
Actor actor = stage.hit(x, y, true);
if (actor != null){
System.out.println("touchUp: " + actor.getName().toString());
}
}
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor){
System.out.println("exit");
}
});
If you change
stage.addListener(new InputListener() {});
to
stage.addListener(new ClickListener() {});
it will recognize the TouchUp call. And it still will be able to handle the TouchDown, and Exit calls.
I had the same problem. I fixed it by creating boolean isDown variable as a field of my GameScreen class. Whenever touchDown occures on my background Image I make isDown variable true and when touchUp occures - isDown = false. That way touchUp will always occur. Then still in my GameScreen in render method i check if isDown is true, if it is, I check if the touch intersects with my actor:
if (isDown) {
if (pointIntersection(myActor, Gdx.input.getX(), Gdx.input.getY())) {
// do something
}
} else {
// reverse the effect of what you did when isDown was true
}
where pointIntersection method is:
public static boolean pointIntersection(Image img, float x, float y) {
y = Gdx.graphics.getHeight() - y;
if (img.x <= x && img.y <= y && img.x + img.width >= x && img.y + img.height >= y)
return true;
return false;
}
It's the only workaround I found to that. Still, it's not very pretty but works for me.

Press an exact area on screen

here is my code now:
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
switch(action)
{
case MotionEvent.ACTION_DOWN:
// Do click work here ...
Y -= 10;
Yopen = 1;
break;
case MotionEvent.ACTION_UP:
// Do release work here ...
Yopen = 0;
break;
}
return super.onTouchEvent(event);
}
But I want to make only three different areas to perform different code.
Can some one help me, some good tutorial on the internet.
Add this code to your onTouchEvent to figure out where the user touched and respond appropriately:
//Grab the current touch coordinates
float x = event.getX();
float y = event.getY();
//If you only want something to happen then the user touches down...
if (event.getAction() != MotionEvent.ACTION_UP) return true;
//If the user pressed in the following area, run it's associated method
if (isXYInRect(x, y, new Rect(x1, y1, x2, y2)))
{
//Do whatever you want for your defined area
}
//or, if the user pressed in the following area, run it's associated method
else if (isXYInRect(x, y, new Rect(x1, y1, x2, y2)))
{
//Do whatever you want for your defined area
}
Here's the isXYinRect method:
//A helper method to determine if a coordinate is within a rectangle
private boolean isXYInRect(float x, float y, Rect rect)
{
//If it is within the bounds...
if (x > rect.left &&
x < rect.right &&
y > rect.top &&
y < rect.bottom)
{
//Then it's a hit
return true;
}
//Otherwise, it's a miss
return false;
}

Categories

Resources