我在设计正确的映射时遇到了问题。
我正在开发一个自上而下的RPG游戏,你只能在运行时看到地图的部分(块) - 当从一个块移动到另一个块时,会加载新的块数据。
取决于我的位置,加载了不同的数据。
目前我的代码看起来像这样(但肯定更长)
public static final int getChunkIdForPos(int x, int y){
switch (x) {
case 1248:
switch (y) {
case 1247: return R.raw.overworld_512;
case 1248: return R.raw.overworld_528;
case 1249: return R.raw.overworld_544;
default: break;}break;
case 1249:
switch (y) {
case 1247: return R.raw.overworld_513;
case 1248: return R.raw.overworld_529;
case 1249: return R.raw.overworld_545;
default: break;}break;
}
return R.raw.overworld_161;
}
问题是此代码不易阅读且不易维护。关于如何做得更好的任何想法?
我在考虑使用Map<Integer,<Map<Integer,Integer>>
来映射数据,但这需要先创建Map。这也意味着你带着很多“死亡”的人。对象作为键(对于SparseArray<SparseArray<>>
)
注意:您无法按照此answer - Implemention a Lookup Table
中的建议确定任何数学的返回值选择此设计的原因是在不创建任何对象的情况下获得答案 - 查找只运行两个开关/案例语句并动态提供答案!
答案 0 :(得分:0)
如果您使用的Point
课程已经实施equals
和hashcode
,则可以将其用作地图中的键。
现在实际的查找机制崩溃为:
static final Map<Point, Integer> lookup = new HashMap<>();
static {
// Looks a lot like your case statement eh?
lookup.put(new Point(1248, 1247), 512);
lookup.put(new Point(1248, 1248), 528);
lookup.put(new Point(1248, 1249), 544);
lookup.put(new Point(1249, 1247), 513);
lookup.put(new Point(1249, 1248), 529);
lookup.put(new Point(1249, 1249), 545);
// Could also be populated by other statics.
}
public static final int getChunkIdForPos(int x, int y) {
Integer got = lookup.get(new Point(x, y));
return got != null ? got : 161;
}
这样的优雅之处在于地图只构建一次。它是在可预测的时间内构建的(对类的第一次引用),并且可以通过其他模块添加(通过稍微调整)。
以下是正确实施Point
和equals
的{{1}}类的示例。
hashcode
答案 1 :(得分:0)
好的,首先要做的事情是:我将地图限制在10.000x10.000到256x256
处理此问题的正确方法是使用代码生成器。在一个单独的项目中,我没有限制创建一个世界地图编辑器,让我可以看到所有组合块。地图完成后(提示:您现在可以保存/加载地图)代码发射器会为您生成一个类。
魔术是从codeEmitter类完成的:
int[][] worldMap = new int[256][256]; //generated via GUI
File file = new File(fileName);
BufferedWriter br = new BufferedWriter(new FileWriter(file));
//writing header
for (int dy = 0; dy < 256; dy++) {
br.write(" public static int row_"+dy+"(int x){\n");
br.write(" switch (x) {\n");
for (int dx = 0; dx < 256; dx++) {
br.write(" case " + dx + ": return " + worldMap[dx][dy] + ";\n");
}
br.write(" default: return 0;\n");
br.write(" }\n");
br.write(" }\n");
br.write("\n");
}
//writing trailer
结果与问题
中请求的代码非常相似 //this part of genCode is not explained above
public static final int getIdForPos(int x, int y, int area){
switch (y) {
case 0: return row_0(x);
case 1: return row_1(x);
//.. lots of rows
default: return 0;
}
}
//but this part is generated with the code above
public static int row_0(int x){
switch (x) {
case 0: return 4711;
case 1: return 815;
//.. lots of columns
default: return 0;
}
}