大家好,我正在创建一个简单的 2D 游戏,到目前为止,我一直在做一场噩梦,试图让事物相互交流。到目前为止,我有一个“主菜单”、“游戏网格”和一个显示在网格上的图像。我现在正在处理它的运动,但我似乎无法让它工作。
package application;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.scene.layout.HBox;
import javafx.scene.Group;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.scene.image.Image;
public class Level {
// private static Array[] level1;
// private WarehouseKeeper warehouse;
private static ImageView image1 = ImageLoader.showWareHouseImage();
private static final int KEYBOARD_MOVEMENT_DELTA = 2;
public static void runLevel1(Stage theStage) {
// ImageView image = new ImageView((Element)
// ImageLoader.wareHouseImage);
// WarehouseKeeper warehouse = new
// WarehouseKeeper(ImageLoader.wareHouseImage);
Group root = new Group();
int columnAmount = 12;
int rowAmount = 12;
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");
Scene scene = new Scene(root, (columnAmount * 40) + 66, (rowAmount * 40) + 66, Color.WHITE);
image(root, gameGrid);
moveWareHouse(scene, createKeeper());
theStage.setScene(scene);
theStage.show();
}
private static void image(Group root, GridPane gameGrid) {
// ImageLoader.wareHouseImage;
/*
* ImageView wareHouse = new ImageView(); wareHouse.setFitHeight(45);
* wareHouse.setFitWidth(45);
*
* Image image1 = ImageLoader.showWareHouseImage();
* wareHouse.setImage(image1);
*/
ImageView image1 = ImageLoader.showWareHouseImage();
final HBox picture = new HBox();
picture.getChildren().add(image1);
gameGrid.setAlignment(Pos.CENTER);
// gameGrid.getChildren().add(wareHouse);
gameGrid.add(picture, 7, 9);
root.getChildren().add(gameGrid);
}
private static WarehouseKeeper createKeeper() {
final WarehouseKeeper keeper = new WarehouseKeeper(image1);
return keeper;
}
private static void moveWareHouse(Scene scene, final WarehouseKeeper keeper) {
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
switch (event.getCode()) {
case W:
keeper.setyPosition(keeper.getyPosition() - KEYBOARD_MOVEMENT_DELTA);
break;
case D:
keeper.setxPosition(keeper.getxPosition() + KEYBOARD_MOVEMENT_DELTA);
break;
case A:
keeper.setyPosition(keeper.getyPosition() + KEYBOARD_MOVEMENT_DELTA);
break;
case S:
keeper.setxPosition(keeper.getxPosition() - KEYBOARD_MOVEMENT_DELTA);
break;
}
}
});
}
}
package application;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.input.KeyEvent;
public class WarehouseKeeper extends ImageLoader {
private Image playerImage;
private ImageView image;
private int speed;
private double xPosition;
private double yPosition;
public WarehouseKeeper(ImageView wareHouseImage) {
super(wareHouseImage);
this.speed = speed;
this.xPosition = xPosition;
this.yPosition = yPosition;
this.wareHouseImage.relocate(xPosition, yPosition);
}
public void updateUI() {
wareHouseImage.relocate(xPosition, yPosition);
}
public double getCenterX() {
return xPosition * 0.5;
}
public double getCenterY() {
return yPosition * 0.5;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public double getxPosition() {
return xPosition;
}
// one of the ideas i had
public void setxPosition(double xPosition) {
this.xPosition = xPosition.setTranslateX(1.0);
}
public double getyPosition() {
return yPosition;
}
public void setyPosition(double d) {
this.yPosition = d + 1.0;
}
public void setTranslateY(double yPosition) {
// TODO Auto-generated method stub
yPosition = yPosition + 2.0;
}
}
package application;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class ImageLoader {
protected ImageView wareHouseImage;
private Object diamondImage;
private Object wallImage;
private Object mapImage;
private Object crateImage;
public ImageLoader(ImageView wareHouseImage) {
this.wareHouseImage = showWareHouseImage();
}
public ImageView getWareHouseImage() {
return wareHouseImage;
}
public void setWareHouseImage(Image wareHouseImage) {
this.wareHouseImage = showWareHouseImage();
}
public static ImageView showWareHouseImage() {
ImageView wareHouse = new ImageView();
wareHouse.setFitHeight(45);
wareHouse.setFitWidth(45);
Image wareHouseImage = new Image("application/warehouse.png");
wareHouse.setImage(wareHouseImage);
return wareHouse;
}
public Object getDiamondImage() {
return diamondImage;
}
public void setDiamondImage(Object diamondImage) {
this.diamondImage = diamondImage;
}
public Object getWallImage() {
return wallImage;
}
public void setWallImage(Object wallImage) {
this.wallImage = wallImage;
}
public Object getMapImage() {
return mapImage;
}
public void setMapImage(Object mapImage) {
this.mapImage = mapImage;
}
public Object getCrateImage() {
return crateImage;
}
public void setCrateImage(Object crateImage) {
this.crateImage = crateImage;
}
}
问题可能出在您对面向对象的 JavaFX 如何工作的理解上,该对象可能由 WareHouseKeeper 和 ImageLoader 类创建,但该对象是在关卡类上实例化的,这意味着如果您在它具有的关卡类上实例化该对象在级别类中移动。例如你有什么是
private static void moveWareHouse(Scene scene, final WarehouseKeeper keeper) {
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
switch (event.getCode()) {
case W:
keeper.setyPosition(keeper.getyPosition() - KEYBOARD_MOVEMENT_DELTA);
break;
case D:
keeper.setxPosition(keeper.getxPosition() + KEYBOARD_MOVEMENT_DELTA);
break;
case A:
keeper.setyPosition(keeper.getyPosition() + KEYBOARD_MOVEMENT_DELTA);
break;
case S:
keeper.setxPosition(keeper.getxPosition() - KEYBOARD_MOVEMENT_DELTA);
break;
}
}
});
}
由于对象已传递给函数,您只需要直接从关卡类中移动它而不是从其他类中移动它,所以这将更改为
private static void moveWareHouse(Stage theStage, Group wHK) {
theStage.addEventFilter(KeyEvent.KEY_RELEASED, e -> {
e.consume();
switch (e.getCharacter()) {
case W:
keeper.setLayoutY(keeper.getLayoutY() - KEYBOARD_MOVEMENT_DELTA);
break;
case D:
keeper.setLayoutX(keeper.getLayoutX() + KEYBOARD_MOVEMENT_DELTA);
break;
case A:
keeper.setLayoutY(keeper.getLayoutY() + KEYBOARD_MOVEMENT_DELTA);
break;
case S:
keeper.setLayoutX(keeper.getLayoutX() - KEYBOARD_MOVEMENT_DELTA);
break;
}
});
}
编辑 我还注意到您将场景解析为关键侦听器,如果您将舞台设置为关键侦听器,则无论您在何处单击它,都需要您先单击场景(以使其成为焦点),然后它才会侦听键将永远是根本焦点,并始终倾听钥匙。
进一步编辑 正如我在顶部的对话中提到的,您最好在您的 WarehouseKeeper 类中创建整个 WarehouseKeeper 并将其实例化到您的主类(level1)中,这样对象的控制就在 level1 内,但 level1 没有所有创建它的代码(因此,如果您以后需要修改它的创建或再次使用它,您可以通过创建它的新实例并将其添加到场景中来调用更多它们)例如。
public final Group warehouseKeeper(ImageView image) {
Group tempGroup;
/* insert necessary code here to add image to group and anything else you want in the group */
return tempGroup;
}
然后你可以通过调用
将它实例化到 level1final Group wHK = new WarehouseKeeper.warehouseKeeper();
wHK.setLayoutX(/*some init val */);
wHK.setLayoutY(/*some init val */);
root.getChildren().add(wHK);