簡體   English   中英

將spritesheet中的sprites存儲在數組Libgdx中

[英]Store sprites from spritesheet in array Libgdx

我在Libgdx android資源中以png格式存儲了960x960 Spritesheet。 在我指定的初始化游戲中使用的精靈的類中,我試圖使其實現,以便從精靈表中剪切出120x120的精靈(因此數組中應有64個項目)。 我該怎么做? 這是我在類似情況下嘗試過的:

public static Texture spritesheet;
public static Sprite[] textures = new Sprite[64];
...
    //inside method that gets called once to initialize variables
    spritesheet = new Texture(
            Gdx.app.getType() == Application.ApplicationType.Android ?
                    "...Spritesheet.png" :
                    "android/assets/...Spritesheet.png"
    );
    spritesheet.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);

    for (int x = 0; x < 64; x ++) {
        textures[x] = new Sprite(spritesheet, x, (x%8), 64, 64);
        textures[x].flip(false, true);
    }

然后,我使用以下代碼在其他類中渲染精靈:

batch.draw(Assets.textures[0 /*this can be any number*/], (float) x, (float) y, 108, 108);

當我這樣做時,它的行為確實很奇怪。 它說在數組中填充了元素,但是仍然有數組索引超出界限異常,或者精靈只是瘋狂地渲染。 總體而言,它沒有奏效。 我要做的是制作它,這樣就不必分別初始化64個不同的Sprite,並進行制作,這樣我就可以通過更改渲染Sprite時輸入的索引輕松地更改Sprite,以便以后可以做其他事情就像動畫一樣 我該怎么做呢?

為此,您應該使用TextureAtlas。 地圖集是由LibGDX TexturePacker從單獨的圖像自動生成的文件。 它存儲了從工作表中的圖像范圍到NinePatch信息的所有內容。 您需要做的就是將單獨的圖像放在一個文件夾中,然后在該文件夾上運行TexturePacker。 這將為您創建一個工作表和一個.atlas / .pack文件,可以輕松加載它們。

如果您在使用命令行時遇到困難,則可以使用TexturePackerGui ,但我還是建議您使用命令行甚至在應用程序中使用它。

我通常要做的是在開發時動態創建這些工作表。 我可以輕松覆蓋單獨的圖像,並且在我再次運行應用程序后,它們會立即生效。 我首先在項目的根目錄下創建一個新的文件夾images 然后我需要為每個包創建另一個文件夾。 對於此示例,我在images創建了文件夾tileset DesktopLauncher我將設置此文件夾以從圖像生成圖集。

    TexturePacker.Settings settings = new TexturePacker.Settings();
    settings.maxWidth = 1024;
    settings.maxHeight = 1024;

設置文件指定有關地圖集的所有內容。 一張紙的最大尺寸(如果應該從圖像,填充,旋轉等中去除透明度),它們都非常簡單,您可以在文檔中查找全部內容。 使用這些設置,您可以創建地圖集。

    TexturePacker.process(settings, 
            "../../images/tileset", //where to find the images to be packed.
            "../../android/assets/tileset/", //where to store the atlas and sheet
            "tileset"); //what filename to use

現在,您可以打開.atlas文件,您會看到它使用文件名作為別名。 該別名用於查找它們,但讓我們先加載地圖集。

TextureAtlas atlas = new TextureAtlas("tileset/tileset.atlas");

通過僅將字符串傳遞給構造函數,它默認情況下會在您的本地路徑中查找,而該路徑又默認為android/assets/ 現在,我們可以要求地圖集移交工作表中的資產。

atlas.findRegion(“ alias”); //將圖片移交給名為“ alias”的工作表

查找這樣的紋理有些昂貴。 您不想每次更新都查找許多這樣的紋理,因此仍然需要將它們存儲在某個位置。

如果您將圖像序列命名為image_01.pngimage_02.pngimage_03.png則它們將全部以相同的名稱存儲,並在圖集內按index對其進行排序。 因此,如果您需要特定紋理的單獨數組,則可以使用_xx命名它們,並一次性完成所有操作:

atlas.findRegions("alias");

這對於Animation特別方便。 只需將圖像序列復制到文件夾並指定要打包即可。 正確命名序列,並為動畫指定區域。 一切都會立即進行。

使用AssetManager加載TextureAtlas與普通Texture幾乎相同,除了您可以指定它來自TextureAtlas.class 您始終會加載.atlas ,后者會處理您的圖像。

我總是使用AssetDescriptor加載我的資產。 如果我在您的位置,我將擺脫靜態的Assets.textures[] 因為那樣會使您早晚陷入麻煩

//None static AssetManager with getter
private AssetManager manager = new AssetManager();
public AssetManager getManager() { return manager; }

//Specify a descriptor for the atlas, this is static so I can acces it anywhere. 
//It's just a descriptor of the asset so this is safe.
public static final AssetDescriptor<TextureAtlas> TileSet = new AssetDescriptor<TextureAtlas>("tileset/tileset.atlas", TextureAtlas.class);

//then just load everything
public void load()
{
    manager.load(tileSet);
    //... load other stuff
}

現在,只需將AssetManager對象傳遞到您需要訪問資產的任何地方,就可以像這樣加載任何資產:

TextureAtlas tileset = assetManager.get(Assets.TileSet);

我認為您的for循環應如下所示

for(int x = 0; x < 64; x ++){
    textures[x] = new Sprite(
        spritesheet, 
        (x%8)*64, //where x=3, (3%8)*64 = 3*64 = 192px sourceX
        (x/8)*64, //where x=3, (int)(3/8)*64 = 0*64 = 0px sourceY
        64, //source width
        64 //source height
    );


Another test case where x=20;
(20%8)*64 = 4*64 = 256px SourceX
(20/8)*64 = 2*64 = 128px SourceY

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM