2

私はゲームに取り組んでおり、最終的にBufferedImageオブジェクトに変換したい複数の画像ファイル(png、gifなど)をロードする必要があります。私のセットアップでは、これらすべての画像を単一のzipファイル「Resources.zip」からロードしたいと思います。そのリソースファイルには、画像、マップファイル、およびオーディオファイルが含まれます。これらはすべて、きちんと並べられたさまざまなサブディレクトリに含まれています。これを実行したいのは、プログラムのアプレットバージョンとアプリケーションバージョンの両方でリソースのロードが(うまくいけば)簡単になるためです。また、アプレットバージョンの場合、このメソッドを使用すると、ゲームリソースのzipファイルの読み込みの進行状況を簡単に表示できるようになることを期待しています(このゲームの精巧さによっては、最終的に10MBになる可能性がありますが、期待していますブラウザに適したサイズに保つため)。

以下にzip処理クラスを含めました。アイデアは、私が別のリソース処理クラスを持っていて、それがResources.zipファイルから特定のリソースを引き出すために使用するZipFileHandlerオブジェクトを作成するということです。

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class ZipFileHandler
{
private ZipFile zipFile;

public ZipFileHandler(String zipFileLocation)
{
    try
    {
        zipFile = new ZipFile(zipFileLocation);
    }
    catch (IOException e) {System.err.println("Unable to load zip file at location: " + zipFileLocation);}
}

public byte[] getEntry(String filePath)
{
    ZipEntry entry = zipFile.getEntry(filePath);
    int entrySize = (int)entry.getSize();
    try
    {
        BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
        byte[] finalByteArray = new byte[entrySize];

        int bufferSize = 2048;
        byte[] buffer = new byte[2048];
        int chunkSize = 0;
        int bytesRead = 0;

        while(true)
        {
            //Read chunk to buffer
            chunkSize = bis.read(buffer, 0, bufferSize); //read() returns the number of bytes read
            if(chunkSize == -1)
            {
                //read() returns -1 if the end of the stream has been reached
                break;
            }

            //Write that chunk to the finalByteArray
            //System.arraycopy(src, srcPos, dest, destPos, length)
            System.arraycopy(buffer, 0, finalByteArray, bytesRead, chunkSize);

            bytesRead += chunkSize;
        }

        bis.close(); //close BufferedInputStream

        System.err.println("Entry size: " + finalByteArray.length);

        return finalByteArray;
    }
    catch (IOException e)
    {
        System.err.println("No zip entry found at: " + filePath);
        return null;
    }
}
}

そして、私は次のようにZipFileHandlerクラスを使用します。

ZipFileHandler zfh = new ZipFileHandler(the_resourceRootPath + "Resources.zip");
    InputStream in = new ByteArrayInputStream(zfh.getEntry("Resources/images/bg_tiles.png"));

    try
    {
        BufferedImage bgTileSprite = ImageIO.read(in);
    }
    catch (IOException e)
    {
        System.err.println("Could not convert zipped image bytearray to a BufferedImage.");
    }

そして良いニュースは、それが機能することです!

しかし、私がやっていることを行うためのより良い方法があるかもしれないと感じています(そして私はBufferedInputStreamsを扱うのにかなり慣れていません)。

結局、私の質問はこれです:

これもいい考えですか?

アプレットとアプリケーションに適した方法で、単一のダウンロード/ストリームで多数のゲームリソースファイルをロードするためのより良い方法はありますか?

私はすべての考えや提案を歓迎します!

ありがとう!

4

2 に答える 2

1

Javaプログラムを使用している場合は、通常、それをjarファイルとしてバンドルすることをお勧めします。したがって、クラスをこのjarファイル内(もちろんディレクトリ内)に単純に配置しないのはなぜですか。その後、あなたは単に使用することができます

`InputStream stream = MayClass.class.getResourceAsStream(imagePath);`

すべてのzipを自分で処理する代わりに、各画像のデータをロードします(また、アプレットのhttp urlなど、実際にはファイルシステム上にないjarに対しても機能します)。

また、jarがキャッシュされると想定していますが、パフォーマンスを測定し、外部zipファイルを使用してソリューションと比較する必要があります。

于 2011-03-28T22:52:04.707 に答える
1

複数のリソースを取得して1つの圧縮ファイルに入れることで、複数のWebアプリケーション(つまりGWT)が機能します。1つの大きなファイルをロードする方が、複数の小さなファイルよりも安価です。これは、アプリでこれらすべてのリソースを使用することを前提としています。そうでない場合は、遅延読み込みも実行可能な代替手段です。
そうは言っても、通常は、アプリを機能させてから、プロファイルを作成してボトルネックがどこにあるかを見つけるのが最善です。そうしないと、多くの複雑なコードが作成され、アプリが機能するまでにかなり時間がかかります。コードの10%〜20%は、実行に80〜90%の時間を要します。プロジェクトがほぼ完了するまで、それが10〜20%であるかどうかはわかりません。
あなたの目標がテクノロジーといじくり回しを学ぶことであるなら、順調に進んでいます-よさそうです。

于 2011-03-28T22:37:45.207 に答える