Reputation: 736
I have been working on an Android game for the past 6 months or so, and have posted on here several times about various lag issues that I cannot get rid of.
I ended up grabbing the LunarLander example and stripping it down to its very core components to see if I could make anything at all that doesn't lag. All it really does is change the amount the canvas is translated each frame, and then draw a background onto the canvas. EVEN THIS, about as simple as you can get for a surfaceView application - stutters...
My game is a scrolling game where you continuously move up the screen (think of a flying game), but the way I am currently doing the background results in constant stuttering every second or so for about 50-100ms. This isn't game breaking, but it is very distracting and makes the game seem as if it was programmed by a complete moron (though I am starting to suspect this might be the case).
No, it is not the garbage collector, there are no new objects being created at all during the game's run loop, and the GC barely ever runs while my game is running.
I am practically tearing my hair out with frustration. I have spent over 40 hours just trying to get rid of the lag on this simple application example over the past week alone and it is driving me crazy. How can an application as simple as the one I have linked possibly have lag issues? You wouldn't think a scrolling background could get much simpler than that...
NOTE: This demonstration constantly gets about 60fps on my phone (A Motorola Milestone). Uncomment the FPS code in the example to see the FPS.
TL;DR: Extraordinarily simple program that is just a scrolling background shows stuttering. Please have a look...
Link to download simple stuttering example based off the LunarLander example: http://dl.dropbox.com/u/4972001/LunarLander.rar
Upvotes: 7
Views: 2340
Reputation: 166
I've been having this same lag issue in my game (and I did something similar you did to LunarLander loop and reached a similar conclusion). If you open logcat, you see can that the lags happens together with GC_FOR_MALLOC (50 ... 100 ms, our lags time). I suspected the source of the problem was the garbage collector. Then I found this post:
http://fanitis.com/2011/02/09/android-game-performance-garbage-collection/
I'll try to reduce the use of garbage collector and see if I achieve a lagless condition hehehe =]
Upvotes: 1
Reputation: 3958
Have you considered jhouse's suggestion of a minimum frame time?
I am using that idea on my current project. I expect phone hardware to have made considerable improvements in the next year or two so this will stop your game becoming unplayable in future.
My code is like this:
long frameTime; // calculate time to process this frame
while (mSurfaceAvailable) {
// ensure minimum frame time can be calculated
frameTime = SystemClock.uptimeMillis();
// code to move everything and display a single frame goes here
// ensure minimum frame time
frameTime = SystemClock.uptimeMillis() - frameTime;
if (frameTime < 0) frameTime = MIN_FRAME_TIME; // cope with wrap-around of uptimeMillis
if (frameTime < MIN_FRAME_TIME) {
/*DEBUG*/Log.v(this.getClass().getName(), "run: Sleeping for "+(MIN_FRAME_TIME - frameTime)+"ms");
try {
sleep(MIN_FRAME_TIME - frameTime);
} catch (InterruptedException e) {
/*DEBUG*/Log.i(this.getClass().getName(), "run: Thread sleep was interrupted (not a problem)");
}
} else {
if (frameTime != MIN_FRAME_TIME) {
/*DEBUG*/Log.v(this.getClass().getName(), "run: System is too slow, by "+(frameTime - MIN_FRAME_TIME)+"ms per frame");
}
}
I got the sleep exception handling from a forum (probably this one!) but have never seen the exception thrown
Upvotes: 0
Reputation: 2692
I have downloaded the RAR file with your scrolling background (looks like a grassy field), and installed it on my Motorolla Droid.
I can perceive no stuttering as it scrolls, I've watched it for well over a minute.
Based on your description I'd wager the Milestone hardware/platform has some weird video drawing/timing issue.
Perhaps the explanation is something along the lines of this: The Milestone's diplay refreshes at 60 Hz (just picking a number here, I don't know what it really is), and your frame rate is just slightly off that - say 63 or 57 Hz ... is it not conceivable that approx once a second the timing of your draw, and the timing of the hardware display update mismatch just enough that the background doesn't get a re-draw that one time, and has to wait until your next frame? And that occasionally the timing lines up just enough that you might miss the timing of two or three draws in a row (depending upon how far off your frame-cycle is from the actual screen refresh cycle).
EDIT: Actually, I watched it for another minute I did did see one very short (just perceivable) stutter.
Upvotes: 4