0

So, I have created my first game. on computer it works(60FPS) but on my mobile, I have 50FPS, and sometimes it jumps to 30 and back again, you see it like a lag. I have stored all objects in an ArrayList. So, I think, it can be caused because i am rendering everything, so I want to know, how to render things only if they are in camera view. I tried to use viewport, but they are still rendering, but you don't see them. So my question is, how to calculate if something is in camera view.

I was trying to render them if they are in camera view. and i am getting troubles with it.

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();
                    }
                }
            }
        }

Actually, I tried to remove those update calls, but it does not help, so the problem is not in there.

Tieson T.
  • 20,774
  • 6
  • 77
  • 92
Kalir4488
  • 43
  • 1
  • 12
  • Need more detail. Is this a 2d or 3d game? If 2d, are you using scene2d or not? Is it an orthographic camera or perspective camera? Are you sure your performance issue is not due to garbage collection rather than number of objects drawn? – Tenfour04 Oct 22 '14 at 12:09
  • In case you are having trouble with that in 3D you might use [this](http://pixelscientists.com/blog/posts/quick-solution-for-3d-culling-in-libgdx) very simple approach. – noone Oct 22 '14 at 12:12
  • It is 2D, i am not using Scene2D. :) Ortographic camera. I dont know, but i think this is the problem. But i was thinking it is something easy.. :D I would like to know how to do that in 3D, too. :D Btw. i will take a look at that link. – Kalir4488 Oct 22 '14 at 13:50
  • Maybe this can help : http://stackoverflow.com/a/18701998/1663265 – thetheodor Oct 22 '14 at 20:47
  • I did it and my FPS did not change so i dont know :D – Kalir4488 Oct 23 '14 at 13:02
  • They didnot change because that way does not work ;) if i use that and i have 100 objects in game, and i can see only 5(rendering only 5) fps are the same, so it looks like this way is doing the same like viewport(it is written there :D ah, it is just clipping my screen so it is the same like viewport, but more complicated). because if i have only 5 objects in game, and i am rendering them, i have full fps :) – Kalir4488 Oct 23 '14 at 20:10
  • Is it possible to clean up your code? Perhaps you could make a method for each separate part. Like one for scoring, moving and maybe several for rendering things. Currently it is a mess and hard to work with, even for yourself let alone others. – Madmenyo Oct 24 '14 at 06:03
  • Ahh.. :) :D i passed the Entities.render to my sprite batch, and removed sb.begin and sb.end from Entity.render, because it was calling sb.begin and sb.end 200 times in one frame.. :D :D MY bad :D but i still can not figure out how to draw only if they are in camera distance. in Entity.render im trying somethin like: if (x <= Core.player1.x && y <= Core.player1.y ) { sb.draw(an.getFrame(), x, y, size, size); } this works only for mobs which are under me and on the left. but i cant figure how to do that if he is onright – Kalir4488 Oct 24 '14 at 13:12
  • AHH! It is done :D So now i am rendering things which are in camera view. FPS are good, that is what i wanted. Thank to all :) :D – Kalir4488 Oct 24 '14 at 13:18
  • Try to keep things clean and organized. It is much easier to spot a mistake or find a bug this way. – Madmenyo Oct 24 '14 at 18:53

1 Answers1

1

You know the position and size of the camera and you know the position of the various objects. So you can calculate what to draw and what not. Simply doing a check on the position of things is a lot more efficient then drawing them.

Even better would be to know in advance what to draw so you do not have to traverse all your object coordinates. For tilemaps, which are fixed in position it is easy to determine what tiles to draw and what not. For more dynamic objects you could try to put your objects in a list and sort it depending on position. If you have lots of objects you have to look into a hashmap or quad tree to sort efficiently.

If you have a lot of things going on outside the screen you can opt to devide your game world into pieces and only update/draw the pieces near to the actual screen. This means you have to remove and add dynamic objects from and too these pieces/sections of your world. Consider if you really need to have things moving around 4 screen widths ahead.

PS: Are you sure you are having FPS problems due to the amount of draw calls? Are you using spritesheets, Excessive loops, etc?

EDIT You stated you where making lots of draw calls each frame but I cannot find the loop where you are doing this. I only see some hud elements and Jedlo jedlo2 jedlo3 being drawn, this certainly cannot be a bottleneck.

Practice a bit more step by step. Try to familiarize yourself with screens and stage since you can draw your hud/UI with these. Instead of jedlo1 to 3, which I presume are frames you could make a method or even a class that does this for you. This way you keep your methods and main classes clean and organized.

Madmenyo
  • 8,389
  • 7
  • 52
  • 99
  • I dont know what you mean by this Spritesheets, but, my animations consist from a picture, which i am spliting so it looks like animation. It is done by using the TextureRegion.split(...); excessive loops? I think i am not.. :D Maybe i can share the Core of the game to look what is in my render func, but it is only drawing images, drawing bitmaps, drawing the entities.. there is 2 spritebatches, one i am calling for images, texts.. and the second i am using to draw entities – Kalir4488 Oct 22 '14 at 16:19
  • Google spritesheets. Loading a single image with 20 sprites on it is more efficient then loading 20 images. Try to exclude drawing sprites off screen. – Madmenyo Oct 22 '14 at 17:35
  • Cant understand :D i am loading only 1 image, in which i have the 16smaller images(sprites, the animation..:D) i am not loading 16 image(1 image for every step), you probably mean that, that i should load only 1 image. and yes, i am. – Kalir4488 Oct 22 '14 at 18:07
  • So you are using a sheet, anyway I was just asking if you where sure the performance issues where comming from the drawing. Like i said, try to make as little draw calls as possible. – Madmenyo Oct 22 '14 at 18:51
  • I think, it is.. if i am not rendering objects, i have static 57FPS(this looks like a max on mobile). so it probably is in rendering objects, and i have a lot of objects(there can be for 200 objects), so rendering only visible part should help :D – Kalir4488 Oct 23 '14 at 13:03
  • And? Did you try my techniques? – Madmenyo Oct 23 '14 at 13:05
  • Can I send you the code from my Render, you will see, that there is nothing bad. :D – Kalir4488 Oct 23 '14 at 13:14
  • Post it here in your question. – Madmenyo Oct 23 '14 at 13:15