I have a game, and when I get to the GameScreen, it gets extremely slow fairly quickly. On the GameScreen, if I just do nothing and watch, and the FPS drops to under 10 and stays there in around 30 seconds. I've been looking around my code, and I think I've narrowed it down to a section, but it makes no sense to me why it's not working, or how to fix it.
start_button = new TextButton("Start", Resources.getSkin());
start_button.setWidth(75);
start_button.setHeight(25);
start_button.setX(FRUSTUM_WIDTH / 10);
start_button.setY(FRUSTUM_HEIGHT / 4);
...
stage.addActor(start_button);
stage.addActor(pause_button);
stage.addActor(reset_button);
stage.addActor(platform_button);
In my GameScreen's render method, I call a method, and in that method I created four textbuttons. The section of code that seems to be the problem is the last four lines when I add the buttons to the stage. If I comment out those lines, the game works fine and the FPS is constantly 60. If I only comment out three of the lines, and add one button to the stage, the FPS will still drop to under 10, but it takes longer and eventually spikes back up to 60.
Why are those lines slowing down the game?
If you are doing all this in your Gamescreen's render method then this is your mistake.
because every time you are creating new button and adding it to the stage which is definately not good.
Every time you add something to stage its list increases and if depending on how frequent your render method is called the list increases and so is the time to process that list.
Dont forget about the garbage collector because lots of objects are being made and when garbage collector will be called your fps will definately decrease.
Related
i'm making my first 2d sidescroller game using a surfaceview and a canvas to draw things on (a lot of primitives put in different path objects).
my game loop uses fixed timesteps with linear interpolation. i don't create any objects during the game. i've been improving my code for 3 weeks now, but my animation is still not all the time smooth. it's ok, but every few seconds there are a lot of little hicks for about 1 or 2 seconds.
what i recognized is when i move my player (this means touching the screen), the little hicks disappear for as long as i touch the screen and move my player.
this means as long as ontouchevent of the surfaceview is called, the animation is smooth.
i dont understand this and i want a smooth animation. can somebody help me?
This sounds like a known issue on certain devices. See e.g.:
Android SurfaceView slows if no touch events occur
Animation glitches while rendering on SurfaceView
Android thread performance/priority on Galaxy Note 2 when screen is touched/released
The problem is that the system is aggressively reducing clock speeds to save power when it doesn't detect interaction with the user. (Qualcomm in particular seems fond of this.) The workaround is to drop frames when necessary. See this article on game loops, and a Choreographer-based trick demonstrated in Grafika's "record GL app" activity (in doFrame()).
I'm looking a minimising battery usage in a game I'm developing, and battery usage is something that's very hard to measure accurately, so I was hoping someone in the know might be able to answer this.
Is it likely to be worth my implementing a system where I don't render when there are no updates to what's displayed on the screen? Something like
updated = false;
for each component
updated |= component.update();
if (updated)
render();
This is the kind of thing that's much easier to add at the start, if it'll be worthwhile, than to try to add in at the end if it's required.
If I was rendering through the CPU then I'd definitely say it was worth doing, but through the GPU I'm not so sure. Will in save an insignificant amount of battery compared to things like the screen being on?
edit:
A bit of clarification. I'm creating a word game, so a lot of the time the user is going to be staring at a motionless screen looking for words. Depending on the mode the game is being played in, something could happen on the screen that isn't triggered by user input. For example, a new object appearing on the screen every 5 seconds. Rendering 300 frames where nothing happens every 5 seconds seems a real waste and is something I'd like to avoid.
I don't know if your method does minimize the battery usage, but i think it would be better to disable continuous Rendering by calling Gdx.graphics.setContinuousRendering(false); in the Applicationlisteners create or something like this.
By doing this you stop the gameloop from calling your render() method. It is then only called in the following situations:
On Input (Keypress, touchdown...)
On a call of Gdx.graphics.requestRendering();
On a call to Gdx.app.postRunnable()
Read this for more informations.
EDIT:
I have now read your edit. Well "Puzzle game" sounds a bit generally for me. If you are sure, that the user will be staring at a motionless screen for a long time, to find a possible solution, then maybe the non-continuous rendering is the right way. But if it is (for example) a platformer with some puzzle elements, the user will probably move the whole time and solve the puzzle "on the fly". In this case i would redner normally.
Also you have to think about the other logic, outside of the current view:
Again the example with the platformer: If you have to solve a puzzle to open a door or whatever, behind this door maybe some monsters are waiting for you to come. So if they patrol arround, you have to update their possitions, even if they are outside of the view (behind the door, outside of the building...). In this case again i would not use non-continuous rendering.
The timer you mentioned, will call render(), if it is fired. See this for reference.
To run something, without calling render() you need to run it on another Thread, so for this use java.util.Timer instead of libgdx Timer.
EDIT: As you have now replaced "puzzle game" with "word game" i think i know what you mean.
Normally you only need to render, when an input event is fired. But as much as i understood you want some objects to appear on screen (to make it more interesting than a motionless picture?). For this you need to use a Timer, i am not sure if libgdx Timer could do this, if not you can use java.util.Timer and when a Timerevent gets fired you just call requestRendering() and in your render update gamelogic and the redraw.
Can you please help me answer the following questions?
How do people usually implement a timed event in games?
Example: You reach some point in time and something happens like a new wave of enemies appears or something similar.
What is the best way to make sprite animations?
Example: Explosions in an android game.
1) Every time round your game loop you will want to record the elapsed time (or delta time.) This means you could keep track of the time past since the game start and the time it took to execute one iteration of your loop (the latter is good for time based movement.)
2) Depends really, I'm assuming this is 2D so I personally use sprite maps (google it) and then after x seconds I will change the image that is being rendered to the next on in the animation sequence. Animation sequences normally consist of "frames" and after x seconds have passed then move to the next frame
1 - Each frame/cycle of your game, record the time, then get the difference between the previous cycle's and the current cycle's time. This is how much time has elapsed since the last frame/cycle. Objects can then have timers that subtract the elapsed time each cycle, and do things when their timers are <= 0.
2 - My preference for game development is flixel, which does a lot of the dirty work for you. If you want to use pixel images instead of vector graphics, you should take a look at flixel. It has a framework that makes working with images and spritesheet animations a breeze. At the very least you can figure out how flixel handles them and write your own methods based on what you learned. If you want vector graphics, however, you'll need some other solution.
It would be really cool to benchmark how many times per second an animation actually gets drawn to the screen in an android app. Is there a way to do it?
ie. I can set an animation to run over a 250ms period, but I want to benchmark how smooth it is objectively.
If you have a game loop running, you can calculate the framerate as follows:
FrameRate= 1000/LoopTime
Where LoopTime is the time it takes to execute an Update call and Draw call.
I'm writing a simple 2D game engine and rendering various objects to a locked SurfaceVew by calling Canvas.drawBitmap (all the same source bitmap but generally not with 1:1 source to destination scaling).
Everything appears to work as expected until there are a lot of calls per frame to drawBitmap. When this happens I occasionally see a stall (100mS or so) accompanied by an effect that looks as if several frames of rendering have occurred together, i.e. some objects will be drawn twice at two screen locations or a pair of objects moving at the same speed will appear to momentarily get closer together or further apart.
The application is structured as follows (simplified for the sake of example);
initialiseGameObjects();
while(quit==false)
{
processGameLogic(); // update object positions
Canvas c = surface_holder.lockCanvas();
if (c != null) {
drawGameObjects(c); // draw all objects
surface_holder.unlockCanvasAndPost(c);
}
}
As I understand it, the Canvas is a holder for draw requests which get executed when the Post is issued. Presumably there is a limit to the number of requests it can hold and I'm wondering if I'm exceeding this limit (I'm drawing up to a hundred small bitmaps depending on what's on screen at any one time) and inadvertently provoking some kind of flush and upsetting the double buffering in some way, although I've not managed to find any documentation to confirm or disprove this.
Does anyone have any idea what might be going on?
Regards,
Steve
You need to sychronize calls to canvas drawing. Check this example of a game driving thread: OnDraw() is not fired, nothing is drawn in surfaceView - Android
EDIT:
However I think it may be related to this problem:
Android SurfaceView/Canvas flickering after trying to clear it