6. 游戏地图文件加载
? 之前,我们将初始关卡的坐标直接写入代码中,如下图中的gameText,其中重要的数据是x,y,以及描述的信息TextLocation和PeopleLocation 现在我们提取初始关卡的关键数据:
text
baba 4,5
is1 5,5
you 6,5
flag 12,5
is2 13,5
win 14,5
wall 4,13
is3 5,13
stop 6,13
rock 12,13
is4 13,13
push 14,13
people
baba 5,9
flag 14,9
rock 9,8
rock 9,9
rock 9,10
wall 4,7
wall 5,7
wall 6,7
wall 6,7
wall 7,7
wall 8,7
wall 9,7
wall 10,7
wall 11,7
wall 12,7
wall 13,7
wall 14,7
wall 4,11
wall 5,11
wall 6,11
wall 6,11
wall 7,11
wall 8,11
wall 9,11
wall 10,11
wall 11,11
wall 12,11
wall 13,11
wall 14,11
如此,我们改为文件加载,这样我们仅需要改变文件就可以快速修改关卡
6.1 文件加载到内存中(坐标)
? 读取文件的操作,我们放置于GameUtil中,分析上面的文件,作者准备存储为一个Map,分别放置GameText和GamePeople的坐标,同样,这两个类依然是以Map形式存储,为了方便,我们建立了一个Location类(util包下),专门存储坐标。
public class Location {
private int x, y;
public Location(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
在GameUtil建立文件读取方法
public static Map<String, Object> loadMap(String url)
存储结构:
Map<String, Object> res = new HashMap<>();
Map<String, Location> text = new HashMap<>();
Map<String, List<Location>> people = new HashMap<>();
在constant新建地图数据常量:
public interface MapConstant {
String TEXT = "text";
String PEOPLE = "people";
String BABA = "baba";
String ROCK = "rock";
String WALL = "wall";
String FLAG = "flag";
String WATER = "water";
String TILE = "tile";
String GRASS = "grass";
String IS1 = "is1";
String IS2 = "is2";
String IS3 = "is3";
String IS4 = "is4";
String IS5 = "is5";
String PUSH = "push";
String STOP = "stop";
String YOU = "you";
String WIN = "win";
String SINK = "sink";
}
文件读取、字符串分隔:
public static Map<String, Object> loadMap(String url) throws IOException {
Map<String, Object> res = new HashMap<>();
Map<String, Location> text = new HashMap<>();
Map<String, List<Location>> people = new HashMap<>();
res.put(MapConstant.TEXT, text);
res.put(MapConstant.PEOPLE, people);
URL resource = GameFrame.class.getResource(url);
InputStream resourceAsStream = GameFrame.class.getResourceAsStream(url);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resourceAsStream));
String line = bufferedReader.readLine();
line = bufferedReader.readLine();
Map<String, Location> textMap = (Map<String, Location>) res.get(MapConstant.TEXT);
while (!MapConstant.PEOPLE.equalsIgnoreCase(line)) {
String[] split = line.split("[\\s+ ,]");
textMap.put(split[0], new Location(Integer.parseInt(split[1]), Integer.parseInt(split[2])));
line = bufferedReader.readLine();
}
Map<String, java.util.List<Location>> peopleMap = (Map<String, java.util.List<Location>>) res.get(MapConstant.PEOPLE);
while (null != (line = bufferedReader.readLine())) {
String[] split = line.split("[\\s+ ,]");
List<Location> orDefault = peopleMap.getOrDefault(split[0], new ArrayList<>());
orDefault.add(new Location(Integer.parseInt(split[1]), Integer.parseInt(split[2])));
peopleMap.put(split[0], orDefault);
}
return res;
}
6.2 GameText\GamePeople初始化
我们在ui/asset下新建map包,存储我们的地图,这里我们存储为level1,level1中即为上述我们提取的数据信息
为了之后提取坐标方便,我们在Text,People分别加入如下构造方法
public Text(Location location, String rule) {
super(location.getX() * 24, location.getY() * 24);
this.rule = rule;
image = GameUtil.loadBufferedImage(rule);
}
public People(Location location, String name) {
super(location.getX() * 24, location.getY() * 24);
this.name = name;
this.image = GameUtil.loadBufferedImage(name);
}
在GameText调用GameUtil读取地图,提取坐标
public GameText() {
this.textList = new ArrayList<>();
Map<String, Object> stringObjectMap = null;
try {
stringObjectMap = GameUtil.loadMap("asset/map/level1");
} catch (IOException e) {
e.printStackTrace();
}
Map<String, Location> locationMap = (Map<String, Location>)stringObjectMap.get(MapConstant.TEXT);
for (String mapConstant : locationMap.keySet()) {
Location location = locationMap.get(mapConstant);
switch (mapConstant) {
case MapConstant.BABA:
this.textList.add(new Text(location, TextLocation.BABA));break;
case MapConstant.FLAG:
this.textList.add(new Text(location, TextLocation.FLAG));break;
case MapConstant.WALL:
this.textList.add(new Text(location, TextLocation.WALL));break;
case MapConstant.ROCK:
this.textList.add(new Text(location, TextLocation.ROCK));break;
case MapConstant.WIN:
this.textList.add(new Text(location, TextLocation.WIN));break;
case MapConstant.PUSH:
this.textList.add(new Text(location, TextLocation.PUSH));break;
case MapConstant.STOP:
this.textList.add(new Text(location, TextLocation.STOP));break;
case MapConstant.YOU:
this.textList.add(new Text(location, TextLocation.YOU));break;
case MapConstant.IS1:
this.textList.add(new Text(location, TextLocation.IS));break;
case MapConstant.IS2:
this.textList.add(new Text(location, TextLocation.IS));break;
case MapConstant.IS3:
this.textList.add(new Text(location, TextLocation.IS));break;
case MapConstant.IS4:
this.textList.add(new Text(location, TextLocation.IS));break;
}
}
}
在GamePeople中调用GameUtil读取地图,提取坐标
public GamePeople() {
this.peopleList = new ArrayList<>();
this.peopleMap = new HashMap<>();
this.peopleMap.put(PeopleLocation.BABA, new ArrayList<People>());
this.peopleMap.put(PeopleLocation.ROCK, new ArrayList<People>());
this.peopleMap.put(PeopleLocation.WALL, new ArrayList<People>());
this.peopleMap.put(PeopleLocation.FLAG, new ArrayList<People>());
Map<String, Object> stringObjectMap = null;
try {
stringObjectMap = GameUtil.loadMap("asset/map/level1");
} catch (IOException e) {
e.printStackTrace();
}
Map<String, List<Location>> locationMap = (Map<String, List<Location>>)stringObjectMap.get(MapConstant.PEOPLE);
for (String mapConstant : locationMap.keySet()) {
List<Location> locations = locationMap.get(mapConstant);
switch (mapConstant) {
case MapConstant.BABA:
List<People> babaList = this.peopleMap.get(PeopleLocation.BABA);
for (int i = 0; i < locations.size(); i++) {
People baba = new People(locations.get(i), PeopleLocation.BABA);
babaList.add(baba);
this.peopleList.add(baba);
}
break;
case MapConstant.FLAG:
List<People> flagList = this.peopleMap.get(PeopleLocation.FLAG);
for (int i = 0; i < locations.size(); i++) {
People flag = new People(locations.get(i), PeopleLocation.FLAG);
flagList.add(flag);
this.peopleList.add(flag);
}
break;
case MapConstant.WALL:
List<People> wallList = this.peopleMap.get(PeopleLocation.WALL);
for (int i = 0; i < locations.size(); i++) {
People wall = new People(locations.get(i), PeopleLocation.WALL);
wallList.add(wall);
this.peopleList.add(wall);
}
break;
case MapConstant.ROCK:
List<People> rockList = this.peopleMap.get(PeopleLocation.ROCK);
for (int i = 0; i < locations.size(); i++) {
People rock = new People(locations.get(i), PeopleLocation.ROCK);
rockList.add(rock);
this.peopleList.add(rock);
}
break;
}
}
}
至此,我们完成地图的文件接口编写。
|