I am developing a game in android with Cocos2d framework with latest build from github(Weikuan Zhou).
In my game, I used lots of images(total images size is around 11MB).
Problem:
I am getting the black box instead of images when I play my game more than 3 times.
What steps will reproduce the problem?
1. When I play my game more than 3 times via "Play Again" functionality of my game.
What is the expected output? What do you see instead?
- images should be displayed properly instead of "BLACK BOX".
and in my logcat, I see the Heap memory goes around 13Mb.
I already release Texture via below method
CCTextureCache.sharedTextureCache().removeAllTextures();
I also tried to remove sprite manually ex. removeChild() method.
But so far not succeeding to find any solution.
If any one have solution for this please let me know.
From what you're describing, you're hitting exactly the same problem i did, which is that cocos2d for android is really buggy when dealing with lots of single sprites loaded individually.
The best route to take to resolve this problem is to get hold of (unless you've got a mac) the free flash version of zwoptex from here http://zwopple.com/zwoptex/static/downloads/zwoptex-flashversion.zip
this will let you build up spritesheets, i suggest relating as many sprites as you can onto each sheet, whilst trying to keep them sensibly grouped.
This is mainly down to cocos doing a single render for ALL sprites in a spritesheet, rather than one render per sprite for normal sprites, hence massively reduced processing time, and much less memory usage.
you can then load the spritesheet with code such as (can't guarantee this code will execute as i'm grabbing snippets from a structured project but it will lead you to the right solution)
CCSpriteFrameCache.sharedSpriteFrameCache().addSpriteFrames("menus.plist"); // loads the spritesheet into the frame cache
CCSpriteSheet menuSpriteSheet = CCSpriteSheet.spriteSheet("menus.png", 20); // loads the spritesheet from the cache ready for use
.... // menu is a CCLayer
CCSprite sprite = CCSprite.sprite(CCSpriteFrameCache.sharedSpriteFrameCache().spriteFrameByName("name of sprite from inside spritesheet.png"));
menuSpriteSheet.addChild(sprite, 1, 1); / you add the sprite to its spritesheet
menu.addChild(menuSpriteSheet, 1); // then add the spritesheet to the layer
This problem happens when you load resources at run time. So it is better to load resources before the scene starts.You can do as follows.
Using the sprite sheets for resources in your game.
Implement your Ui in constructor of your class.
Implement your functionality in overridden method onEnter() in your layer.
You must unload your sprite sheets after finishing your scene.
These is the procedure that I am following.
Thanks.
Related
I'm working on a university project in which I need to visualize on a smartphone datas from pressure sensors built in an insole.
I need to draw on a View, as a background, a footprint, something like the image below but just for one foot.
I don't want to use a static image because with different screens resolution it could lose too much quality, so I'm trying to do it by code.
The main problem is that I'm not very skilled in graphic programming so I have not a smart approach to this problem.
The first and only idea that I had was to take the insole's CAD representation, with its real dimensions, scale it in function of screen's ones and put it together using simple shapes (arc, circle, ecc...) available in Android.
In this way I'm creating a Path which will compose the whole footprint, once I will draw it with a Canvas.
This method will let me to do the work but is awful and needs an exceptional amount of work and time to set every part.
I have searched for some similar questions but I haven't found anything to solve my problem.
Is there (of course there is) a smarter way to do this stuff, saving time and energies?
Thank you
of course, you can always use open gl es
this method might not save your time and energy but will give you a better graphic and scope to improve it for later purpose
the concept is to create a float buffer with all the points of your footwear and then draw is with connected lines on a surfaceView
to get started with open gl es you can use this tutorial : https://developer.android.com/guide/topics/graphics/opengl.html
and here is an example : https://developer.android.com/training/graphics/opengl/index.html
I was looking for information on how to implement an animation to my android application in the most efficient way (without out-of-memory error).
Let's say I have the same animation for smoke as this app does:
https://play.google.com/store/apps/details?id=com.apps4you.virtualsmoking
(The smoke effects)
And I made these with png's frame by frame animation in photoshop.
(150 frames);
When I add these to my app (using animation-list), I get a memory error.
I'm wondering how he added this animation without a memory crash error.
There can be many solutions to the problem:
1)Use canvas
2)You can even use GLSurfaceview
3)Use some game engine like Cocos2d-x,libgdx,unity or rajawali
Flash Pro CC, AS3, Air for Android (v17), rendering mode GPU, stage quality.LOW, FPS: 60, testing device: an old Nexus One smartphone (Android 2.3.3).
The guides say that GPU makes rendering the bitmaps cheap, somehow i can't grasp how exactly it works.
So i have 49 separate bitmap squares covering the stage and one MovieClip in the middle with a bitmap inside tweened to move up and down (jumping ball). Pretty simple, right?
This is the view: http://i.stack.imgur.com/EKcJ6.png
All graphics are bitmaps (not vectors). Yet i get 55 fps (it varies arround 53-57).
Then i select all 49 squares and put them inside a symbol (MovieClip). Visually nothing changes. It seems to increase the FPS a tiny bit, the average fps is now ~57 (55-59).
Then i take the MovieClip (with all the squares inside it) and set cacheAsBitmap=true. Voila, now i have 60 fps!
What is happening in all 3 different cases? Why i need to put bitmaps into one MC and cache this MC as bitmap - aren't the squares already bitmaps?
I have also tried to make each square a MovieClip and cache it as bitmap, but i still got 55 fps.
Is it possible to keep squares separate at 60 fps?
In my real project i have many MovieClips on the stage (~100) but in most cases only one of them is animated at a time. Yet somehow it seems that the mere presence of other movieclips reduce the performance (fps). Obviously, i cannot put them all into one MC and cache it as bitmap as in the simplified example above.
How can i solve this, what should i do?
Thanks!
I think it relates to this best practice recommendation:
Limit the numbers of items visible on stage. Each item takes some time
to render and composite with the other items around it. When you no
longer want to display a display object, set its visible property to
false. Do not simply move it off stage, hide it behind another object,
or set its alpha property to 0. If the display object is no longer
needed at all, remove it from the stage with removeChild().
By putting all the bitmaps in a single container and setting cacheAsBitmap=true you are essentially turning them into a single bitmap as far as the compositor is concerned. This tends to be faster to composite than multiple individual bitmaps. Setting a bitmap to cacheAsBitmap=true (or in a single container with cacheAsBitmap=true) has no effect because it's already a bitmap.
Also note that GPU mode isn't recommended anymore, it was Adobe's first attempt at GPU accelerating the display and they basically gave up on that path in favor of the new Stage3D rendering pipeline. While GPU render mode can work really well when used just right, it can be somewhat unpredictable and confusing, so I would highly recommend you check out Stage3D.
Hope that helps.
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
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.