0

だから私は現在、TiledMapPlusと呼ばれる Slick2d ライブラリのライブラリ拡張を作成しています。これは、Tiled を使用する人々により大きなサポートを提供し、データなどへのアクセスを高速化することを目的としています。

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

したがって、基本的な問題は、XML レイヤー データの形式が正しくなく、TiledMap パーサー/エディターで読み取れないことです。データをGZIP 圧縮された BASE64 形式に圧縮しようとする数多くのチュートリアルを実行しました。私は最終的にこれを GZIP 圧縮オプションで使用することにしました。ただし、データなどを圧縮するたびに、常に Tiled2d エディターよりも大きく出力され、破損したデータが出力されます。どうしてこれなの?

ファイルへのリンク:

TiledMap エディターによって自動的に生成された Tiled Map

私のライブラリを使用して、上記の TiledMap から生成された Tiled Map

動作していないライブラリからのコードのスニペット

または、ここでフォーマットされたすべてを表示できます

4

3 に答える 3

1

ありがとうリアム私は実際にあなたが書いたことを見つけることができるすべてのものに従ってきました.TiledMapPlusのあなたのコードが最終的に私のためにこれを解決しました.

Liam のコードから取得した、正しく機能するソリューションを次に示します。

            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番号を渡しています。それは完全に受け入れられ、エンコードされています!

于 2012-02-26T15:03:19.127 に答える
1

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

ObjectOutputStream -> GZIPOutputStream -> Base64OutputStream

最初の ObjectOuputStream は Java バイト配列オブジェクトをシリアライズしているため、必要ありません。GZIpOuputStream にバイトを直接フィードする必要があります。適切な方法が見つからない場合は、apache commons コーデックを使用して独自の方法を簡単に設定できます。

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());
}
于 2011-10-27T21:04:34.640 に答える
0

四十二からの答えの価値について話すことはできません。うまくいった場合は、そう言って返信してください。私が書いているゲームでこれが機能するようになりましたが、問題は使用している形式にあります。

TiledMapPlus および slick2d に必要なように、データが圧縮および gzip された 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 の null 値としてクラッシュします。そのため、2 桁の数字のエンコードと圧縮の後に返される内容に問題があります。これは、obj-c を使用している人々がこれと同じ問題に遭遇していないように見えるため、かなり Java 固有のようです。

どんな助けでも大歓迎です。

于 2012-02-25T22:05:00.830 に答える