我需要一个小型火星着陆器视频游戏的帮助,我正在为我的计算机科学课程做准备。我们必须使用扫描仪阅读游戏配置文本文件,并将其用作游戏不同方面的规则(重力,你拥有的燃料量等)。她给了我们不同的文本文件,它们都有不同的困难和价值观,但它们都具有相同的格式,因此我需要能够简单地调用不同的文本文件并准备好一个新的级别。我的问题是:
如何将文件中的输入转换为单独的变量,以便我可以操作它们来创建游戏?
这里是用于读取文本文件的代码,它还将其打印到控制台
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class MarsLander {
public static void main(String [] args) {
try {
Scanner sc = new Scanner(new File("gameConfig.txt"));
while (sc.hasNext()){
String s = sc.next();
System.out.println(s);
}
sc.close();
}
catch (FileNotFoundException e) {
System.out.println("Failed to open file!");
}
}
}
以下是其中一个文字游戏配置文件:
1000 500
mars_sky.jpg
ship.png ship_bottom.png ship_left.png ship_right.png ship_landed.png ship_crashed.png
20 50
500.0 400.0
100
thrust.wav yay.wav explosion.wav
-0.1
2.0
0.5
500 50
答案 0 :(得分:0)
在我的解决方案中,我正在思考一些更通用的东西。让我先向您展示我编写的代码。然后我会解释它的行为和特殊性。
public class GameExample {
private static class Game {
private Long x, y;
private List<String> images = new ArrayList<>();
private Game(final Long x, final Long y, final List<String> images) {
this.x = x;
this.y = y;
this.images = images;
}
public Long getX() {
return x;
}
public Long getY() {
return y;
}
public List<String> getImages() {
return images;
}
public static class Builder {
// Parsing methods used by the builder to read the files and build the configuration
// TODO: add here builder methods for each line of the file
private final List<BiFunction<String, Game.Builder, Game.Builder>> parsingMethods = Arrays.asList(
(str, builder) -> builder.withPositions(str),
(str, builder) -> builder.withImages(str));
private Long x, y;
private List<String> images = new ArrayList<>();
private Builder withPositions(final String str) {
String[] positions = str.split(" ");
x = Long.valueOf(positions[0]);
y = Long.valueOf(positions[1]);
return this;
}
private Builder withImages(final String str) {
Stream.of(str.split(" ")).forEach(imgStr -> images.add(imgStr));
return this;
}
public Game build(final String filename) throws IOException {
Scanner sc = null;
try {
// Read the file line by line
List<String> lines = Files.lines(Paths.get(filename)).collect(Collectors.toList());
// Iterate over each line and call the configured method
IntStream.range(0, lines.size()).forEach(
index -> parsingMethods.get(index)
.apply(lines.get(index), this));
// Build an instance of the game
return new Game(x, y, images);
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
if (sc != null) sc.close();
}
}
}
}
public static void main(String[] args) throws IOException {
final Game.Builder builder = new Game.Builder();
Game game = builder.build("file.txt");
System.out.println(game.getX() + ":" + game.getY());
System.out.println(game.getImages());
}
}
这段代码会输出:
<强> 10:15 强>
<强> test.jpg放在强>
使用给定的配置文件:
10 15
<强> test.jpg放在强>
让我解释一下做了什么。我们定义了一个Game构建器,它只有一个带有签名Game build(final String filename)
的公共方法。它需要文件名,并将根据此文件的内容构建游戏。这种方法的基础是构建器定义了一个列表,用于确定构建器的哪个方法用于文件的每一行:
private final List<BiFunction<String, Game.Builder, Game.Builder>> parsingMethods = Arrays.asList(
(str, builder) -> builder.withPositions(str),
(str, builder) -> builder.withImages(str));
此列表显示:
withPositions
用于第一行withImages
用于第二行现在,在build
方法中,它实现了在行上执行方法的逻辑:
// Iterate over each line and call the configured method
IntStream.range(0, lines.size()).forEach(
index -> parsingMethods.get(index)
.apply(lines.get(index), this));
因此,我们可以通过执行以下操作轻松解析新的数据行:
在构建器中添加一个新的私有方法,描述如何解析该行;
在名为parsingMethods
的列表中添加此方法。