簡體   English   中英

Libgdx:從多個紋理地圖集中渲染排序的精靈

[英]Libgdx: Rendering sorted sprites from multiple texture atlases

我需要在屏幕上以libgdx (平均20-30)的對象進行渲染,所有對象均按 Y值排序,因此,具有最低Y值的精靈將首先渲染。 (請考慮以下觀點http : //i.stack.imgur.com/m1VQA.gif

游戲利用紋理圖集,每個紋理圖集的大小為2048 * 2048。

我目前有三個地圖集。 一種是可玩角色,一種是NPC角色,另一種是動物/怪物。 最終,我們計划添加許多不同的對象,npc集等,因此將所有子畫面混合到一個大地圖集上不是一個選擇(在設計和硬件上都會受到很大限制)。

當前的渲染方法首先按Y值對屏幕上的每個對象進行排序,然后繪制它們。 除了事實如此,這可以完美地工作,因為這樣可以發生許多紋理切換。

例如,渲染:-3個動物-2個npc-玩家-1個npc-1個動物-1個npc-2個動物,

將需要7個紋理切換。 這完全取決於對象在屏幕上的位置。

按圖集對子畫面進行排序不是一種選擇(首先繪制動物,然后是npc,然后是玩家),因為這將導致無法進行Y排序。

(我想到的第一件事是將紋理圖集增加到8192 * 8192,但是許多較舊的台式機和移動設備將無法運行游戲。第二件事我想到的是某種深度緩沖,但是我不確定如何做到這一點。)

在保持穩定的幀速率的同時,必須使用哪種方法來獲得所需的結果(來自多個紋理的精靈)? 有沒有可行的openGL技巧來做到這一點? 我應該擔心每幀有6-7個紋理開關嗎?

看到此鏈接是libgdx測試,測試深度為z,但您可以使用y軸

SortedSpriteTest

您需要使用比較器並對數組進行排序,從而明顯降低游戲性能。

實際上,如果您給Actor指定的Sprite作為屬性,那應該不成問題。 在渲染內容時,您永遠不會加載任何東西。 如果創建Actor,則需要從Atlas中加載精靈,紋理等,並將其提供給Actor。 像這樣:

Texture monster = getTextureByType(type);
Monster mon = new Monster(level, new Sprite(monster), screen, ai,npc);

在您的Monster(演員!)內部,將其保存為Sprite。 我認為是常規構造函數

public Monster(int level, Sprite sprite, GameScreen screen, AIInterface ai,
                boolean npc) {
            this.life = 300;
            this.curLife = 200;
            this.ai = ai;
            this.level = level;
            this.sprite = sprite;
            this.sprite.setRegion(0, 0, 32, 48);
    }

抽獎非常簡單:

    @Override
    public void draw(SpriteBatch batch, float parentAlpha) {
        if (alife) {
            sprite.setPosition(this.getX() + ofset, this.getY());
            sprite.draw(batch);
        }
     }

如果這樣做,您將不會遇到任何幀率問題。 演員人數不算少。 只需在繪制/渲染周期內不加載紋理,它就可以正常工作。 而且,使用多個Atlas也不應該有任何問題。 地圖集不用於渲染。 它用於將多個紋理放入一個紋理中以使其更容易處理。 永遠不會從地圖集中在draw或render方法內部加載任何內容。 如果這樣做,您將獲得非常糟糕的性能。

對於排序,請使用insertsort。 那應該比您的szenario中的集合排序要快。 也許每10幀稱一次。 您甚至都不會注意到在短時間內它們的排序不正確。

private void sortList(Array<Actor> array) {
    // double starttime = System.nanoTime();
    for (int i = 1; i < array.size; i++) {
        Actor temp = array.get(i);
        int j = i - 1;

        while (j >= 0 && array.get(j).getY() < temp.getY()) {
            array.set(j + 1, array.get(j));
            j--;
        }
        array.set(j + 1, temp);
    }
    // System.out.println("Time taken: " + (System.nanoTime() - starttime));
}

暫無
暫無

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

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