I use CCSpriteBatchNode, but I got some exception error. Here is my code:
//Use CCSpriteBatchNode.....!!!
CCSpriteBatchNode *singleGameSpriteBatchNode;
//if < 16 , create dice
unsigned int createDiceNumber = 4 - (maxDiceNumber%4) ;
for (int i = 0; i<createDiceNumber; i++) {
CCLOG(#"Total dice number = %d" , createDiceNumber);
int randomDiceNumber = arc4random()%17;
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"singleGameImage.plist"];
singleGameSpriteBatchNode = [CCSpriteBatchNode batchNodeWithFile:#"singleGameImage.png"];
Dice *tempCreateDice = [[Dice alloc]initWithSpriteFrameName:[self getDicePicture:randomDiceNumber]];
[singleGameSpriteBatchNode addChild:tempCreateDice];
[self addChild:singleGameSpriteBatchNode z:5];
[createDiceArray addObject:tempCreateDice];
[tempCreateDice setPosition:ccp( 40 , 220-(60*i))];
[tempCreateDice setRecentPosition:ccp( 40 , 220-(60*i))];
[tempCreateDice setDiceType:randomDiceNumber];
[tempCreateDice release];
maxDiceNumber++;
mustMoveDiceNumber++;
}
CCLOG(#"length = %d" , [createDiceArray count]);
}
It succeeds to create dice with image. But when I use the ccTouchesBegan method I get some error message:
*** Assertion failure in -[Dice draw], /Users/xxxxx/Documents/C_Program/iOs Practice(2011)/DiceGame/DiceGame/libs/cocos2d/CCSprite.m:576
2012-08-13 02:32:47.921 DiceGame[11103:c07] *** Terminating app due to uncaught
exception 'NSInternalInconsistencyException', reason: 'If CCSprite is being
rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called'
PS: Dice is a class inherits from CCSprite that I created.
If it can't use CCSpriteBatchNode, maybe I should go back to use CCSprite.
Have you read the error message?
'If CCSprite is being rendered by CCSpriteBatchNode,
CCSprite#draw SHOULD NOT be called'
Either don't override the -(void) draw method or don't use the sprite batch node.
Related
probably this is a simple problem to solve, since I'm quite new.
I have a scene with a waiter holding a tray of food
(the food is a random CCSprite choosen from an array)
each time he comes onscreen he holds a new piece of food
(the user touches the food and the waiter walks off to return
again with a new piece of food
however I cant seem to delete the old peice of food from the screen
as it says the child is already added...
any help would be great
-(id) init
{
///other code then...
waiterOnSCreen
= [CCSprite spriteWithSpriteFrameName:#"CatUP.png"];
waiterOnSCreen.position = ccp(CatOffSCreenPosX, catXpos);
[self addChild:waiterOnSCreen z:0];
//moving the waiter
// the random food sprite is added later to the waiter
// [waiterOnSCreen addChild:myRandomSprite];
}
-(void)LoadRandomFood
{
///I make my array here then and add CCSprites
RandomFood = [[NSMutableArray alloc]initWithObjects:
//cake,
RandomMuffin,
RandomMeat,
RandomCake,//
nil];//
int i = 0;
int count= [RandomFood count];
if (i < count)
{
int i = arc4random() % [RandomFood count];
myRandomSprite = (CCSprite *)[RandomFood objectAtIndex:i];
//waiterOnSCreen is a CCSprite added on the init
[waiterOnSCreen addChild:myRandomSprite];
myRandomSprite.position=ccp(290,220);
myRandomSprite.tag = RandomFoodTag;
}
}
later
in if(CGRectContainsPoint(waiterOnSCreen.boundingBox, location))
{
//trying to remove the food here
//Ive already tried to remove the sprite using
[self removeChildByTag:RandomeObjectTag];
//and also
CCSprite *wantedSprite = (CCSprite *)[self getChildByTag:RandomFoodTag];
[wantedSprite removeFromParentAndCleanup:YES];
}
}
Im guessing its also crashing 'child already added. It can't be added again'
as its trying to add RandomMuffin,RandomMeat,RandomCake, again
im not too sure how to fix that.
You shouldn't need to create another array just to delete a sprite. If you can provide a more complete picture of your project I would be happy to review it. Can you post the entire code file where you are doing your work? Or multiple files? On inspecting some of your samples further a few concerns in LoadRandomFood you are allocating an NSMutableArray without checking if RandomFood already has a value.
Something like this would be safer though note I am just doing a sanity check here. It would be more efficient to just fill in RandomFood once on init or elsewhere that is not going to be executed constantly.
-(void)LoadRandomFood
{
if (RandomFood)
{
[RandomFood release];
}
///I make my array here then and add CCSprites
RandomFood = [[NSMutableArray alloc]initWithObjects:
//cake,
RandomMuffin,
RandomMeat,
RandomCake,//
nil];//
int i = 0;
int count= [RandomFood count];
if (i < count)
{
int i = arc4random() % [RandomFood count];
myRandomSprite = (CCSprite *)[RandomFood objectAtIndex:i];
//waiterOnSCreen is a CCSprite added on the init
[waiterOnSCreen addChild:myRandomSprite];
myRandomSprite.position=ccp(290,220);
myRandomSprite.tag = RandomFoodTag;
}
}
In the case of the crash when adding a sprite are you sure the removeChildByTag call is being executed? Is it possible you are re-assigning the tag to a new sprite before deleting the old one? Have you stepped through the logic in the debugger? Again it would help to see a more complete code file here.
I had to make another array to access the sprite and delete it
NSMutableArray *_buffer = [NSMutableArray new];
[_buffer insertObject:myRandomSprite atIndex:0];
CCSprite *sprite = (CCSprite *)[_buffer objectAtIndex:0];
[sprite removeFromParentAndCleanup:YES];
I'm having a strange problem... I have a custom class with sprite and booleans properties
In my main GameLayer, I have CCLayerColor *my1layer and in my .m section I have this code:
my1layer = [CCLayerColor layerWithColor:ccc4(144,238,144, 255)];
[self addChild: my1layer z:5 tag:100];
[my1layer setContentSize:CGSizeMake(200, 1280)];`
//default start position
my1layer =ccp(s.width/2-420, s.height-s.height+180.);
MylmageItem *postImage1 = [[MylmageItem alloc] initWithLayer:self];
[postImage1 release];
postImage1.postImageNum=CCRANDOM_0_1()*12 +1;
postImage1.postImage = [CCSprite spriteWithSpriteFrameName:(NSString*)[self assignPostImage:postImage1.postImageNum ]];
postImage1.postImage.position =ccp(my1layer.contentSize.width/2, my1layer.contentSize.height-my1layer.contentSize.height+80);
[my1layer addChild:myImage1.slotImage z:6 tag:101];’
code above does work and shows the images on layer, however when I try to access the property postImage1.postImageNum, it shows 0 always...
I do this: CCLayer *myLayer1 = (CCLayer*)[self getChildByTag:100]; later to retrieve my object...
MyImageItem *tmpImage1 = (MymageItem*)[myLayer1 getChildByTag:101]; from here I always get 0 when I do CCLOG(#"postImage1.postImageNum %d",tmpImage1.postImageNum);
How do I get data from my1layer?
Sprite animation issues.
Using this example which seems to work for others:
How to create animation in cocos2d 3.0?
So I do this:
NSMutableArray *ballAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 11; ++i)
{
[ballAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache]
spriteFrameByName: [NSString stringWithFormat:#"discoball1200x2008c16-%d.png", i]]];
}
CCAnimation *ballAnim = [CCAnimation
animationWithSpriteFrames:ballAnimFrames delay:0.1f];
discoBallSprite = [CCSprite spriteWithImageNamed:#"discoball1200x2008c16-1.png"];
discoBallSprite.position = ccp(upper1Body.position.x,upper1Body.position.y-200);
CCActionAnimate *animationAction = [CCActionAnimate actionWithAnimation:ballAnim];
CCActionRepeatForever *repeatingAnimation = [CCActionRepeatForever actionWithAction:animationAction];
discoBallSprite.scaleX = 0.25;
discoBallSprite.scaleY = 0.25;
[discoBallSprite runAction:repeatingAnimation];
[self addChild:discoBallSprite z:10];
I get the following error:
'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
Obviously the error message is saying my image file is nil but it seems perfectly fine.
I tried renaming files to remove the extra "-" character but no change (I also renamed files outside of Xcode and re-imported with new name).
All my images are in Resources folder.
I tried moving images out of Resources folder to next level up but still the error.
The naming of them seems fine.
Any ideas what else to check?
Make a sprite sheet, add it to your int
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"YourAnim.plist"];
Now in the animation code
[ballAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName: [YourAnim.png", i]]];
When you make a sprite sheet it makes two things, 1) a png with the sprites and 2) a plist with the coordinates
if you so decide to use the program I told you about make sure you set it to cocos2d
See The code Link
Now Change for Cocos2dV3 is below.
In the link code there is CCAnimation that is replace by CCActionAnimate in V3 and also CCRepeatForever is replace by CCActionRepeatForever in V3.
Also check your .plist images may be 10 althougt in for condition it get 11th image in it. so may be that is your problem to insert image in array,
replace and try.
for(int i = 1; i < 11; ++i)
{
// Code
}
Change it work fine.
I am using tilemap in my box2D game in which I have created powers. When the player hits the power, a score label is displayed on the screen. Along with this I want to remove that power from the tilemap when player hits it. I have displayed label but I am unable to remove the power. Here is some code :
In ContactListener I am calling the method which removes the power from tilemap :
void ContactListener::BeginContact(b2Contact *contact) {
else if(actorA.tag==obj.gamePower.tag) //obj is a DataClass object.
{
[GameScene addPointLabel]; // For displaying score label
[GameScene removePower:actorA];
}
+(void)removePower:(id)sender
{
GameScene *obj=[[GameScene alloc]init];
CCSprite *sprite = (CCSprite *)sender;
[obj removePowerFromScene:sprite];
[obj release];
}
-(void)removePowerFromScene:(id)sender
{
CCSprite *sprite = (CCSprite *)sender;
[self removeChild:sprite cleanup:YES];
}
I have created an object layer on tilemap to display power. But somehow, I am unable to remove it. Can someone help me?
If power is a CCNode why don't you remove it with [power removeFromParentAndCleanup:YES] ?
The (removePower:) does remove nothing because it creates a new scene and remove the sprite from that scene where the sprite does not belong to.
Another notice, be careful with contact listener. Removing o node in BeginContact is potential of crash. Let imagine the case that powerA contacts with both actor1 and actor2. The first call to BeginContact with powerA and actor1 removes powerA, so subsequent call to BeginContact with powerA envolved will crash !
I have problem with following code.
mySpriteArray=[[NSMutableArray alloc] init];
star=[CCSprite spriteWithFile:#"22.png"];
for(int i=0;i<10; i++)
{
[mySpriteArray insertObject:star atIndex:i];
}
// NSLog(#"x=%i",[mySpriteArray count]);
for (int i=0; i<10; i++) // Opponents is NSMutableArray
{
CCSprite *tempSprite = (CCSprite *) [mySpriteArray objectAtIndex:i];
tempSprite.position=ccp(100,100);
[self addChild:tempSprite];
}
}
where star is a object of CCSprite and mySpriteArray is a mutable array.The problem is that when i run the program it crash and say
* Assertion failure in -[GameScene addChild:z:tag:], /Users/salimsazzad/Desktop/balon hunter/libs/cocos2d/CCNode.m:305
2010-10-08 19:05:35.854 balon hunter[3967:207] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'child already added. It can't be added again'.
i can't understand whats wrong,i am adding 10 object,not 1 object in 10 times because CCSprite *tempSprite = (CCSprite *) [mySpriteArray objectAtIndex:i];creating a new object each time.
so what is the problem???
You have created your star object once and added it 10 times to array:
star=[CCSprite spriteWithFile:#"22.png"];
for(int i=0;i<10; i++)
{
[mySpriteArray insertObject:star atIndex:i];
}
So your array contains the same object and that's the reason of assertion you get.