I am developing a Cocos2D/Kobold2D game with ARC. I want to store CCSprite references in a CCArray. All the CCSprite objects are added as children to a parent CCNode. Is it a good idea to wrap the CCSprite objects with [NSValue valueWithNonretainedObject:..] for weak references? In all examples I found the CCSprites were stored retained in CCArrays...
There is really no need to use NSValue.
If you add objects to an NSArray or CCArray or any collection, they will be retained. It is your duty to make sure the objects are removed respectively the collection released at the appropriate time.
In many cases you don't actually need to store node references separately. You have the children array, just iterate over it and select the nodes you need to work with, for example by tagging them or by using the userObject property.
Related
Very new to C++ and Cocos2d-x but I was just toying around with CCArray and had a question. I'm used to NSMutableArray and NSArray, where i dont have to set the size for the array upon creation.
with CCArray every example i find of it has the size set
CCArray *frames = CCArray::arrayWithCapacity(int)
So my question is this, is it possible to leave the capacity open ended?
Is this gonna cause problems in the future?
And can I add more elements in the future as I can do with NSMutableArray, but not NSArray.
thanks!
In cocos2d-x CCArray is mutable, i.e. you can add elements to it. To create CCArray instance without capacity, you can use CCArray::array() constructor. CCMutableArray is template-based container that can store objects of the same type. CCArray stores objects as CCObject instances, so you have to cast them after getting from CCArray instance
I have four different types of objects within my environment(box2d), each type of object having multiple instances of itself, and would like to find the most efficient way to deal with adding and manipulating all the CCSprites. The sprites are all from different files, so would it be best to create each sprite and add it to a data structure (NSMutableArray) or would I use a CCSpriteBatchNode even though each CCSprite file is different (for each type of object)? Thanks.
#interface LevelScene : CCLayer
{
b2World* world;
GLESDebugDraw *m_debugDraw;
CCSpriteBatchNode *ballBatch;
CCSpriteBatchNode *blockBatch;
CCSpriteBatchNode *springBatch;
CCSprite *goal;
}
+(id) scene;
// adds a new sprite at a given coordinate
-(void) addNewBallWithCoords:(CGPoint)p;
// loads the objects (blocks, springs, and the goal), returns the Level Object
-(Level) loadLevel:(int)level;
#end
Well, CCSpriteBatchNode isn't likely your answer, if you are using different textures. From the Cocos2D documentation here:
CCSpriteBatchNode is like a batch
node: if it contains children, it will
draw them in 1 single OpenGL call
(often known as "batch draw"). A
CCSpriteBatchNode can reference one
and only one texture (one image file,
one texture atlas).
So that's out. Ostensibly, you'd be adding these CCSprite objects to a CCLayer (or some other CCNode object), right?
There's no need to create a separate array for managing child objects -- Cocos2D provides you with the children property of any node. If you [myLayer addChild:newSprite], you'll have a reference to it in children.
Does that help? I can expand my answer if you provide me with a little more idea of your use case.
I am working on a game. There are balls that fall from the top of the screen, and the player has to catch them, as the are caught they stack ontop of one another. I have a method that creates each new ball and adds it to an Array that i use to move the sprites. Problem is that the after they collide I need them to stop moving, since the array is called on to move them they all move. And if i try to make them stop they all stop. So I was hoping to create a pointer attribute if ther is such a think, for example "sprite.position" I need a new attribute that i can check like a boolean. I was hoping to create a attribute like sprite.hasCollided and if it returns YES then the ball should no longer move. Is this possible or is there a better way to do it?
Thanks
Tanner
I would suggest you create a ball object. And add the boolean as as part of the object.
CCNodes (and, by inheritence, CCSprites) have a userData property, which is a void*. You can use this to relate a custom object to a cocos2d object. Keep in mind if you use the userData option, you will, in most cases, need to allocate any memory when you create/assign the sprite, and release it when you are done.
int* myInt = (int*)malloc(sizeof(int));
*myInt = 0;
sprite.userData = myInt;
//some time later, when you are done with the sprite
free(sprite.userData);
As an improvement on the userData property, you can do what xuanweng suggests and create a ball object containing various game-related properties for the balls, and assign an instance of this to each of your ball CCSprites using the method above.
If I have a grandfather object that contains an array of parent objects that contains an array of children objects. Assuming I have released the objects after adding them to the arrays, how do I go about releasing all the objects? Can I just call removeallobjects on the grandfather object? When I do this I get a leak :(
Thanks
Simply call release on the "grandfather" object - it'll then release the "parent" objects, who will release the "children" objects, etc. all the way down. (Or "up" depending on how you look at it.)
In essence when you release an NS(Mutable)Array, it'll release the objects it has pointers to - if those objects happen to be NS(Mutable)Arrays, they'll therefore release the objects they have pointers to...
I am trying to create a game and have run into what is probably a pretty easy problem to solve.
As the player goes through the game, many objects (Vehicle) will be added and removed.
The Vehicles get added to an array called currentVehiclesMutableArray.
My problem is I cant figure out how to retain a Vehicle so that it remains in the array until I am finished with it.
A NSMutableArray automatically retains anything you add to it.
In fact, you have to make sure you release an object after you added it, or you'll have a memory leak.
For example:
Vehicle *vehicle = [[Vehicle alloc] init];
[mutableArray addObject:vehicle];
[vehicle release]; // you should release it, because it was retained by the array
// at this point, mutableArray holds your vehicle object, and is retaining it