我有一个应用程序,该应用程序有一些破球动作,但是当释放鼠标按钮而不是单击时,游戏会重新启动。

我创建了该应用程序,以使游戏从单击鼠标开始。如果球击中了底部窗格而不是击中了桨叶,则说明游戏将重置并且玩家丧命。球拍还可以通过鼠标进行控制,因此从理论上讲,当球未命中且游戏重置时,鼠标仍会被按下而不再使用球拍。不幸的是,我似乎无法解决从控制操纵杆释放鼠标键重新启动游戏的问题。我尝试使用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


单击并开始游戏。当我第二次单击鼠标来控制球拍时,保持点击计数器可以防止游戏重新启动。但是,计数器及其位置的任何变化都不能阻止鼠标释放后立即开始游戏。我正在使用Scene Builder,目前已经尝试了以下方法:

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

我还尝试使它们的所有窗格事件都没有,而没有将它们作为桨事件,以防在前后拖动桨时导致光标在被拖动和释放时不再位于桨上。

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

最佳答案

我发现鼠标事件总是被按下,释放,单击-因此,我原以为在从拖动动作中释放鼠标事件后它将停止,因此单击事件仍然必须发生。我最终创建了一个变量,并使其在游戏开始时在click事件中(在if var == 0内)增加,在每次按下/释放时增加和减少,然后在click事件中最终减少以得到否则,它将返回0(仅当球不再移动时)(否则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

10-04 18:24