繁体   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