I am trying to make it so that the game piece (red square) cannot be moved unless the player initially clicks on it, but can then drag it freely until releasing it. Currently, if the player clicks anywhere on the the screen the game piece will move to their cursor/finger when they start moving it. If I try to use something like:
case MotionEvent.ACTION_DOWN: //player pressing down
if (gamePiece.getRectangle().contains((int) event.getX(), (int) event.getY())) {
switch (event.getAction()) {;
case MotionEvent.ACTION_MOVE: //player moving their finger
gamePiecePoint.set((int) event.getX(), (int) event.getY() - 100);
{
}
Checking that the block contains the Point where the player clicked does prevent the player from moving, but it makes movement VERY inconsistent, because the cursor doesn't stay directly on the game piece while moving.
What I want to do is require an initial touch on the game piece, then allow movement freely until they release the block. I'm just not sure how to accomplish this.
This is my current onTouchEvent implementation. the if statement in the ACTION_DOWN case prevents the block from snapping to the players Point immediately, but when the cursor is moved the game piece moves to it.
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: //player pressing down
if (!(gamePiece.getRectangle().contains((int) event.getX(), (int) event.getY()))) {
break;
}
case MotionEvent.ACTION_MOVE: //player moving their finger
gamePiecePoint.set((int) event.getX(), (int) event.getY() - 100);
//GameBoard.checkInteraction(gamePiecePoint);
break;
case MotionEvent.ACTION_UP:
gamePiecePoint = GameBoard.checkInteraction(gamePiecePoint);
break;
}
return true;
//return super.onTouchEvent(event);
}
EDIT: From suggestions by @Nicola I changed my switch-case block to the following (defined wasClicked at class level)...
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: //player pressing down
// Check if action down happened inside the gamePiece
wasClicked = gamePiece.getRectangle().contains((int) event.getX(), (int) event.getY());
case MotionEvent.ACTION_MOVE: //player moving their finger
if (wasClicked) {
gamePiecePoint.set((int) event.getX(), (int) event.getY() - 100);
}
case MotionEvent.ACTION_UP:
gamePiecePoint = GameBoard.snapToNearest(gamePiecePoint);
// Snaps player gamePiece to nearest tile on release
}
I did notice that if I put wasClicked = false; into the ACTION_UP case it breaks the system and I can only move the gamePiece a small amount at a time. I am not 100% sure why this is happening, but when I used system.out to monitor ACTION_UP from console, I noticed that it triggers constantly as I am moving the piece, and not just when I release the block. I'm not sure this is intended, but it works without it so I am satisfied for now. Thank you so much!!

Creating a flag
canMovePiececould help.When
ACTION_DOWNhappens we can setcanMovePiecetotrueif the coordinates of the event are contained inside the red square, if they're not nothing happens.Now, if the flag is
truewe know that the player can move the red square, so everytimeACTION_MOVEhappens (don't create aswitch-caseblock inside theACTION_DOWN, you could just use a singleswitch-caseinside theonTouchEvent()) it's possible to check the value of the flag: if it'strue, we get the currentxandyof the movement and update the position of the red square. If it'sfalse, nothing happens.I think this should be enough to establish a real-time movement of the red square based on the cursor (finger) position. When
ACTION_UPhappens we should only set the flag tofalseto start with another action in the future.