Detect touch on rectangle that are using drawRect() - java

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;
}
});

Related

Character Sprite in a Java Android Game with buggy movement when using two fingers

The following code I wrote does what I want, a touch on the left or right side of the screen to move the sprite left or right and stop at the edge of the phone screen. The issue I'm having is when you do a fast motion of touching the right side of the screen, letting go while using another finger to touch the left side of the screen to change direction will yield a result of the sprite still moving to the right side of the screen despite you wanting to move left. In order to fix this, you need to let go completely for at least 0.5sec then press the other direction to start moving in that direction, which I don't want to have to live with. If anyone has any tips/help for this, please let me know!
MAIN ACTIVITY CLASS METHOD:
public boolean onTouchEvent(MotionEvent event){
int x = (int)event.getX();
switch(event.getAction()) {
case (MotionEvent.ACTION_DOWN):
CharacterSprite.touchedX = x;
break;
case (MotionEvent.ACTION_UP):
CharacterSprite.touchedX = 0;
break;
}
return super.onTouchEvent(event);
}
CHARACTERSPRITE CLASS METHOD:
public void update() {
if (touchedX != 0) {
if (touchedX < screenWidth / 2) {
if (!(xVelocity < 0)) {
xVelocity = xVelocity * -1;
}
if (!(x > 0)) {
touchedX = 0;
return;
}
x += xVelocity;
}
if (touchedX > screenWidth / 2) {
if (!(xVelocity > 0)) {
xVelocity = xVelocity * -1;
}
if (!(x < screenWidth - image.getWidth())) {
touchedX = 0;
return;
}
x += xVelocity;
}
}
}
The way you handling MotionEvent will not work for multitouch events. Each finger (action pointer) data stored as an array and you need to handle each entry separately. Here is the lesson on handling multitouch events:
https://developer.android.com/training/gestures/multi

close a dialog on background image touch libgdx

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.

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.

How to get how many pixels I moved on a MotionEvent.ACTION_MOVE event in Android

I have a touch listener that watches for ACTION_DOWN, ACTION_MOVE, and ACTION_UP.
I want to get the number of pixels moved, but I can't find anything in the documentation that allows this.
} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
float x2 = motionEvent.getX();
float y2 = motionEvent.getY();
//Logging x2 and y2....
My log outputs pretty big numbers, even though I move very very slightly.
I try to move 1 pixel in either direction with my mouse pointer, but I get results like 42 for x and 75 for y. I'm guessing getX() and getY() do not respond with what I think they respond with.
EDIT:
public boolean onTouch(View v, MotionEvent motionEvent) {
float startX = 0;
float startY = 0;
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
startX = motionEvent.getRawX();
startY = motionEvent.getRawY();
Log.e("resize", "action down");
} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
Log.e("resize", "action move");
float movedX = motionEvent.getRawX() - startX;
float movedY = motionEvent.getRawY() - startY;
Log.e("", " movement "+movedX+" "+movedY+"");
getX() and getY() are coordinates of point on the view in which motion event was fired, calculated relatively to view's initial size and position. It means that if your view was rotated or scaled, these coordinates are recalculated using rotation and scale matrix.
To get absolute screen coordinates, you should use getRawX() and getRawY() instead.
To obtain vector at which finger moved from the starting point, first you need to remember point at which ACTION_DOWN event was fired:
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN){
startX = event.getRawX();
startY = event.getRawY();
}
Then, when finger moves, calculate movement coordinates relative to this starting point:
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE){
movedX = event.getRawX() - startX;
movedY = event.getRawY() - startY;
}

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