【问题标题】:LibGDX render only, if camera sees itLibGDX 仅渲染,如果相机看到它
【发布时间】:2014-10-22 12:05:04
【问题描述】:

所以,我创建了我的第一个游戏。在计算机上它可以工作(60FPS),但在我的手机上,我有 50FPS,有时它会跳到 30 又回来,你会看到它像一个滞后。我已将所有对象存储在 ArrayList 中。所以,我认为,这可能是因为我正在渲染所有东西,所以我想知道,只有当它们在相机视图中时如何渲染它们。我尝试使用视口,但它们仍在渲染,但您看不到它们。所以我的问题是,如何计算相机视图中是否有东西。

如果它们在相机视图中,我会尝试渲染它们。我遇到了麻烦。

public void render () {
            if (space == 1){ //if you are alive.. space 1 means you are alive, 0 means you are in menu
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
            sb.setProjectionMatrix(cam.combined);
            camera.position.x = player1.x + player1.getSize()/2;
            camera.position.y = player1.y + player1.getSize()/2;
            camera.update();
            sb.setProjectionMatrix(camera.combined);
            sb.begin();
            sb.draw(bg, 0, 0, 1920 , 1080 );
            //HP //it means food
            if (HP > 12.4f)
            {
                sb.draw(Jedlo2, player1.x + (450 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            else if (HP < 0.5f)
            {
                sb.draw(Jedlo, player1.x + (450 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            else if (HP < 12.5f)
            {
                sb.draw(Jedlo3, player1.x + (450 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            //kornut 2
            if (HP > 37.4f)
            {
                sb.draw(Jedlo2, player1.x + (500 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            else if (HP > 24 && HP < 37.5f)
            {
                sb.draw(Jedlo3, player1.x + (500 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            else if (HP < 25)
            {
                sb.draw(Jedlo, player1.x + (500 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            //kornut 3
            if (HP > 62.4f)
            {
                sb.draw(Jedlo2, player1.x + (550 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            else if (HP > 49.9f && HP < 62.5f)
            {
                sb.draw(Jedlo3, player1.x + (550 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            else if (HP < 50)
            {
                sb.draw(Jedlo, player1.x + (550 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            //kornut 4
            if (HP > 87.4f)
            {
                sb.draw(Jedlo2, player1.x + (600 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            else if (HP > 74.9f && HP < 87.5f)
            {
                sb.draw(Jedlo3, player1.x + (600 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            else if (HP < 75)
            {
                sb.draw(Jedlo, player1.x + (600 + player1.seeSize()/2), player1.y + (320 + player1.seeSize()/2), 50, 50);
            }
            //HP
            font.draw(sb, "Score: " + player1.getScore(), player1.x - (620 - player1.seeSize()/2),  player1.y + (370 + player1.seeSize()/2));
    h.draw(sb, "FPS: " + Gdx.graphics.getFramesPerSecond(), player1.x - (620 - player1.seeSize()/2),  player1.y + (300 + player1.seeSize()/2));
            sb.end();
        //entities  
        for (Entity e : entities)
            {  
                e.render(sb); 
            }
        //entities
        //Touchpad
            player1.setrlx(player1.pos(true) + touchpad.getKnobPercentX()*blspeed);
            player1.setrly(player1.pos(false) + touchpad.getKnobPercentY()*blspeed);
            if (touchpad.getKnobPercentX()*blspeed > 0.0f && touchpad.getKnobPercentY()*blspeed > -1.5f && touchpad.getKnobPercentY()*blspeed < 1f)
            {
                player1.an.setRow(0);
            }
            else if (touchpad.getKnobPercentX()*blspeed < 0.0f && touchpad.getKnobPercentY()*blspeed < 1.0f && touchpad.getKnobPercentY()*blspeed > -1.5f)
            {
                player1.an.setRow(1);
            }
            else if (touchpad.getKnobPercentY()*blspeed > 0.0f)
            {
                player1.an.setRow(3);
            }
            else if (touchpad.getKnobPercentY()*blspeed < 0.0f)
            {
                player1.an.setRow(2);
            }
            //Touchpad
            Gdx.input.setInputProcessor(stage);
            stage.act(Gdx.graphics.getDeltaTime()); 
            stage.draw();
            HP -= 0.05f;
            time += Gdx.graphics.getDeltaTime();
            time2 += Gdx.graphics.getDeltaTime();
            if (time >= period)
            {
                time -= period;
                update();
            }

            if (time2 >= p2)
            {
                time2 -= p2;
                updatemobs();
            }
            }
            else if (space == 0) //if you are in menu, my problem is if you are not in menu so you dont need to check this //right now, in this code, the menu is not updated, but there is only small things, you dont need to check that.
            {
                Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
                entities.clear();
                JukeBox.stop("water");
                if (player1.getScore() > lastscore)
                {
                    Bin.create(player1.getScore());
                    lastscore = player1.getScore();
                }
                sb.setProjectionMatrix(camera.combined);
                sb.setProjectionMatrix(cam.combined);
                sb.begin();
                sb.draw(but, 1280/2.3f, 720/2.4f, 200, 100);
                if (player1.getScore() > 0)
                {
                    offx2 = h.getBounds("Your Score: " + player1.getScore()).width/2f;
                    h.draw(sb, "Your Score: " + player1.getScore(), 1280/2-offx2, 600);
                }
                offx = fo.getBounds("Your highscore: " + player1.getScore()).width/2f;
                fo.draw(sb, "Your highscore: " + lastscore, 1280/2-offx, 700);
                sb.end();
                if (Gdx.input.isButtonPressed(0))
                {
                     x = Gdx.input.getX();
                    y = Gdx.input.getY();
                    if ( x > 1279/2.3f && x < 1725/2.3f && y > 775/2.4f && y < 1000/2.4f )
                    {
                        JukeBox.play("button");
                    space = 1;
                    player1.setScore();
                    player1.setPos();
                    player1.SetrlSize();
                   // cr();
                    cr();
                    }
                }
            }
        }

实际上,我尝试删除那些更新调用,但它没有帮助,所以问题不在那里。

【问题讨论】:

  • 需要更多细节。这是2d还是3d游戏?如果是 2d,您是否使用 scene2d?它是正交相机还是透视相机?您确定您的性能问题不是由于垃圾收集而不是绘制的对象数量吗?
  • 如果您在 3D 中遇到问题,您可以使用 this 非常简单的方法。
  • 它是 2D,我没有使用 Scene2D。 :) 正交相机。我不知道,但我认为这是问题所在。但我认为这很容易.. :D 我也想知道如何在 3D 中做到这一点。 :D 顺便说一句。我会看看那个链接。
  • 也许这会有所帮助:stackoverflow.com/a/18701998/1663265
  • 我做到了,我的 FPS 没有改变,所以我不知道 :D

标签: java optimization camera libgdx render


【解决方案1】:

您知道相机的位置和大小,并且您知道各种对象的位置。所以你可以计算出什么画什么不画。简单地检查事物的位置比绘制它们更有效。

最好提前知道要绘制什么,这样您就不必遍历所有对象坐标。对于固定位置的瓦片地图,很容易确定要绘制哪些瓦片,哪些不画。对于更多动态对象,您可以尝试将对象放在列表中并根据位置对其进行排序。如果您有很多对象,则必须查看哈希图或四叉树才能有效排序。

如果您在屏幕外有很多事情发生,您可以选择将您的游戏世界分割成多个片段,并且只更新/绘制靠近实际屏幕的片段。这意味着您必须从世界的这些片段/部分中删除和添加动态对象。考虑一下你是否真的需要让东西向前移动 4 个屏幕宽度。

PS: 您确定由于绘制调用的数量而存在 FPS 问题吗?你在使用 spritesheets、Excessive loops 等吗?

编辑 您说您在每帧进行大量绘图调用,但我找不到您正在执行此操作的循环。我只看到一些 hud 元素和 Jedlo jedlo2 jedlo3 被绘制,这肯定不是瓶颈。

一步一步地练习。尝试熟悉屏幕和舞台,因为您可以使用这些来绘制您的 hud/UI。而不是jedlo1 to 3,我认为它是框架,您可以创建一个方法甚至一个为您执行此操作的类。这样你就可以保持你的方法和主类整洁有序。

【讨论】:

  • 我不知道你所说的 Spritesheets 是什么意思,但是,我的动画由一张图片组成,我正在拆分它,所以它看起来像动画。它是通过使用 TextureRegion.split(...); 完成的。过多的循环?我想我不是.. :D 也许我可以分享游戏的核心来查看我的渲染函数中的内容,但它只是绘制图像、绘制位图、绘制实体.. 有 2 个 spritebatches,我是调用图像、文本.. 以及我用来绘制实体的第二个
  • 谷歌精灵表。加载具有 20 个精灵的单个图像比加载 20 个图像更有效。尝试将绘图精灵排除在屏幕外。
  • 无法理解:D 我只加载 1 个图像,其中我有 16 个较小的图像(精灵、动画..:D)我没有加载 16 个图像(每一步 1 个图像),您可能的意思是,我应该只加载 1 张图片。是的,我是。
  • 所以你使用的是一张纸,无论如何我只是问你是否确定性能问题来自图纸。就像我说的,尽量减少draw call。
  • 我认为,它是.. 如果我不渲染对象,我有静态 57FPS(这看起来像是移动设备上的最大值)。所以它可能是在渲染对象,我有很多对象(可以有 200 个对象),所以只渲染可见部分应该会有所帮助:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 2011-11-24
  • 2016-06-22
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 2014-05-02
相关资源
最近更新 更多