我正在尝试重新创建突破游戏。球反弹并检测到碰撞。然而,太多的碰撞同时发生。这个球一次破坏一块以上的砖块。
我开始用一个圆作为球,但后来把它改成了一个矩形,以帮助获得更准确的碰撞检测。但这并不能完全解决问题。
我已尝试在检测到碰撞时反转y坐标。因此,一旦物体发生碰撞,球就会回到球拍上。但这并不能完全解决问题。我想避免背对背的冲突。我看过类似的帖子,但对我没有帮助。有什么建议吗?
package breakoutgame;
import javafx.application.*;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.stage.Stage;
import javafx.animation.*;
import javafx.event.*;
import javafx.util.Duration;
import java.util.*;
import javafx.scene.control.Label;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Font;
public class BreakoutGame extends Application {
@Override
public void start(Stage window) {
//creates main layout
Pane layout= new Pane();
layout.setStyle("-fx-background-color: black");
layout.setPrefSize(610,400);
Scene view= new Scene(layout);
//creates components and adds them to the main layout
ArrayList<Rectangle> allBricks = new ArrayList<>();
for(int x=0; x<10; x++) {
for(int y=0; y<8; y++) {
Rectangle brick=new Rectangle(60,15);
if(y<=1){
brick.setFill(Color.RED);
}
if(y>1 && y<=3){
brick.setFill(Color.ORANGE);
}
if(y>3 && y<=5){
brick.setFill(Color.GREEN);
}
if(y>5 && y<8){
brick.setFill(Color.YELLOW);
}
brick.setLayoutX(x*62);
brick.setLayoutY((16*y)+35);
layout.getChildren().add(brick);
allBricks.add(brick);
}
}
Rectangle ball= new Rectangle(20,20, Color.BLUE);
ball.relocate(300, 200);
Rectangle paddle= new Rectangle(90,7, Color.ORANGERED);
paddle.relocate(275, 390);
layout.getChildren().addAll(paddle, ball);
//controls paddle movement
int movement = 15;
view.setOnKeyPressed(event -> {
if (event.getCode() == KeyCode.LEFT) {
if(paddle.getLayoutX() < 0) {
paddle.setLayoutX(paddle.getLayoutX()+movement);
}
paddle.setLayoutX(paddle.getLayoutX()-movement);
}
if (event.getCode() == KeyCode.RIGHT) {
if(paddle.getLayoutX() > 510) {
paddle.setLayoutX(510);
}
paddle.setLayoutX(paddle.getLayoutX()+movement);
}
});
//creates an indefinite bouncing ball
Timeline timeline = new Timeline(new
KeyFrame(Duration.millis(20),
new EventHandler<ActionEvent>() {
double dx = 5;
double dy = 3;
@Override
public void handle(ActionEvent t) {
//ball movement
ball.setLayoutX(ball.getLayoutX() + dx);
ball.setLayoutY(ball.getLayoutY() + dy);
boolean leftWall = ball.getLayoutX() <= 0;
boolean topWall = ball.getLayoutY() < 35;
boolean rightWall = ball.getLayoutX() >= 590;
boolean bottomWall = ball.getLayoutY() >= 380;
// If the top wall has been touched, the ball reverses direction.
if (topWall) {
dy = dy * -1;
}
// If the left or right wall has been touched, the ball reverses direction.
if (leftWall || rightWall) {
dx = dx * -1;
}
if(bottomWall) {
dy = dy * -1;
}
//if ball collides with paddle
if (collide(paddle)) {
dy = -dy;
}
//if ball and brick collides, remove brick
Rectangle temp=null;
for(Rectangle brick:allBricks) {
if(collide(brick)) {
temp=brick;
layout.getChildren().remove(brick);
dy=-dy;
}
}
allBricks.remove(temp);
temp=null;
}
public boolean collide(Rectangle other) {
Shape collisionArea = Shape.intersect(ball, other);
return collisionArea.getBoundsInLocal().getWidth() != -1;
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
window.setTitle("Breakout Game!");
window.setScene(view);
window.show();
}
public static void main(String[] args) {
launch(args);
}
}
1条答案
按热度按时间uxh89sit1#
我添加了一些system.out.println()调用,以查看球何时移动以及砖块何时被击中。我没有看到任何来自同一个动作的双重打击,但我确实看到它有时在从另一块砖块反弹后击中第二块砖块。
我做了一些其他的重构,只是为了让我更容易了解它的工作原理,所以这就是你在这里得到的: