对象不会碰撞
我正在使用Javafx尝试创建一个2D玩家,玩家(玩家等级)将能够将一个箱子(食品类)移动到某个位置。我可以让玩家与我想移动的图像发生碰撞,但不会在网格上移动。我已经设置了一个system.out消息来充当一个调试器,但仍然没有动作。对象不会碰撞
public class Game extends Application{
Pane backgroundPane;
Pane playfieldLayer;
Pane scoreLayer;
Image playerImage;
Image foodImage;
List<Player> players = new ArrayList<>();
List<Food> foods = new ArrayList<>();
Text collisionText = new Text();
boolean collision = false;
Scene scene;
@Override
public void start(Stage theStage) {
Group root = new Group();
int columnAmount = 18;
int rowAmount = 18;
GridPane gameGrid = new GridPane();
for (int i = 0; i < columnAmount; i++) {
ColumnConstraints columnn = new ColumnConstraints(45);
gameGrid.getColumnConstraints().add(columnn);
}
for (int i = 0; i < rowAmount; i++) {
RowConstraints row = new RowConstraints(45);
gameGrid.getRowConstraints().add(row);
}
gameGrid.setStyle("-fx-background-color: white; -fx-grid-lines-visible:true");
root.getChildren().add(gameGrid);
// create layers
backgroundPane = new Pane();
backgroundPane.setId("root");
playfieldLayer = new Pane();
scoreLayer = new Pane();
root.getChildren().add(backgroundPane);
root.getChildren().add(playfieldLayer);
root.getChildren().add(scoreLayer);
scene = new Scene(root, Settings.SCENE_WIDTH, Settings.SCENE_HEIGHT);
backgroundPane.getStylesheets().addAll(this.getClass().getResource("application.css").toExternalForm());
theStage.setResizable(false);
theStage.setScene(scene);
theStage.show();
loadGame();
createPlayers();
AnimationTimer gameLoop = new AnimationTimer() {
@Override
public void handle(long now) {
// player input
players.forEach(sprite -> sprite.processInput());
spawnFood();
players.forEach(sprite -> sprite.move());
foods.forEach(sprite -> sprite.move());
checkCollisions();
players.forEach(sprite -> sprite.updateUI());
foods.forEach(sprite -> sprite.updateUI());
}
};
gameLoop.start();
}
private void loadGame() {
playerImage = new Image(getClass().getResource("warehouse.png").toExternalForm());
//enemyImage = new Image(getClass().getResource("enemy.png").toExternalForm());
foodImage = new Image(getClass().getResource("food.png").toExternalForm());
}
private void createPlayers() {
// player input
Input input = new Input(scene);
// register input listeners
input.addListeners(); // TODO: remove listeners on game over
Image image = playerImage;
// center horizontally, position at 70% vertically
double x = (Settings.SCENE_WIDTH - image.getWidth())/2.0;
double y = Settings.SCENE_HEIGHT * 0.7;
// create player
Player player = new Player(playfieldLayer, image, x, y, 0, 0, 0, Settings.PLAYER_SPEED, input);
// register player
players.add(player);
}
Input input = new Input(scene);
input.addListeners();
Image image = foodImage;
double x = (Settings.SCENE_WIDTH - image.getWidth())/2.0;
double y = Settings.SCENE_HEIGHT * 0.2;
Food food = new Food(playfieldLayer, image, x,y,0,0, Settings.PLAYER_SHIP_SPEED, input);
foods.add(food);
private void checkCollisions() {
collision = false;
for(Player player: players) {
for(Food food: foods) {
if(player.collidesWith(food)) {
Food.collision = true;
food.updateUI();
System.out.println("Collided");
}
}
}
}
public static void main(String[] args) {
launch(args);
}
}
public abstract class SpriteBase {
public void move() {
if(!canMove)
return;
x += dx;
y += dy;
}
public void updateUI() {
imageView.relocate(x, y);
}
}
public class Food extends SpriteBase {
double foodMinX;
double foodMaxX;
double foodMinY;
double foodMaxY;
double speed;
Input input;
static boolean collision;
public Food(Pane layer, Image image, double x, double y, double dx, double dy, double speed, Input input) {
super(layer, image, x, y, dx, dy);
this.speed = speed;
this.input = input;
checkBounds1();
}
private void checkBounds1() {
// calculate movement bounds of the player ship
// allow half of the ship to be outside of the screen
foodMinX = 0 - image.getWidth()/2.0;
foodMaxX = Settings.SCENE_WIDTH - image.getWidth()/2.0;
foodMinY = 0 - image.getHeight()/2.0;
foodMaxY = Settings.SCENE_HEIGHT -image.getHeight()/2.0;
}
public void processInput() {
if(input.isMoveUp() && collision != false) {
input.removeListeners();
dy = -speed;
collision = false;
System.out.println("move up you bastard");
} else if(input.isMoveDown() && collision != false) {
input.removeListeners();
System.out.println("move up you bastard");
dy = speed;
collision = false;
} else {
dy = 0d;
}
// horizontal direction
if(input.isMoveLeft() && collision == true) {
input.removeListeners();
System.out.println("move up you bastard");
collision = false;
dx = -speed;
} else if(input.isMoveRight() && collision == true) {
input.removeListeners();
System.out.println("move up you bastard");
collision = false;
dx = speed;
} else {
dx = 0d;
}
}
@Override
public void move() {
super.move();
// ensure the food can't move outside of the screen
checkBounds();
}
private void checkBounds() {
// vertical
if(Double.compare(y, foodMinY) < 0) {
y = foodMinY;
} else if(Double.compare(y, foodMaxY) > 0) {
y = foodMaxY;
}
// horizontal
if(Double.compare(x, foodMinX) < 0) {
x = foodMinX;
} else if(Double.compare(x, foodMaxX) > 0) {
x = foodMaxX;
}
}
继续评论。
当你调用方法spawnFood()
,你是一个dx
制作new Food()
,和0
dy
值。所以它没有移动的速度。
Food food = new Food(playfieldLayer, image, x,y,0,0); <--Here
“但我在Player
班上也这么做!” (编辑了)
Player player = new Player(playfieldLayer, image, x, y, 0, 0, 0, Settings.PLAYER_SPEED, input);<-- Here
你在0
通为dx,dy
当你创建Player
为好,除非你也传递给它Settings.PLAYER_SPEED
,然后您可以在构造函数中设置。
public Player(Pane layer, Image image, double x, double y, double r, double dx, double dy, double speed, Input input) {
super(layer, image, x, y, dx, dy);
this.speed = speed; <--Here
this.input = input;
checkBounds1();
}
你不这样做在Food
类。
public Food(Pane layer, Image image, double x, double y, double dx, double dy) {
super(layer, image, x, y, dx, dy);
/***** NOT HERE ****/
checkBounds1();
}
我建议你spawnFood()
方法改变dx,dy
值,别的东西,或者也可以通过它的Settings.PLAYER_SPEED
,因为我想你要的食物留在字符的前面。
非常感谢你的回应。我已经提前尝试输入您的建议。基本上我改变了我的游戏类中的spawnFood()和checkCollision()方法,添加了一个输入监听器并传递了播放器的速度并添加了一个静态布尔变量。此外,在我的食物类中,我添加了碰撞检测,以根据玩家输入移动图像(我认为这对我所需要的是相当明智的)。 但我得到这个奇怪的问题,原始图像留在它的重生点,我只能移动图像的方式,直到它碰到屏幕边缘。 – callumSteven
我应该提到我所做的更改是在原始帖子中 – callumSteven
我怀疑你发布的代码比大多数人想要浏览的要多得多。尝试并将其减少到[mcve] – khelwood
设置食物时,您将'0'传递给'dx'和'dy'。所以'move()'函数被调用,它只是给你的'x'和'y'加'0'。在你的'spawnFoods'方法中。 –
我减少了一些。你认为它看起来更好吗?还是你会建议进一步削减它? 谢谢你的回复Hypnic Jerk,非常友善。你会建议如何解决这个问题? – callumSteven