OnMouseRelease 的行为类似于 OnMouseClick

OnMouseRelease is acting like OnMouseClick

我有一个应用程序让球打破了一些块,但游戏在松开鼠标按钮而不是单击时重新开始。

我创建了应用程序,以便通过单击鼠标开始游戏。如果球击中了底部窗格而不是球拍,那么游戏将重新开始并且玩家将失去生命。球拍也是用鼠标控制的,所以理论上,当球未命中并且游戏重置时,鼠标仍然会因使用球拍而被按下。不幸的是,我似乎无法解决从控制桨释放鼠标按钮重新启动游戏的问题。我尝试添加强制释放、计数器、使用 onMouseDragReleased 和 onDragDetected 以及其他组合。下面是一些部分代码,其中包括我认为与我的问题相关的区域。我尝试的一些不同方面被注释掉了。

public class BBController {
boolean start = true; //check if can start game
int pl = 0; //counter for checking mouse release
int cl = 0; //counter for checking mouse clicks
Timeline animateBall; //move ball
ArrayList<Rectangle> rec; //ArrayList to house all of the "blocks"

//GUI components
    ... 

//Start the game
@FXML void startGameWithMouseClicked(MouseEvent event) {
    if (cl == 0){ //haven't clicked to start game
        animateBall = new Timeline( //for making the ball move around
            new KeyFrame(Duration.millis(12),
                new EventHandler<ActionEvent>() {
                    int dx = 2;
                    int dy = 2;

                    @Override
                    public void handle(ActionEvent e){
                        ball.setLayoutX(ball.getLayoutX() + dx);
                        ball.setLayoutY(ball.getLayoutY() + dy);
                        Bounds b = pane.getBoundsInLocal();

                        if (hitSides(b)){ //ball hits left or right side
                            ...
                        }
                        //ball hits top of pane, the paddle, or a block
                        if (hitTop(b) || hitPaddle() || hitBlock()){
                            ...
                        }
                        if (rec.size() == 0){ //if hit all of the blocks
                            ...
                        }
                        if (hitBottom(b)){ //if ball hits bottom pane
                            //stop the bouncing
                            animateBall.setCycleCount(0);
                            animateBall.stop();
                            //next mouse click can start game if lives left
                            cl -= 1;
                            cb.setText(Integer.toString(cl));
                            /*if (pl==0){cl -= 1;}
                            cb.setText(Integer.toString(cl));
                            //reset paddle
                            if (pl > 0){
                            Event.fireEvent(pane, new MouseEvent(
                                MouseEvent.MOUSE_RELEASED,0, 0, 0, 0,
                                MouseButton.PRIMARY, 1, true, true, true,
                                true, true, true, true, true, true, true,
                                null));
                            }*/




                            //if (pl > 0){pl -=1;}
                            //pb.setText(Integer.toString(pl));

                            paddle.setLayoutX(250);
                            //reset the ball's position
                            ball.setLayoutX(300);
                            ball.setLayoutY(371);
                            //lose a life
                            livesTotalBox.setText(Integer.toString(
                                Integer.parseInt(
                                    livesTotalBox.getText()) - 1));
                            if (Integer.parseInt( //out of lives
                                livesTotalBox.getText()) == 0){
                                start = false; //can't play any more
                                gameOver.setStyle(
                                    "-fx-background-color: YELLOW");
                                gameOver.setVisible(true);
                            }
                        }//end hitBottom
                    }//end handle
                }//end EventHandler
            )//end KeyFrame
        );//end Timeline

        if(start == true){//if lives avail & mouse events cleared
            cl += 1; //future clicks don't try to start game again
            cb.setText(Integer.toString(cl));
            animateBall.setCycleCount(Timeline.INDEFINITE);
            animateBall.play();
        }
    } //end if (cl == 0)
}//end startGameWithMouseClicked

private boolean hitSides(Bounds b){ //check if ball hits sides of pane
    ...
}

private boolean hitTop(Bounds b){ //Check if ball hits top of pane
    ...
}

private boolean hitBottom(Bounds b){ //check if ball hits bottom of pane
    ...
}

private boolean hitPaddle(){ //check if ball hits paddle
    ...
}

private boolean hitBlock(){ //check if ball hits a block
    ...

} //end hitBlock

//Control the paddle
@FXML void selectPaddleWithMousePressed(MouseEvent event) {
//  pl += 1; //mouse button pressed outside of starting game
//  pb.setText(Integer.toString(pl));
    paddle.getLayoutX();
}
@FXML void movePaddleWithMouseDragged(MouseEvent event) { //move paddle
    if (event.getSceneX() <= 0){ //paddle can't go beyond left side pane
        paddle.setLayoutX(0);
    }
    else if (event.getSceneX() >= 500){ //paddle can't go beyond right side
        paddle.setLayoutX(500);
    }
    else {paddle.setLayoutX(event.getSceneX());} //paddle anywhere btw sides
}
@FXML void stopPaddleWithMouseReleased(MouseEvent event) {
/*  if (pl > 0) {//mouse was pressed outside of starting game
        pl -= 1;
        pb.setText(Integer.toString(pl));
        //leave paddle where you released
        paddle.setLayoutX(paddle.getLayoutX());
    }
    else {//game needs to reset
        paddle.setLayoutX(250);
        pb.setText(Integer.toString(pl));
        //next mouse click can start game if lives left
        cl -= 1;
        cb.setText(Integer.toString(cl));
    }*/

    if (cl == 0) { paddle.setLayoutX(250); }
    else { paddle.setLayoutX(paddle.getLayoutX()); }
}

// called by FXMLLoader to initialize the controller
public void initialize() {
    ...
}//end initialize
}//end BBController

我点击它开始游戏。当我第二次单击鼠标以控制球拍时,保持点击计数器可防止游戏重新启动。但是,none 计数器及其位置的变化可能会导致游戏无法在鼠标释放时立即开始。我正在使用 Scene Builder,我目前尝试了以下方法:

startGameWithMouseClicked 作为窗格的 onMouseClicked 事件 selectPaddleWithMousePressed 作为桨的 onDragDetected 或 onMousePressed movePaddleWithMouseDragged 作为桨 onMouseDragReleased 或 onMouseDragged stopPaddleWithMouseReleased 作为桨 onMouseDragReleased 或 onMouseReleased

我还尝试将它们设为 pane 和 none 的所有事件作为桨,以防来回拖动桨导致光标在拖动和释放时不再位于桨上。

任何建议将不胜感激,因为这是我的应用程序的一个烦人的错误。 谢谢

我发现鼠标事件总是按下、释放、单击 - 所以我认为它会在从拖动动作中释放后停止,但单击事件仍然必须发生。我最终创建了一个变量,并让它在游戏开始时在点击事件中增加(在 if var == 0 内),在每个 press/release 上增加和减少,然后在点击事件中最终减少将它恢复为 0(仅当球不再移动时)作为 else 语句(因此当 var != 0 时)。

这是我的逻辑:

click event
  if counter = 0
    start game
    counter + 1
  if counter != 0
    if ball moving, do nothing //for if you press/release multiple times while dragging paddle
    if ball not moving, counter - 1 //next click can start game
end click event

press event 
  counter + 1
end press event

drag event 
  move paddle
end drag event

release event 
  counter -1
end release event