Я не могу говорить о значении ответа из сорока двух. Если это сработало, пожалуйста, ответьте, сказав так. У меня это работает в игре, которую я пишу, и проблема в используемом вами формате.
Когда вы создаете файл TMX, в котором данные сжаты и заархивированы gzip, как это требуется для TiledMapPlus и slick2d, вы НЕ используете теги <tiled>
, как в обычных несжатых файлах. Это контринтуитивно, но так оно и работает.
Чтобы создать данные в теге <data>
, вам нужно создать строку/поток каждого gid, используя 32-битное целое число, а затем преобразовать его в UTF-8, а затем сжать и закодировать.
Вот пример, который я нашел где-то в Интернете:
Element data = doc.createElement("data");
data.setAttribute("encoding", "base64");
data.setAttribute("compression", "gzip");
String bytestring = new String();
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
switch(this.data[x][y]){
case 0: bytestring += "1000";
break;
case 1: bytestring += "2000";
break;
case 2: bytestring += "3000";
break;
case 3: bytestring += "4000";
break;
case 4: bytestring += "5000";
break;
case 5: bytestring += "6000";
break;
case 6: bytestring += "7000";
break;
case 7: bytestring += "8000";
break;
case 8: bytestring += "9000";
break;
}
}
}
Text value = doc.createTextNode(compress(bytestring));
data.appendChild(value);
Сжатие и кодирование выполняются следующим образом:
private static String compress(String str){
byte byteAry[] = null;
try{
byteAry = str.getBytes("UTF-8");
}catch( UnsupportedEncodingException e){
System.out.println("Unsupported character set");
}
for(int i = 0; i < byteAry.length; i++) {
if(byteAry[i] == 48)
byteAry[i] = 0;
if(byteAry[i] == 49)
byteAry[i] = 1;
if(byteAry[i] == 50)
byteAry[i] = 2;
if(byteAry[i] == 51)
byteAry[i] = 3;
if(byteAry[i] == 52)
byteAry[i] = 4;
if(byteAry[i] == 53)
byteAry[i] = 5;
if(byteAry[i] == 54)
byteAry[i] = 6;
if(byteAry[i] == 55)
byteAry[i] = 7;
if(byteAry[i] == 56)
byteAry[i] = 8;
if(byteAry[i] == 57)
byteAry[i] = 9;
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try {
OutputStream deflater = new GZIPOutputStream(buffer);
deflater.write(byteAry);
deflater.close();
}catch (IOException e) {
throw new IllegalStateException(e);
}
String results = Base64.encodeBase64String(buffer.toByteArray());
return results;
}
Теперь вот более сложный вопрос, который очень связан. В приведенном выше примере вы можете видеть, что каждый GID представлен 32-битной строкой, такой как 1000. Они напрямую связаны с включенным файлом набора тайлов. У меня проблема в том, что я могу использовать эту технику, чтобы подняться выше GID 9 (показать как 9000). Я считаю, что это как-то связано с самим ByteStream. Если я ввожу 1100, он вылетает из-за нулевого значения для GID этой плитки (при чтении файла), даже если в наборе плиток около 20 плиток. Итак, что-то не так с тем, что возвращается после кодирования и сжатия для любого двузначного числа. Это кажется довольно специфичным для Java, поскольку люди, работающие с obj-c, похоже, не сталкиваются с этой проблемой.
Любая помощь будет принята с благодарностью.
25.02.2012