2016-03-20 66 views
1

我有960x960 spritesheet作爲png存儲在我的Libgdx android資產中。在我爲遊戲中的初始化精靈指定的一個類中,我試圖讓它有一個從spritesheet中切出的120x120精靈(所以應該有64個項目在數組中)。我怎麼能做到這一點?這是我在一個類似的情況曾嘗試:從spritesheet陣列中存儲精靈Libgdx

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個不同的精靈,並使其成爲可以通過更改渲染精靈時輸入的索引來輕鬆更改精靈,以便稍後可以做其他事情就像動畫一樣。我怎麼能這樣做呢?

回答

0

我覺得你的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 
3

您應該使用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[]since that will get you into trouble sooner or later

//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); 
+0

紋理圖集是規模是個好主意,但它仍然是重要的知道它是如何工作的。豎起大拇指。 –