I just noticed that when I turn off my screen on my mobile device and turn it on again some graphics resize or disappear. My game is coded towards 800x480 resolution and my HTC Desire HD doesn't have this problem (it has a 800x480 resolution). However, when tested on my HTC One or a Samsung Galaxy S3 the graphics scale or behave weird.
The only thing those objects who behave weird have in common are that they rotate every frame. Stationary objects don't seem to be affected at all.
I have stars who rotates and scales up/down every frame and I have a moving block who goes left/right or up/down. The moving block seems to ignore collision when the screen is restarted and disappears to places he should not be able to reach.
Any ideas?
Thanks in advance.
When you turn off the screen, rendering is paused (i.e. no calls to render() are made). When you resume, Gdx.graphics.getDeltaTime() will be very large as the last frame was rendered at least some seconds ago. So the delta time values that are normally in the order of 0.0166 (60 FPS) will now be in the order of a 100 times greater.
If you are using this delta to take a physics simulation / collision check step, that will go beserk because it's way too large. Rotation shouldn't be a real problem, but scaling will also go out the roof.
A simple way to avoid this is to put in something like
if (delta > 0.1f)
delta = 0.0166f
to avoid taking really large steps.
Related
I am trying to make a game where the planet would be in the center of user's screen and very slowly rotate like planet would.. So first I decided to test it if everything would work fine, and it doesn't.. I get a simple "planet" image like this:
Bitmap image = BitmapFactory.decodeResource(getResources(),R.mipmap.totone);
I also have a variable that stores the angle. Then in the draw function I just rotate the canvas, draw my planet (now rotated), and rotate canvas back. like this:
//the planet's image is 512x512px
canvas.rotate(ang,256,256); //256, 256 is the center of rotation
canvas.drawBitmap(image, 0,0, null);
canvas.rotate(-ang,256,256); //rotate back
I have no idea why, but it looks like when the image is rotated by 90 and 270 degrees the game fps slows a little? I made a little gif to show the problem. The fps is perfectly 60 all the time but then it drops at 50ish for couple miliseconds for no reason? What is causing this? I tried to change my thread's target fps to 30 and it looks like no fps drops happened then.. So it's probably performance issue. Note that I tried rotating the bitmap using maany different methods, the fps drop effect is still the same..
Gif
Most likely, this is an interaction between the device's fixed screen refresh rate and a slight variation in the time it takes to draw the bitmap at certain angles.
I'm guessing that you increment ang by a constant amount in onDraw(). This fact can be used to explain the sharp change in rotation rate.
EXPLANATION
Your device refreshes its screen at 60Hz. That means onDraw() gets called at 60Hz, max, under ideal conditions: About once every 16.7ms.
Let's assume that onDraw() takes about 15ms to execute. There's 1.7ms left over; everything's fine! You get a nice, smooth, 60Hz rotation.
Then assume that, at certain values of ang, onDraw() takes just a little bit longer; say, 18ms. (I will speculate on why the execution time of drawBitmap() varies based on the angle in a moment. For now, let's look at what happens with this 18ms drawing time.)
Ideally, onDraw() gets called at 60Hz. But now you're taking too long; more than 1 cycle. The compositor now has to drop a frame from your app, because you couldn't supply it fast enough! So, instead of onDraw() executing every 16.7ms, now it can only be called every 33.4ms.
In other words, the screen hardware refreshes at a constant rate, and when your onDraw() crosses that 16.7ms threshold, your update rate gets cut exactly in half.
This is hinted at in your GIF. The displayed frame rate goes from 60 to 51, but it seems pretty clear to me the actual rotation rate drops by almost exactly 50%. I suspect the discrepancy is simply due to the way you calculated the displayed frame rate.
SPECULATION ON VARIATION IN drawBitmap() EXECUTION TIME
Could be the caching performance of the processor. At certain rotation angles, the graphics logic could be accessing bitmap memory in a way that is not ideal for the L1 cache/prefretching logic. In other words, you could be getting a lot of cache misses at these angles.
RECOMMENDED FIXES FOR PLAYABILITY
Use a faster graphics pipeline, such as OpenGL, and/or:
Base ang on a time hack (uptimeMillis()) instead of an increment. You'll still drop frames, but the apparent rotation rate will be corrected.
If you want to go really crazy, you could supply a second bitmap, pre-rotated 90 degrees to the first, and use this bitmap for draws that take place at angles closer to 90/270 degrees. If I'm right about the cache misses, this would ameliorate the problem.
I have a game developed natively for Android, and now my users also want an iOS version. I thought LibGDX would be the better choice because it'll let me reuse Java code from the game, and also I already have some experience with it.
In my game I have different image sizes for different device densities (in drawable-hdpi, drawable-xhdpi and so on).
So, my question is: how can I achieve the same, but using LibGDX (also taking care of the new densities required by iOS device resolutions, if any change is required)?
Thank you.
Yes you can achieve the same, but it wont be automatic like on Android unless you write some native code as well. I have found that the best way to manage it is simply to do it yourself:
1) When your app starts you can get the screen size and density using Gdx.graphics.getHeight(), getWidth(), Gdx.graphics.getDensity()
2) Depending on the size and density you can change the location path to the correct folder where your assets should be loaded from.
3) Now when any asset loading code is run make sure that it uses your pre-set path from the step above, so that you get the correct assets for that display size/density.
Most of the time you can use the largest image and use `Viewports' to handle resolution and aspect ratio for you. The larger images will be scaled down and this will result in some loss of detail of course.
Viewports will automatically scale the size you want to show of your game world to the screen it displays it. For example FitViewport(100, 100) will create a viewport that shows 100 x 100 "game units". If you would play this on a 1920 x 1080 device it will scale that 100 x 100 game world to a 1080 x 1080 area and leave an empty bar of 840 x 1080.
The size of the game world has nothing to do with pixels. You could create a enemy with the size of 0.5f x 0.5f world units and give that a texture of 256 x 256 pixels. Your viewport scales this for you to the correct size.
Unless you want a pixel perfect game this should be good enough. On some bigger screens but low resolutions devices you might get some minor artefacts due to filtering, setting the filtering for your textures Texture.setFilter(TextureFilter.Nearest, TextureFilter.Linear) might fix some.
All I ever think about when designing graphics are the pixels in my art should represent roughly or at least 1 screen pixel. Usually I just draw pixel perfect for HD and it looks fine on a 800 x 480 screen. If you want to squeeze out a bit more performance you could use MipMaps, I think TexturePacker generates them automatically with the right Filter settings but I have no experience with them.
This can be done using
com.badlogic.gdx.assets.loaders.resolvers.ResolutionFileResolver.
Here is javadoc for it.
So, after ages of searching all I ever keep coming across is spritesheet. I am planning on making a multiplayer game where the changing of items and gear happens regularly. I want to have fun creating new items, but with spritesheets it can get ridiculous redrawing the same movement and having choppy transitions.
cdn.akamai.steamstatic.com/steam/apps/524970/header.jpg?t=1475608912
Here is the game that kind of inspired me. Very smooth characters and when I watch the animation it is basically just rotating parts, or expanding the image. Am I missing something, or is there an animation technique where you can easily just rotate limbs, or perhaps just expand the image without having to constantly sift through images. Some pseudo code could be ImageWidth = ImageWidth * 1.5 to create a bigger version. Or ImageRotation = 20 where the image rotates at a certain point. Just wanting to know what people use to animate themselves or if you have advice for me.
I just finished developing my mini-game on Android and I got some questions about perfomance and generally "how to": If I have 25+ objects on the creeen (just a polygon with 7-8 angles) its starts to lag hard and CPU usage is very high (15-20% without colision detection, up to 50% with collision detection on samsung note 10.1 tablet).
So I have ~25 polygons (asteroids) and they are always "flying". So to move them I make a Timer, right? On TimerTask I got something like this
public void move() {
translate[1] += speed[1];
translate[0] += speed[0];
updateTranslateMatrix(); // updating translate matrix and then send it into vertex shader
updateAABBCoords(); // update coordinates of Axis-aligned bounding box
updateCoordsByTranslate(); // update coordinates of verticles (to be able to define exact collision (with bullets and starship))
}
Is there something unnecessary in this method?
Also I want to ask if it is OK to run this timer every 17 ms? Or 17 ms is too often? I feel smoothness of movement only at 17 ms, may be I am doing it wrong? And same Timer interval I got on starship/bullets movement and on Collision detection.
Help me, please. I feel like missing something huge and fundamental, because 50% CPU on note 10.1 in that simple Asteroids game is not normal.
One key issue, I believe, is that you are assigning an individual Timer to every object instead of employing a general purpose game loop. A vast majority of games use a game loop which runs continuously and can be split, typically, into two components: Update and Render.
An article on basic game loop design for Java/Android
An answer to a relevant question on game loop design on gamedev.stackexchange.com
When using a game loop you can not guarantee being able to update exactly every 17ms or some other arbitrary duration. Instead, the Update and Render methods receive a DeltaTime parameter which is the time since the last frame.
This is then used when, for example, getting new object positions by multiplying it with the object's velocity. Doing so allows for smooth interpolation of position and ensures that object speed is not affected by CPU speed.
This isn't directly a programing problem but I feel it still can fall under the catagory, I am sorry if this is the wrong place. I am making a game in flash using box2d and I decided to draw the levels in flash as the level design would look better, The levels are very large ( this level is 10,000 pixels long) and the canvas in flash just won't display anything.
The preview in the library seems to be able to display the drawing longer than the one on the stage. How do I go about making the canvas longer? Should I try upgrading to a newer version of flash, does that version allow this?
You just don't put everything at once over your canvas, instead draw only those level primitives or parts that are visible right now. Or, if your level is basically a pretty simple shape, you can just change its X and Y so that the relevant part of the level is displayed on stage.
Don't use giant bitmaps - they use a lot of memory, and even if not all of the content is visible, they will degrade performance considerably. For this reason, Flash imposes a size limit of 4095x4095 pixels (or an equal amount of pixels in rectangular formats).
The way to deal with this is to tile your graphics into parts of equal size, preferably smaller than the stage (1/2 or 1/3 side length is a good measure). You then place them all as a grid into a larger Sprite or MovieClip and set visible=false; on each tile. Then, at runtime, your game loop must check for each frame, which of the tiles should actually appear on the stage - and only those should then be set to visible=true;. That way, you reduce the amount of pixels drawn to what is absolutely necessary, and keep screen memory usage to a minimum.