2011-10-27 4 views
0

私は現在ライブラリへのライブラリ拡張を作成しています(TiledMapPlus)。これは、タイルを使用して人々へのより大きなサポートを提供することを目的とし、データへのより速いアクセスなどを可能にする。Javaを使用してTiledMapデータを正しく圧縮して変換する方法は?

ライブラリの目的の1つは動的マップ編集を提供することであった。 私は昨日これを実装しましたが、今はあなたの助けが必要です。私のコードに何か問題があります。

だから、基本的な問題は、XMLの階層データが不正な形式のある、ある、とはTiledMapパーサ/エディタでを読み取ることができません。 私は多くのチュートリアルを通して、データをGZIP圧縮、BASE64フォーマットに圧縮しようとしました。私は最終的にGZIP圧縮オプションを使用してthisを使用しました。 しかし、データなどを圧縮するたびに、常にTiled2dエディタよりも出力が大きくなり、破損したデータが出力されます。どうしてこれなの?ファイルへ

リンク:

A Tiled Map automatically generated by the TiledMap editor

A Tiled Map generated from the above TiledMap, using my library

Snippet of the code from my library which isn't working

Alternatively you can view them all formatted here

+0

そのすべてを追うことはできませんでしたが、圧縮したいものにbase64を使用することは、かなり悪い考えです。しかし、もう一度、まともなコンプレッサーは、バイトの7番目と8番目のビットが常に0であり、それに応じて圧縮するという事実を拾い上げるでしょう... – bdares

+0

その混乱があれば、私はGZIPを使用してデータを圧縮してからBase64。そのTiledMap標準、私はそれを笑って定義しませんでした。 – liamzebedee

答えて

1

ありがとうLiam私は実際にあなたが書いたすべての可能なことに従ってきました。そして、それは最終的に私のためにこれを解決したTiledMapPlusのあなたのコードでした。

  Element layer = doc.createElement("layer"); 
     layer.setAttribute("name", "layer"); 
     layer.setAttribute("width", width); 
     layer.setAttribute("height", height); 



      Element data = doc.createElement("data"); 

      ByteArrayOutputStream os = new ByteArrayOutputStream();     
      for(int tileY = 0;tileY<layerHeight;tileY++){ 
       for(int tileX = 0;tileX<layerWidth;tileX++){ 
        int tileGID = this.data[tileX][tileY]; 
        os.write(tileGID); 
        os.write(tileGID << 8); 
        os.write(tileGID << 16); 
        os.write(tileGID << 24); 
       } 
      } 
      os.flush(); 
      String compressedData = Base64.encodeBytes(os.toByteArray(),Base64.DONT_BREAK_LINES|Base64.GZIP|Base64.ENCODE); 
      data.appendChild(doc.createTextNode(compressedData));    
      data.setAttribute("encoding", "base64"); 
      data.setAttribute("compression","gzip"); 

      layer.appendChild(data); 

     mapElement.appendChild(layer); 

私は、同じデータ生成技術を使用して、私が望む任意のID番号を渡すと、それは受け入れ、完全にそれをコードされています:ここで

正しくリアムのコードから取られた作品のソリューションです!

1

使用している方法は、このような出力ストリームのパイプラインを設定します:

たObjectOutputStream - > GZIPOutputStream - > Base64OutputStream

それはJAVAバイト配列オブジェクトをシリアル化されているのであなたは、まずObjectOuputStreamを持っている必要はありません。 GZIpOuputStreamにバイトを直接入力するだけです。

public String compressAndEncode(byte[] data) throws Exception { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    GZIPOutputStream gz = new GZIPOutputStream(out); 
    ByteArrayInputStream in = new ByteArrayInputStream(data); 
    int c; 
    while ((c = in.read()) != -1) 
     gz.write(c); 
    gz.finish(); 
    Base64 b = new Base64(0); 
    return b.encodeToString(out.toByteArray()); 
} 
0

私は四〇から二からの回答の値に話すカント:あなたは適切な方法を見つけることができない場合、あなた自身の使用のApache Commonsのコーデックを設定することは非常に簡単です。それがうまくいけば、そう答えてください。私はこれをゲームImの書き込みで動作させています。問題は使用している形式です。

TiledMapPlusとslick2dに必要なデータが圧縮され、gzipedになっているTMXファイルを作成すると、一般的な非圧縮ファイルのような<tiled>タグは使用されません。そのカウンターは直感的ですが、それはどのように動作します。

<data>タグでデータを作成するには、32ビット整数を使用して各gidの文字列/ストリームを作成し、それをUTF-8に変換してから圧縮してエンコードする必要があります。ここで

は、私は、Web上のどこかに見つかった例です。

   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が1000などの32ビット文字列で表されていることがわかります。これらは、組み込みのタイルセットファイルに直接関連付けられます。私はこの技術をGID 9(9000として表示)を上回るように使うことができるという点で問題を抱えています。これはByteStream自体と関係があると私は信じています。私が1100と入力すると、タイルセットにタイルが20個ほどあるにもかかわらず、そのタイルのGIDのヌル値としてクラッシュします(ファイルを読み込んだとき)。したがって、任意の2桁の数字のエンコーディングと圧縮の後に何が返されるかに問題があります。これはobj-cの仕事をしている人々がこれと同じ問題を抱えているように見えるので、Java固有のようです。

ご協力いただければ幸いです。

+0

私はTiledMapPlusライブラリの作成者であり、TiledMapファイルを書くことができます。 – liamzebedee

+0

混乱して申し訳ありませんが、ランダムに生成されたマップを調べるとこの記事が表示されます。うまくいけば、これは私の追加がどこにでもあるので、それを持つ人々を助けるでしょう。私の「進歩した」問題は私の他のポストで解決されます。基本的には、私が見つけたこの文字列技法より良い方法があります。より良い方法は、LiamがTiledMapPlusのwrite()メソッドでこれを行う方法です(ここではhttps://github.com/liamzebedee/TiledMapPlus/blob/master/src/org/newdawn/slick/tiled/TiledMapPlus)。 java)。 このライブラリLiamに関する素晴らしい作業をお寄せいただき、ありがとうございます。 状態間にデータを渡す際にはどの言葉ですか? –

+0

私は42の答えが本当に問題を解決しなかったと仮定して正しいですか? 「」というタグをエンコードしていたのは本当ですか? これは多くのマップ生成の問題が出てくるので、私はいくつかの詳細を追加しました。多くの人がランダムなマップなどで問題を抱えているようです。 –

関連する問題