簡體   English   中英

Libgdx 舞台添加演員低FPS

[英]Libgdx stage add actor low FPS

我正在使用應用程序適配器。 當我在 create() 方法中有以下代碼時,我的 fps 始終約為 14。

for (i in 0..1000) {
                stage.addActor(Food(
                        Food.TEXTURE_PURPLE!!,
                        100f,
                        (random.nextInt(MAP_SIZE)).toFloat(),
                        (random.nextInt(MAP_SIZE)).toFloat()))

                stage.addActor(Food(
                        Food.TEXTURE_GREEN!!,
                        100f,
                        (random.nextInt(MAP_SIZE)).toFloat(),
                        (random.nextInt(MAP_SIZE)).toFloat()))
}

但是當我在 create() 方法中有這個時,我的 fps 總是 60。為什么?

    for (i in 0..1000) {
                stage.addActor(Food(
                        Food.TEXTURE_PURPLE!!,
                        100f,
                        (random.nextInt(MAP_SIZE)).toFloat(),
                        (random.nextInt(MAP_SIZE)).toFloat()))
            }

   for (i in 0..1000) {
              stage.addActor(Food(
                        Food.TEXTURE_GREEN!!,
                        100f,
                        (random.nextInt(MAP_SIZE)).toFloat(),
                        (random.nextInt(MAP_SIZE)).toFloat()))
            }

問題是紋理交換。 SpriteBatch 的工作方式是您使用其draw函數之一提交要繪制到其隊列中的項目。 一旦您添加了無法與隊列中的其他所有內容一起繪制的內容,它就會通過進行 OpenGL 繪制調用來刷新隊列,然后啟動一個新隊列。

兩個不同的紋理不能在同一個 OpenGL 繪制調用中繪制,所以當你的食物項目沒有按紋理排序時,它們中的每一個都會觸發另一個刷新。 沖洗是一項昂貴的操作,您希望避免使用超過幾十個。

解決方案是使用 TextureAtlas,它將多個圖像組合成一個紋理,通過 TextureRegion 訪問。 您可以將 TextureRegions 提交給SpriteBatch.draw(...) 只要 TextureRegions 共享相同的 Texture,就可以在單個批處理隊列中繪制許多具有不同 TextureRegions 的項目。

附帶說明...我強烈建議不要使用 static 對紋理的引用。 最常被問到的 libgdx 問題是“為什么我的紋理是黑色的”,這始終是因為他們使用 static 紋理引用,卻不了解如何正確處理紋理和重新加載。 Static references outlive your game when on Android, which can cause big memory leaks, and bizarre bugs if you do any lazy loading of anything, which is very easy to accidentally do when using static references.

更簡潔的設計是擁有一個 Assets class(如果您的游戲中每個階段有很多獨特的東西,可能每個階段都有一個),它有一個 AssetManager 來加載您的所有東西。 可以將單個資產實例傳遞給您的所有游戲 object 構造函數。 例如:

class Assets: Disposable {
    private val assetManager = AssetManager()

    lateinit val foodGreenTexture: Texture
    lateinit val foodRedTexture: Texture
    lateinit val foodBlueTexture: Texture
    //...

    init {
        assetManager.load("green.png", Texture::class.java)
        assetManager.load("red.png", Texture::class.java)
        //...
        assetManager.finishLoading()
        foodGreenTexture = assetManager.get("green.png")
        //...
    }

    override fun dispose (){
        assetManager.dispose()
    }
}

不要忘記在初始化它(您的游戲或屏幕)的同一個 object 中對您的資產 class 調用 dispose。

我還建議研究使用 CoveTools 庫,該庫有一個名為 AssignmentAssetManager 的助手,它可以刪除上面的一堆樣板。 同樣的 class 看起來像這樣。 請注意,無論您加載多少不同的資產, init塊都將非常短:

class Assets: Disposable {
    private val assetManager = AssignmentAssetManager()

    @Asset("green.png") val foodGreenTexture: Texture = null
    @Asset("red.png") val foodRedTexture: Texture = null
    @Asset("blue.png") val foodBlueTexture: Texture = null
    //...

    init {
        assetManager.loadAssetFields(this)
        assetManager.finishLoading()
    }

    override fun dispose (){
        assetManager.dispose()
    }
}

第二個說明...我強烈建議不要使用 Sprite class,尤其是在使用 Actors 時。 請改用 TextureRegion class。 Sprite 是一個高度專業化的 class,它擴展了 TextureRegion,但包含了額外的數據,如 position、大小、旋轉等。如果您使用 Actor,這些額外的數據是多余的,所以它很容易出錯並且浪費 CPU 和 ZCD69B4957F016CD8191D7BFDE 復制數據來回。

暫無
暫無

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

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