我是 java 和 OOP 的初学者,我正在尝试创建一个迷宫游戏,目前我正在使用动画计时器,以便玩家可以顺利移动。我创建了一个碰撞检测方法,当玩家遇到一堵牢不可破的墙时,该方法返回 true 并打印出存在碰撞,但玩家继续在其上移动。需要帮助和建议,谢谢!
这是我的玩家类别
package application;
import java.util.ArrayList;
import javafx.animation.AnimationTimer;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.fxml.FXML;
import javafx.geometry.Bounds;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
public class Player{
@FXML private ImageView player;
@FXML AnchorPane scene;
private double x;
private double y;
private int lives;
private int scoreCounter;
private BooleanProperty upPressed = new SimpleBooleanProperty();
private BooleanProperty leftPressed = new SimpleBooleanProperty();
private BooleanProperty rightPressed = new SimpleBooleanProperty();
private BooleanProperty downPressed = new SimpleBooleanProperty();
private BooleanBinding keyPressed = upPressed.or(leftPressed).or(rightPressed).or(downPressed);
private boolean left, up, right, down;
boolean canMove = true;
private double movementVariable = 0.75;
CollisionHandler collisionHandler = new CollisionHandler();
public Player(ImageView player, double x, double y, int lives, int scoreCounter) {
this.player = player;
this.x = x;
this.y = y;
this.lives = lives;
this.scoreCounter = scoreCounter;
}
public void makeMovable(ImageView player, AnchorPane scene, ArrayList<Rectangle> unbreakableObjects) {
this.player = player;
this.scene = scene;
movementSetup();
keyPressed.addListener(((observableValue, aBoolean, t1) -> {
if (!aBoolean) {
timer.start();
canMove = false;
} else {
timer.stop();
}
}));
}
AnimationTimer timer = new AnimationTimer() {
// double currentX = player.getLayoutX();
// double currentY = player.getLayoutY();
//
@Override
public void handle(long timestamp) {
// double currentX = player.getLayoutX();
// double currrentY = player.getLayoutY();
if(upPressed.get()) {
player.setLayoutY(player.getLayoutY() - movementVariable);
}
if(downPressed.get()){
player.setLayoutY(player.getLayoutY() + movementVariable);
}
if(leftPressed.get()){
player.setLayoutX(player.getLayoutX() - movementVariable);
}
if(rightPressed.get()){
player.setLayoutX(player.getLayoutX() + movementVariable);
}
}
};
public boolean playerCollidesWithUnbreakable(double x, double y, ArrayList <Rectangle> unbreakables) {
if (collisionHandler.checkCollisionUnbreakables(this, unbreakables)) {
if(upPressed.get()) {
player.setLayoutY(player.getLayoutY() + movementVariable);
}
if(downPressed.get()){
player.setLayoutY(player.getLayoutY() - movementVariable);
}
if(leftPressed.get()){
player.setLayoutX(player.getLayoutX() + movementVariable);
}
if(rightPressed.get()){
player.setLayoutX(player.getLayoutX() - movementVariable);
}
return true;
} else {
return false;
}
}
private void movementSetup(){
scene.setOnKeyPressed(e -> {
if(e.getCode() == KeyCode.W) {
upPressed.set(true);
up = true;
}
if(e.getCode() == KeyCode.A) {
leftPressed.set(true);
left = true;
}
if(e.getCode() == KeyCode.S) {
downPressed.set(true);
down = true;
}
if(e.getCode() == KeyCode.D) {
rightPressed.set(true);
right = true;
}
});
scene.setOnKeyReleased(e ->{
if(e.getCode() == KeyCode.W) {
upPressed.set(false);
up = true;
}
if(e.getCode() == KeyCode.A) {
leftPressed.set(false);
left = true;
}
if(e.getCode() == KeyCode.S) {
downPressed.set(false);
down = true;
}
if(e.getCode() == KeyCode.D) {
rightPressed.set(false);
right = true;
}
});
}
public int getScore() {
return this.scoreCounter;
}
public void incrementScore() {
this.scoreCounter++;
}
public double returnX() {
return player.getX();
}
public double returnY() {
return player.getY();
}
public void newX(double x) {
player.setX(x);
}
public void newY(double y) {
player.setY(y);
}
public Bounds getPlayerBounds() {
return player.getBoundsInParent();
}
public ImageView getPlayerImageView() {
return player;
}
}
这是我的控制器类
package application;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
import javafx.animation.AnimationTimer;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
public class PlayerController implements Initializable{
@FXML
private ImageView player;
private Player playerComponent;
@FXML private AnchorPane scene;
private double x = 0;
private double y = 0;
private int scoreCounter = 0;
@FXML private int lives;
@FXML private Text score;
@FXML private Rectangle Bed;
@FXML private Rectangle Plant;
@FXML private Rectangle Shelf1;
@FXML private Rectangle Shelf2;
@FXML private Rectangle Box1;
@FXML private Rectangle Box2;
@FXML private Rectangle Box3;
@FXML private Rectangle Box4;
@FXML private Rectangle Cabinet1;
@FXML private Rectangle TVset;
@FXML private Rectangle chair1;
@FXML private Rectangle chair2;
@FXML private Rectangle Table1;
@FXML private Rectangle Desk1;
@FXML private Rectangle Desk2;
@FXML private Rectangle Box5;
@FXML private Rectangle Box6;
@FXML private Rectangle Cabinet2;
@FXML private Rectangle RightWall;
@FXML private Rectangle TopWall;
@FXML private Rectangle LeftWall;
@FXML private Rectangle BottomWall;
@FXML private ImageView breakable1;
@FXML private ImageView breakable2;
@FXML private ImageView breakable3;
@FXML private ImageView breakable4;
@FXML private ImageView breakable5;
@FXML private ImageView breakable6;
@FXML private ImageView breakable7;
@FXML private ImageView breakable8;
@FXML private ImageView breakable9;
@FXML private ImageView breakable10;
@FXML private ImageView breakable11;
@FXML private ImageView breakable12;
@FXML private ImageView breakable13;
@FXML private ImageView breakable14;
@FXML private ImageView breakable15;
@FXML private ImageView breakable16;
@FXML private ImageView breakable17;
@FXML private ImageView breakable18;
@FXML private ImageView breakable19;
@FXML private ImageView breakable20;
@FXML private ImageView breakable21;
@FXML private ImageView breakable22;
@FXML private ImageView breakable23;
@FXML private ImageView breakable24;
private ArrayList<Rectangle> unbreakableObjects = new ArrayList();
private ArrayList<ImageView> breakableObjects;
Unbreakable unbreakable = new Unbreakable();
CollisionHandler collisionHandler = new CollisionHandler();
AnimationTimer gameLoop;
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
this.scene = scene;
playerComponent = new Player(player, x, y, lives, scoreCounter);
gameLoop = new AnimationTimer() {
@Override
public void handle(long arg0) {
double currentX = player.getX();
double currentY = player.getY();
playerComponent.makeMovable(player, scene, unbreakableObjects);
if(collisionHandler.checkCollisionUnbreakables(playerComponent, unbreakableObjects)) {
player.setX(currentX);
player.setY(currentY);
}
}
};
gameLoop.start();
unbreakableObjects.add(Bed);
unbreakableObjects.add(Cabinet1);
unbreakableObjects.add(Shelf1);
unbreakableObjects.add(Shelf2);
unbreakableObjects.add(Box1);
unbreakableObjects.add(Box2);
unbreakableObjects.add(Box3);
unbreakableObjects.add(Box4);
unbreakableObjects.add(Plant);
unbreakableObjects.add(TVset);
unbreakableObjects.add(chair1);
unbreakableObjects.add(chair2);
unbreakableObjects.add(Table1);
unbreakableObjects.add(Desk1);
unbreakableObjects.add(Desk2);
unbreakableObjects.add(Box5);
unbreakableObjects.add(Box6);
unbreakableObjects.add(Cabinet2);
unbreakableObjects.add(RightWall);
unbreakableObjects.add(TopWall);
unbreakableObjects.add(LeftWall);
unbreakableObjects.add(BottomWall);
breakableObjects = new ArrayList<>();
breakableObjects.add(breakable1);
breakableObjects.add(breakable2);
breakableObjects.add(breakable3);
breakableObjects.add(breakable4);
breakableObjects.add(breakable5);
breakableObjects.add(breakable6);
breakableObjects.add(breakable7);
breakableObjects.add(breakable8);
breakableObjects.add(breakable9);
breakableObjects.add(breakable10);
breakableObjects.add(breakable11);
breakableObjects.add(breakable12);
breakableObjects.add(breakable13);
breakableObjects.add(breakable14);
breakableObjects.add(breakable15);
breakableObjects.add(breakable16);
breakableObjects.add(breakable17);
breakableObjects.add(breakable18);
breakableObjects.add(breakable19);
breakableObjects.add(breakable20);
breakableObjects.add(breakable21);
breakableObjects.add(breakable22);
breakableObjects.add(breakable23);
breakableObjects.add(breakable24);
}
private void pointChecker() {
playerComponent.incrementScore(); score.setText(String.valueOf(playerComponent.getScore()));
System.out.println("PLAYER SCORE: " + playerComponent.getScore());
}
}
这是我的碰撞处理程序
package application;
import java.util.ArrayList;
import javafx.geometry.Bounds;
import javafx.scene.image.ImageView;
import javafx.scene.shape.Rectangle;
public class CollisionHandler {
public boolean checkCollisionUnbreakables(Player player, ArrayList<Rectangle> unbreakableObjects) {
Bounds playerBounds = player.getPlayerBounds();
for (Rectangle rectangle : unbreakableObjects) {
Bounds rectangleBounds = rectangle.getBoundsInParent();
if (playerBounds.intersects(rectangleBounds)) {
System.out.println("You can't go there!");
return true;
}
}
return false;
}
public boolean checkCollisionBreakables(Player player, ArrayList<ImageView> breakableObjects) {
Bounds playerBounds = player.getPlayerBounds();
for (ImageView breakable : breakableObjects) {
Bounds breakableBounds = breakable.getBoundsInParent();
if (playerBounds.intersects(breakableBounds)) {
if (breakable.getImage() == null) {
// System.out.println("Cleared already");
// Cleared already
return false;
} else {
System.out.println("Picked up trash");
breakable.setImage(null);
return true;
}
}
}
return false;
}
}
尝试在移动之前存储玩家的当前位置,移动后我检查是否有碰撞,如果发生碰撞,我将玩家设置为存储的位置。
一旦检测到碰撞就尝试打破循环。
public boolean checkCollisionUnbreakables(Player player, ArrayList<Rectangle> unbreakableObjects) {
Bounds playerBounds = player.getPlayerBounds();
Boolean collide = false;
for (Rectangle rectangle : unbreakableObjects) {
Bounds rectangleBounds = rectangle.getBoundsInParent();
if (playerBounds.intersects(rectangleBounds)) {
System.out.println("You can't go there!");
collide = true;
}
}
return collide;
}
您的循环仍然继续迭代所有不可破坏的对象,如果该不可破坏的对象不在玩家范围内,则将返回 false。当然它会打印出警告,但你没有打破循环,导致它返回所有迭代结果。