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()).
Related
I'm working on an app where I must have on a part of the screen an animated music staff. That's:
5 static lines
A dozen of music notes (each one is basically an oval and a line)
A few additional symbols (clefs)
I must have a precise control of the size of each element, and have to smoothly animate position and alpha of the notes and clefs so the notes are moving right to left (disappearing when on the left of the screen, and appearing when on the right, hence the alpha). I also have to change sometimes the color of the notes.
I think I can't use standard "Animations" class, as it's an endless animation with the speed and the notes depending on real time factors.
So what is/are the best way(s) to do that and to achieve a smooth animation?
Different Views? (VectorDrawables?) Single SurfaceView where I manually draw each shape at each frame? (or TextureView?)
(Note: minimum API is set to 15)
Thank you for helping me choosing the right technique.
So you're wrong about the Animations class being infinite. It doesn't need to be. However EVERYTHING in Android will depend on real life factors- Android is not a RTOS (real time OS), there is no guarantee of execution time.
However, if you absolutely need total control, I would just jump to total control- hook the Choreographer so you get a call every 1/60th of a second, and each frame invalidate your view(s) that need to change and redraw them. If the phone is running slow for some reasons like other apps you may drop a frame or run slightly slower than 1/60th of a second, but this is as close as you can get (and what Animation classes use behind the scenes).
With animators you can animate smoothly around 5 different views on average phone. So in your case (with dozen of notes and so on) it will have around 10fps. So slightly better will be SurfaceView and handdrawing all that you want. Maybe GLSurfaceView worth considering.
In order to test this I recommend you to create some test app first, where will be 10 views flying around, and look at performance.
We are trying to create a text animation like Transition and Zoom on the Video.
We are not able to get Smooth transition and the effect is so jerky. Then we understood sub pixel rendering is not possible in android.
What alternatives can we think of? Can we solve this problem in OpenGL?
Ok... I would like to add more to my question....We are actually trying to implement text animations on top of a video which is played by a native player on a surface view.
We tried to achieve the text animations using the android Canvas APIs to scale, translate etc and draw the text. This works but the output is not so smooth. We have verified that its not a performance issue. Even if we refresh the frames at more than 30fps, the
jerkiness is seen.
Then, we tried to use android Views to get these animations and observed that the animations are buttery smooth when Hardware acceleration is turned on. But even the android View system animation fails to give good quality scale animations when hardware acceleration is turned OFF.
This again is not a performance issue since we have tried to dump each frame into a bitmap and checked each frame on PC.
So, it seems that SKIA graphics library used to draw on Canvas when hardware acceleration is turned off, is not capable of sub pixel rendering or something of that sort. For example, when i am running a slow scale animation (a scale of about 0.15 in about 6 seconds), the scale updates happen by 1 pixel in around 3 frames.
But if the same animation is run on a hardware accelerated view, each frames updates a fraction of a pixel and the scale animation looks
very smooth.
I can sure use the view animations while previewing. But I need to get these animation buffers and encode them along with the video. Any inputs on getting these buffers, with hardware acceleration turned ON would help. I have tried Drawing cache, but that seems to be drawn using software rendering pipeline and not hardware.
Smooth transistions and jerky animations have nothing to do with subpixel rendering.
The problem sounds like you're not correctly timing your rendering function. Do not use a interval timer to trigger rendering of a frame. You should put the rendering and animation into your programs event loop idle handler and measure the time it takes to render a frame. Then advance the animation by that time.
After getting help with starting android pong, I realized that I painted myself into a corner.
For reference on the code(Its long) and advice, here is a link to the last thread Updating player score in an android game
Basically the frame rate is halved when i touch the screen. I think it is due to updating everything or drawing on the canvas. This also lends itself to bad communication between the pieces of the application(the view, frame, and oncreate). Is there a recommended way to create an android 2d game? This is based off the lunar landing game and it seemed fine but when i tried to recreate it , it seemed much worse. I could not find a lot of resource on a best practice for drawing and so far this seems a bit discouraging.
So in short
How would you modify the code posted in the link to improve performance? Or did I paint myself into a poorly made corner, and it is time to start a new? If so , how?
Thanks
You don't need invalidate() in onTouch because you are already running a frame animation by the additional thread.
Try to define all the fixed values/variables in the constructor of the SurfaceView or in onSizeChanged() where you know the size of the canvas and bitmaps loaded, so not to make any unneccesary variable creation, requests or calcualtions in onDraw, onTouch or other methods to handle game logic, otherwise it will slow down.
We've noticed that when you put Android views with view animation (nothing complex, just AlphaAnimation and TranslateAnimation) on top of a GLSurfaceView, the animation runs slowly (i.e. you see a lot of stuttering.) I am calling pause() on the GLSurfaceView, and I believe I've confirmed (through setting breakpoints) that the GL draw calls are not getting hit while the animation is playing, so I'm not sure where the slowness is coming from.
Does anyone know of a way around this? I know that on iPhone this also used to be a problem, but there was some OS update they made to fix the issue. They are short view animations (e.g. You Win!) so it's not the worst thing in the world, but it would be nice if there was some workaround.
The reason we are not doing the animations in GL is that they have to be able to run from any Activity in our game, and not all of our Activities have GLSurfaceViews.
Finally, if it matters, we am using the modified GLSurfaceView source from Replica Island http://code.google.com/p/replicaisland/
Drawing on top of a GLSurfaceView is slow, therefore animating is as well. You are forcing the framework to do more work to determine what part of the surface view is visible.
You should really consider doing these animations inside the surface view when you are using a surface view.
An alternative is to put the animation in a small window above your activity.
I'm developing an Android application with OpenGL and JNI (all OpenGL stuff is in C code).
Imagine I've drawn a cube. I want that user can push his finger over the cube and can rotate the cube and move it around the screen.
Is there any way to do that?
How can assign an event listener to touch and move events only when the user touch the cube?
UPDATE I want something like this:
Rotate cube with fingers
Thanks.
This is called "picking" in 3d-ville... There are a number of tutorials on the subject floating hither and yon. There's even another question (sans the JNI spin) here on StackOverflow.
Also, check out this google IO video on developing android games to see why your approach may not be faster than pure Java... It Depends.
It turns out that JNI calls are Quite Expensive, so a JNI-based renderer could end up slower than a pure-java one unless you are Very Careful. YM Will V.
I'm pretty sure you'll have to listen to all touches then change behavior based on what is being touched. I suppose you could compute your cube's bounding box on screen and then monkey with your listeners every frame (or every time it moves), but I seriously doubt that would be the most efficient course to take. Listen for all touches, react appropriately.