我正在完成一项任务,我从文本文件阅读器中制作迷宫。我已经制作了一个方法,让我选择一个文本文件并将其转换为迷宫,但我无法从该方法中提取迷宫。我在第28行获得了I
:NullPointerException
我一直坚持为什么这个方法不能返回我的数组,以及我如何让方法返回StartX和StartY位置。
X = Maze[0].length;
编辑:
对于未来的人来说,这是我解决问题的代码:
package Innlevering09;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javafx.application.Application;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
public class MazeGame extends Application {
MazeRoute[][] Maze;
int X;
int Y;
int StartX;
int StartY;
Player Player;
public void start(Stage primaryStage) {
try {
GridPane root = new GridPane();
Player Player = new Player(StartX, StartY);
Maze = FileReader();
X = Maze[0].length;
Y = Maze.length;
root.add(Player.getAppearance(), Player.getXpos(), Player.getYpos());
for(int x = 0; x<X; x++){
for(int y = 0; y<Y; y++){
root.add(Maze[x][y].getAppearance(), x, y);
}
}
Scene scene = new Scene(root, X*10, Y*10);
//scene.setOnKeyPressed(new FileListener(this));
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public MazeRoute[][] FileReader() {
String Text = "";
File File;
int Row;
FileChooser FileChooser = new FileChooser();
FileChooser.setTitle("Open a textfile");
FileChooser.getExtensionFilters().add(new ExtensionFilter("Text Files", "*.txt"));
File = FileChooser.showOpenDialog(null);
try (Scanner FileReader = new Scanner(File)){
X = FileReader.nextInt();
Y = FileReader.nextInt();
Text = FileReader.nextLine();
MazeRoute[][] Maze = new MazeRoute[X][Y];
while (FileReader.hasNext()){
Text = FileReader.nextLine();
for (int i = 0 ; i < X ; i++){
for (Row = 0 ; Row < Y ; Row++) {
char Character = Text.charAt(i);
switch (Character){
case '#':
Maze[i][Row] = new Wall(i, Row);
break;
case ' ':
Maze[i][Row] = new NormalTile(i, Row);
break;
case '-':
Maze[i][Row] = new EndTile(i, Row);
break;
case '*':
Maze[i][Row] = new NormalTile(i, Row);
StartX = i;
StartY = Row;
break;
}Row++;
}
}
}
}catch (FileNotFoundException Error) {
System.out.println("Cannot open file");
Error.printStackTrace();
}
return Maze;
}
public static void main(String[] args) {
launch(args);
}
}
我所做的更改如下:
public class MazeGame extends Application {
MazeRoute[][] maze;
int X;
int Y;
int startX;
int startY;
Player player = new Player();
public void start(Stage primaryStage){
try{
maze = fileReader();
player.setXpos(startX);
player.setYpos(startY);
GridPane root = new GridPane();
Scene scene = new Scene(root, Color.BLACK);
Player player = new Player();
for(int x = 0; x<X; x++){
for(int y = 0; y<Y; y++){
root.add(maze[x][y].getAppearance(), maze[x][y].getTileXpos(), maze[x][y].getTileYpos());
}
}
root.add(player.getAppearance(), player.getXpos(), player.getYpos());
primaryStage.setTitle("MazeGame");
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public MazeRoute[][] fileReader() throws FileNotFoundException {
String text = "";
File file;
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open a text file with a maze");
fileChooser.getExtensionFilters().add(new ExtensionFilter("Text Files", "*.txt"));
file = fileChooser.showOpenDialog(null);
Scanner fileScanner = new Scanner(file);
X = fileScanner.nextInt();
Y = fileScanner.nextInt();
text = fileScanner.nextLine();
MazeRoute[][] methodMaze = new MazeRoute [X][Y];
while (fileScanner.hasNext()) {
for (int row = 0 ; row < Y ; row++){
text = fileScanner.nextLine();
for (int i = 0 ; i < X ; i++) {
char character = text.charAt(i);
switch (character) {
case '#':
methodMaze[i][row] = new Wall(i, row);
break;
case ' ':
methodMaze[i][row] = new NormalTile(i, row);
break;
case '-':
methodMaze[i][row] = new EndTile(i, row);
break;
case '*':
methodMaze[i][row] = new NormalTile(i, row);
startX = i;
startY = row;
break;
}
}
}
}
return methodMaze;
}
public static void main(String[] args) {
launch(args);
}
}
循环中交换了row
和i
,这意味着循环现在通过一个完整的行,然后再递增到下一个循环。for
移到text = fileScanner.nextLine();
循环的内部,以便它实际扫描下一行。for
循环从0开始计数而不是1(我知道这个愚蠢的错误)。答案 0 :(得分:1)
方法FileReader
(名称应以小写字母开头),返回Maze
。
但是,这是类级别的属性,因为在try-catch中声明的具有相同名称的局部变量超出了范围。
此类级属性尚未分配,因此等于null
。
答案 1 :(得分:0)
这是一个范围问题。您没有返回函数“FileReader”中声明的变量,因为它仅在while循环的范围内声明。可用于返回的唯一变量是在类的范围内声明的变量。
答案 2 :(得分:0)
首先,正如其他人所指出的那样,Java命名约定是所有变量,方法和非静态字段必须以小写字母开头。当变量与现有Java SE类具有相同的名称时,这一点尤为重要。您的代码将更容易阅读,您不仅可以帮助自己,还可以更快地获得Stack Overflow上的人们的帮助。
在FileReader
方法中,您有以下这一行:
MazeRoute[][] Maze = new MazeRoute[X][Y];
该行声明了一个名为Maze
的新变量,它与MazeGame类的Maze字段之间没有无关系。所有后续代码行都填充了新变量,而不是MazeGame类中声明的Maze字段。
变量仅存在于声明它的括号内的块中。在这种情况下,该块是您的try
块,因为在Maze
块内声明了新的try
变量。到达try
块的末尾后,Maze
变量不存在,其值可用于垃圾回收。
当您的FileReader方法到达其return语句时,该Maze变量不存在,因此return Maze;
实际上引用了MazeGame类的Maze字段。但是该字段从未由您的方法设置,因为您的代码设置了一个本地定义的变量,该变量恰好具有相同的名称。在Java中,除非另外设置,否则所有对象字段都为空。所以该方法返回null。
解决问题的最简单方法是避免定义新的Maze变量。改变这个:
MazeRoute[][] Maze = new MazeRoute[X][Y];
到此:
Maze = new MazeRoute[X][Y];