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