Efficiently spawning sprites in Cocos2D - performance

Just a quick question here; I have a background image in my game. Every time I spawn an sprite, I use the [self addChild:#""]; statement. Would it be more efficient to to call [backgroundImage addChild:#""]; instead? I have tested both ways and they both work, but I cannot tell which is more efficient, or if it even makes a difference.
Thanks,
Tate

If your object is CCLayer, calling [self addChild:img], the image will be added to the CCLayer.
I believe your background image is a CCSprite. [background addChild:img], will add the sprite to the background. If you adjust your background, like moving it up, all the sprites attached to background(child of background) would be moving together with the background image.
When you called [self removeChild:background], all the child attached to the background would be removed as well..
It depends on what are the requirements of the game.. =)

Related

Improve CGContextDrawImage performance

I have a custom NSView that has it's own drawRect. I draw a lot of images using CGContextDrawImage into the view. The NsView is in a NSScrollView. The issue I am having is, while scrolling, the drawrect takes too long. the scrolling isn't smooth.
I did try setting wantslayer to true, to enable layer-backed drawing. Now the scrolling is smooth until the next drawrect is called, i.e till next time a new dirtyRect has to be redrawn.
Since I have to use drawrect to draw the contents, is there a way to improve scrolling performance?
if not, is there an alternative?
Update:
the call that's taking time.
I tried what Rob suggested below (using NSImageView for each image). that helped. I see smooth scrolling while setting the images as well.
But I would like to know why CGContextDrawImage takes time? especially rgbaf16_sample_rgbaf_inner. is there a way to avoid it?

Choppy/Slow Animation on first load cocos2d

Write now, I'm creating an interactive ebook using cocos2d. When the program runs the cover page animation is choppy only on initial load. This animation is on the cover page and it is huge. We're talking 13 texture atlases, 26 images.
I know the problem stems from preloading/loading images, but I already loaded all the images before the animation occurs.
-(id) init {
if( (self=[super init]) ) {
isTouchEnabled_=YES;
//Pg0 Animations
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:#"CB0A0.plist"];
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:#"CB0A1.plist"];
...etc.}}
The overall set up of the book is as follows. I build a scene, a menu layer, and then the menu layer pushes and pops different layers/ different pages.
When the cover page is loaded (Pg0), if the user touches a picture it runs through the animation. Then when the user, touches the picture again, a second animation runs.
All the images of the book are loaded in the menu layer (so before any page pushes or pops). I've tried loading these images on the scene, or the individual pages to speed up the process, but that doesn't affect time.
I am running my animation through an animation helper, which loops through the images for me.
Any help would be wonderful, and I am would love to share more code or info about the project if it needed.
Have the same problem. When use cocos2d v0.9 animation was ok, no lag. Lag appears when migrating to cocos2d v2.0.
When you add sprites to cache (addSpriteFramesWithFile:(NSString*)plist) in cocos2d v0.9 texture2d is also created (CCSpriteFrameCache.m:238), in cocos2d v2.0 there is no textture2d creation, texture is created at first use of CCSpriteFrame. I fix it by adding
[[CCTextureCache sharedTextureCache] addImage:textureFileName];
in CCSpriteFrameCache.m:207 (v2.0)
I was just experiencing this problem in cocos2D v3.1 iphone. I had spritesheets that were cached but still were stuttering on loading. I found somewhere on another post that you need to load the texture itself as well to get rid of the initial lag. This is what I did in my caching sprites method:
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"spritesheet.plist"];
CCTexture *temporaryLoadTexture = [CCTexture textureWithFile:#"spritesheet.png"];
Just by loading a dummy CCTexture file, that got rid of all first-time animation and sprite lag. Hope this helps!
Check if your AppDelegate implements the memory warning method. Check what that method does.
By default, cocos2d implements that method and purges all caches. Now when that gets triggered while preloading textures, what happens is that cocos2d removes the preloaded textures because a memory warning was received yet those preloaded textures aren't in use yet. Cocos2d considers them to be "unused" and removes them from memory. Which means next time you use that texture, it needs to be loaded from disk again.
I wrote a blog post where I describe this issue, and ways to solve it. Most importantly: get TexturePacker and use only .pvr.ccz for texture atlases. Try to reduce texture color depth to 16 bit where possible. And be sure to dump texture memory usage to learn how much memory you're actually using, and whether that amount of memory is within reasonable limits. Including older devices with fewer memory that you may be supporting.

Drawing over an image in win32?

First of all, keep in mind that I am a beginner in win32, so I am very likely to be missing the obvious.
I am working with Code::Blocks, C++, win32. I am making a program that:
would load an image from a file
would load some info from another file and draw it over the image.
The program would then draw additional stuff over the image later on. Also, I don't need this drawing to be actually incorporated into the image, the image only acts as a reference for the drawing.
I have managed to display the image in a child (static) window and I have successfully drawn the info onto the main window. When I wanted to combine the two so the drawing would go over the image, however, I got stuck - I didn't know what window to draw to and which message to process for the drawing. I have searched the Internet for any hints, examples, anything, but I found nothing. (This is probably because I didn't know exactly how to describe my problem.)
I have been trying different things over the past few days, like drawing to the static control with the image, and trying to paint to a transparent static control on top of the one for the image, but nothing worked.
If anyone could give me any hints, that would be great! Thanks!
Trap the WM_PAINT message for the window you want to draw. In the handler, add code draw the image (BitBlt function perhaps) first and then the drawing you want. You must also handle WM_ERASEBKGND message which is used to erase the background of the window when re-sizing etc.
Refer: WM_PAINT message, WM_ERASEBKGND message

how to draw many CCSprite without slow performance?

I'm making such a arrow shooting game. Everything is good. but I realized if I draw line tracking my arrow, It will be great. so I put some code on my game in my Scheduler that is supposed to draw circle where arrow is going. But I had to draw so many circle, so game frame is not good when I shoot multi arrow.
Is there other better way? I use CCSpriteBatchNode, plist, CCSpriteFrameCache already. I did all I can do. I need help Thanks so much
this is my code
...............
[self schedule:#selector(CollisionDetection:)];
}
- (void)CollisionDetection:(ccTime)dt
{
for (CCSprite *arrow in arrows->arrowsArray)
{
CCSprite *track = [CCSprite spriteWithSpriteFrameName:#"WhiteCircle.png"];
[track setPosition:arrow.position];
[arrows->rootLayer->arrowsSheet addChild:track];
id delete = [CCFadeOut actionWithDuration:1.0];
id deleteAction= [CCSequence actions:delete ,[CCCallFuncN actionWithTarget:self selector:#selector(spriteActionFinished:)], nil];
[track runAction:deleteAction];
.......
The allocation of objects is a large overhead. If your game runs to slow you should consider creating a pool of arrows at the beginning of the game and only trigger the action on it as soon as you need it. If it is not visible anymore just set it to inactive and reuse it the next time you need an arrow.
Sounds like your problem isn't the arrows, but the circles, which I imagine are Cocos objects too. You'd be better off learning how to draw the circle texture directly to the screen using opengl commands instead of objects. That'll help a lot.
When have a time critical animation, i stay clear from CCCallFunc(N), as it can stall the scheduler for a noticeable amount of time. As I read your code, you have a CallFunc at every scheduled interval ... hmmmm. Have you tried running this without the scheduler, ie package and start all your animations at once, with a single CallFunc at the end ? Instead of changing the position as part of the scheduled interval, use a CCMoveTo that you will run at the same time as your tracking animation.

How does CATransition work?

CATransition is quite unusual. Consider the following code.
CATransition* trans=[CATransition animation];
trans.duration=0.5;
trans.type=kCATransitionFade;
[self.holdingView.layer addAnimation:trans forKey:nil];
self.loadingView.hidden=YES;
self.displayView.hidden=NO;
Notice that nowhere did I tell the transition that I wanted to display the displayView rather than loadingView, so the views must somehow access the transition themselves. Can anyone explain in more detail how this works?
When you add the transition as an animation, an implicit CATransaction is begun. From that point on, all modifications to layer properties are going to be animated rather than immediately applied. The way the CATransition performs this animation to to take a snapshot of the view before the layer properties are changed, and a snapshot of what the view will look like after the layer properties are changed. It then uses a filter (on Mac this is Core Image, but on iPhone I'm guessing it's just hard-coded math) to iterate between those two images over time.
This is a key feature of Core Animation. Your draw logic doesn't generally need to deal with the animation. You're given a graphics context, you draw into it, you're done. The system handles compositing that with other images over time (or rotating it in space, or whatever). So in the case of changing the hidden state, the initial-state fully composited image is blended with the final-state composted image. Very fast on a GPU, and it doesn't really matter what change you made to the view.

Resources