I'm just trying to figure out the best approach for running a scolling background on an android device. The method I have so far.... its pretty laggy. I use threads, which I believe is not the best bet for android platforms

4 Answers
4

There could be a variety of things causing your background scrolling to be choppy.

Your image could be very large causing canvas.drawBitmap(); to be slow

Your loop could be firing slowly or inconsistently. I could be wrong, and maybe there are extenuating circumstances, but generally a sleep(); call is never good in a game loop, or any loop for that matter. It could quite easily be the a contributor to your choppiness. I'd remove it to see what happens.

Other code you've stripped out from the example could be taking up lots of milliseconds in your loop.

I highly recommend you track the number of milliseconds between each iteration of your loop. You can use this data to determine how far to move your background based on how long the last loop took. This should smooth out your scrolling for the most part.

If the issue is because your image is so large that drawing it is taking up too much time, you may need to break the image up into smaller parts and "stream" it across the screen based on the scrolling position.

Actually a sleep call is good in every game loop, but as you pointed out it should be a variable time based on how long the rest of the loop took. But especially in a mobile device, a tight CPU loop will only drain the battery that much faster. No need to run at 200 FPS when the screen can only really update at 60 (or 30, or whatever rate it updates) - you'll just get complaints about draining battery life.
–
RicketFeb 4 '11 at 22:14

I agree with you. I've read (specifically about .NET's implementation, I thought it applied more generally as well) that sleep(); calls only promise to sleep for at least the specified time, maybe longer. Since we're talking about milliseconds in a game loop depending on how much longer it sleeps it could be an issue.
–
NateFeb 4 '11 at 23:37

1

Usually sleeping to 1ms (or less) before you need to wake up and then busy-looping for a short period is safe enough. If sleep doesn't wake you up to within millisecond precision, the system is overloaded and you will be starved for resources anyway.
–
user744Feb 5 '11 at 0:17

But if you just want one background scroll, you could get a pretty good feel for how to do it from this game example.

(NOTE: I believe this game has scrolling backgrounds, correct me if I am wrong and I will edit this Answer)

EDIT:

You should definitely handle the drawing in a separate thread from the user input. Also depending on what version of Android you are building for, you might want to sleep in the input handling method for a couple milliseconds. You would want to do this because in earlier versions of Android, pressing the screen would result in a flood of inputs which would slow down the processing of an application. This was more acute in games. Check out the Replica Island code for more information on what I'm talking about.

Chris sleeps the input thread for 32 milliseconds which is approximately 30 sleeps per second (which matches 30 fps for the game). This makes sense because if you are only calling your update method once per frame, you don't need to have the input thread produce any more than 1 input for a touch event.

thanks, that helped. but how can I split the touch actions that results in its own draw. Ontop of the current draw. for example. map is scrolling from top to bottom. where u touch moves your character. at the moment everything is drawing in one section.
–
StevanicusFeb 23 '11 at 21:50

@Stevanicus I'm not completely sure what you are asking but the basic idea is you want to separate your drawing calls and your update calls. You should take input and process everything in an update method and after the update method has finished processing everything for the frame, you should draw the frame by calling draw. In the draw method is when you draw everything in opposite order you want it to show up on the screen. (You want to draw your background first). Not sure if this answered your question, if it didn't, can you give me a little more specifics?
–
jluzwickFeb 24 '11 at 1:56

Thanks for your comment. How can I separate the drawing from the user input in the surfaceview? And would u say the above thread is best way for handling drawing?
–
StevanicusFeb 24 '11 at 23:37

Read this article, specifically how the class FPSTimer is used in the draw thread to time the drawing loop. I've used this example to write my own surfaceview-based game. It also provides a good basis for handling key event inputs. For handling touch events, you would want to override the View.OnTouchListener for DOWN, MOVE, and UP events.