Skip to content
Advertisement

How to make sure a player is touching the game piece before allowing them to move it

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.

enter image description here

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!!

Advertisement

Answer

Creating a flag canMovePiece could help.
When ACTION_DOWN happens we can set canMovePiece to true if the coordinates of the event are contained inside the red square, if they’re not nothing happens.
Now, if the flag is true we know that the player can move the red square, so everytime ACTION_MOVE happens (don’t create a switch-case block inside the ACTION_DOWN, you could just use a single switch-case inside the onTouchEvent()) it’s possible to check the value of the flag: if it’s true, we get the current x and y of the movement and update the position of the red square. If it’s false, 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_UP happens we should only set the flag to false to start with another action in the future.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement