How to remove the sprite from parent in cocos2d-android - cocos2d-iphone

Topic In Cocos2d-android game:
To delete the sprite after collided with another sprite, i have used spriteRect function, but this isnt making the sprite to get removed after intersect, after lot of googling got to know that it should be deleted from parent,
here's the code
CGRect ship1Rect = CGRect.make(ship1.getPosition().x - (ship1.getContentSize().width/2),
ship1.getPosition().y - (ship1.getContentSize().height/2),
ship1.getContentSize().width,
ship1.getContentSize().height);
if (CGRect.intersects(targetRect, ship1Rect))
{
parent.removeChildByTag(17, true);
}
but here parent.removeChildByTag(17, true); in this line getting error as "parent cannot be resolved" error, where am i going wrong please can anybody tell

ship1.getParent().removeChild(ship1,true);
or
ship1.getParent(). removeChildByTag(17,true);

You can use only
removeChild(ship1,true);
insteasd of
parent.removeChildByTag(17, true);

Related

Cocos2d-x runAction Error

Okay, so I want my cat sprite to move up and down onClick of two (UP and DOWN) buttons.
I'm a beginner in cocos2d-x.
So, in mygame.h i have a global declaration of the sprite cat:
cocos2d::Sprite *cat;
In one function i create a new scene and add a cat in it.
cat = Sprite::create("cat.png");
cat->setScale(0.2);
cat->setPosition(0, 190);//(Director::getInstance()->getVisibleOrigin().x + 50, Director::getInstance()->getVisibleSize().height / 2);
layer->addChild(cat);
playscene->addChild(cat);
In another function(button callback) i have this code:
void HelloWorld::down(Object* pSender){
CCActionInterval* down = CCMoveBy::create(1.0f, Point(0.0, -20.0));
cat->runAction(down);
}
And everything's ok untill i press the up or down button.
It throws an error on the cat->runAction(down); line.
When i exemine the variable cat, it looks like I cant get to the position parameters. Its a memory read error..
In cocos2dx 3.0
you can write direct in runaction for any sprite.
spriteName->runAction(Sequence::create(MoveBy::create(1.0f,Point(398,565)),NULL));
It looks like you are mixing Cocos2D-X 2.x API's with Cocos2D-X 3.0 ones. I'm taking a stab in the dark guess and saying it looks like you're trying to use 3.0. You will need to change the following line:
CCActionInterval* down = CCMoveBy::create(1.0f, Point(0.0, -20.0));
To:
ActionInterval* down = MoveBy::create(1.0f, Point(0.0, -20.0));

Cocos2d-x ccaction not called and ccsequence create issue

I'm trying to do what I did hundred of times with cocos2d, but with cocos2d-x seems I have less luck.
If i do
CCsequence *squence = CCSequence::create(someAction1, someAction2, NULL);
the compiler says:
No matching function for call to 'create'
I've found this problem around the internet but without any solution. By the way, if I do a simple action like:
CCAction *action = CCMoveTo::create(5.0f, CCPointMake(0,0));
sprite->runAction(action);
the action is not even called, and the sprite is not nil (I've printed his size etc), printing info about that sprite it is the exact object it should be
Try this:
CCFiniteTimeAction *action = CCMoveTo::create(x, (y,z));
CCsequence *squence = CCSequence::create(action, NULL);
I think the error is because CCSequence expects CCFiniteTimeAction classes but you're declaring them as CCAction which makes the compiler think you're passing the wrong type, complaining that there is no create function that takes CCAction as parameters.
You can try like this
CCMoveBy *action = CCMoveBy::create(.5, CCPointMake(ball->getPositionX(), ball->getPositionY()+100));
CCMoveBy* action_back = (CCMoveBy*)action->reverse();
ball->runAction(CCSequence::create(action, action_back, NULL));
ball is sprite

Cocos2d and SpriteBatchNode: cannot identify which sprite frame is causing an Assertion to fail

I have already asked something similar but I can't figure out properly how to debug this. That's the question.
I added some Exceptions handler (catches all Objective-C) exceptions and that's the result of what I see:
The problem is with the setTexture method and it fails at the assertion verifying whether the texture name that needs to be displayed is the same as the one in the current sprite batch node.
This happens when trying to replace one scene with another but doesn't happen all the times. It has to do with the new scene as I tried to "isolate" the problem by calling the replace from a different part of the game and it still does give trouble.
In the game scene I have a couple of sprite sheets and sprite batch nodes but as I don't manage to isolate a sprite sheet id I cannot understand which sprite frame is giving me the problem, as well as I don't understand why this happens only sometimes.
I would like to:
understand which sprite frame name gives me the AssertionFailure
understand to which sprite sheet it belongs
This should help me to understand if it is a naming problem or if this has to do with something else.
Hoping not to be too lame with this question..
EDIT: I tried the answer but I am not able to read the 'fileName' information, here is what the debugger says "Summary unavailable":
That's how I create the filename property:
/** TMP: Bug solving filename */
#property (copy) NSString *fileName;
-(id) initWithTexture:(CCTexture2D*)texture rectInPixels:(CGRect)rect rotated:(BOOL)rotated offset:(CGPoint)offset originalSize:(CGSize)originalSize
{
if( (self=[super init]) )
{
self.fileName = [NSString stringWithFormat:#"GLUINT texture name: %i", texture.name];
self.texture = texture;
rectInPixels_ = rect;
rect_ = CC_RECT_PIXELS_TO_POINTS( rect );
offsetInPixels_ = offset;
offset_ = CC_POINT_PIXELS_TO_POINTS( offsetInPixels_ );
originalSizeInPixels_ = originalSize;
originalSize_ = CC_SIZE_PIXELS_TO_POINTS( originalSizeInPixels_ );
rotated_ = rotated;
}
return self;
}
-(id) initWithTextureFilename:(NSString *)filename rectInPixels:(CGRect)rect rotated:(BOOL)rotated offset:(CGPoint)offset originalSize:(CGSize)originalSize
{
if( (self=[super init]) )
{
self.fileName = fileName; //TMP
texture_ = nil;
textureFilename_ = [filename copy];
rectInPixels_ = rect;
rect_ = CC_RECT_PIXELS_TO_POINTS( rect );
offsetInPixels_ = offset;
offset_ = CC_POINT_PIXELS_TO_POINTS( offsetInPixels_ );
originalSizeInPixels_ = originalSize;
originalSize_ = CC_SIZE_PIXELS_TO_POINTS( originalSizeInPixels_ );
rotated_ = rotated;
}
return self;
}
In such cases logging is your friend. Every time you create a CCAnimate action (or CCAnimation) you should log something like this:
// during 'create sprite frames from sprite frame names' loop
NSLog(#"adding sprite frame name for CCAnimate: %#", spriteFrameName);
// after CCAnimate was created
NSLog(#"creating CCAnimate %# with sprite frames: %#, animate, arrayOfSpriteFrames);
You will probably want to add more detail, like which sprite frame names were added to that CCAnimate. You may also have to add additional logging if you cache CCAnimations and reuse them later (log each CCAnimation when reused).
Now when you receive that error you should select the [CCSprite setDisplayFrame:] method in the call stack. The debugger will then show you the value for the CCSpriteFrame it wants to set. Look for the pointer value, it will read something like 0x254fb22e.
Search for that value in your log, this will bring you back to one of the "creating CCAnimate.." logs. From the log lines above you can see the sprite frame names it contains. Since you also logged the 'arrayOfSpriteFrames' you can get their pointer value, compare it with the pointer value of the CCSpriteFrame that caused the assertion.
When you have a match, and it's the fourth item in the sprite frame array, just look up the name of the fourth sprite frame name added to the CCAnimate.
There may be a quicker way to do this depending on which information is available in the debugger (and how well versed you are in debugging), but this is one approach that will definitely lead you to the offending sprite frame name in relatively short time.
Note that the pointer values are not unique - it's possible that a different CCAnimate was created with the same pointer value. Especially if there's a high frequence of CCAnimate playing and stopping it can happen that another CCAnimate is allocated at the exact same memory location of a previous one. So be wary if the results don't seem to match up. A quick way to find out is to test on different devices or Simulator vs. Device, as pointer values and allocation strategies vary.
You don't need to log which sprite frame name belongs to which texture atlas. Simply open the plist of each atlas and search for the sprite frame name. The plist is an XML file.
Tip: common cause for this problem can be having the same sprite frame name in two different texture atlases - cocos2d may use either texture when you request a sprite frame with a duplicate name.
Another Tip: if the logging seems daunting, I'd simply do the following:
open source code for CCSpriteFrame class
add a NSString* property 'filename' with 'copy' attribute
every time you create a CCSpriteFrame object, assign the filename to the CCSpriteFrame
Now whenever you see a CCSpriteFrame in the debugger, it'll show you the associated filename in the debugger view.
ok , looks like you have been there before ... Comment the first NSAssert, uncomment the if block. Then put a break point on the newly uncommented NSAssert. Execution will pause BEFORE the exception, and you should be to inspect the iVars of each class instance in the call stack (at least i can with AppCode, hope xCode allows that). Maybe you will get enough of a hint to figure out which texture/animation/batchnode is giving you a hard time.
Also ... fyi. Whenever i start a project with cocos2d (any version) , i apply some 'standard' fixes to it so that my life will be easier for debugging. A standard 'patch' is to add a name to CCNode, which i set to some meaningful value : always. Also i override the descpription method to return MY name. Assigning meaningful names has helped me many times, especially when walking down (or up) the node hierarchy to figure out a bug. I also nuke many of the NSAsserts and whenever possible (especially in ctors), return nil and log an error message. As per Stefen's suggestion, if a cocos2d ctor returns me a nil, i spew out an error log message. I can then break on that log statement and drill-down the issue.

Temporarily disable touch with CCLayerPanZoom

I've recently added the CCLayerPanZoom cocos2d extension to my project and got my game scene zooming and scrolling just like I want. Now when the player takes certain actions, I want to be able to disable the pan/zoom temporarily while they perform an action but can't figure out how to do it. I searched around and found the following code in a forum but it doesn't work or I don't know how to use it.
Does anyone know how to do this properly either with different code or the code below?
-(void)enableTouches:(BOOL)enable {
if(enable) {
[[CCTouchDispatcher sharedDispatcher] addStandardDelegate:self priority:0];
_panZoomLayer.isTouchEnabled = YES;
CCLOG(#"LayerPanZoom enabled.");
} else {
[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
_panZoomLayer.isTouchEnabled = NO;
CCLOG(#"LayerPanZoom disabled.");
}
}
I finally figured it out and figured I would post the answer back up here to share. The code I posted wasn't working because I was sending back self instead of the _panZoomLayer. So here are the steps to get this working yourself.
Implement the CCLayerPanZoom into your project as described by the documentation.
Add the following code as a method to call on your new CCLayerPanZoom class.
-(void)enableTouches:(BOOL)enable {
if(enable) {
[[CCTouchDispatcher sharedDispatcher] addStandardDelegate:_panZoomLayer priority:0];
CCLOG(#"LayerPanZoom enabled.");
} else {
[[CCTouchDispatcher sharedDispatcher] removeDelegate:_panZoomLayer];
CCLOG(#"LayerPanZoom disabled.");
}}
NOTE: Make sure to put the instance of the parent class as the delegate to remove.
In order to re-enable and have it function properly, you have to remove all the entries from the array in the CCLayerPanZoom class before calling to re-register the delegate. I created a new method in the CCLayerPanZoom class as follows and just call it right before the addStandardDelegate method above.
-(void)removeTouchesFromArray {
[self.touches removeAllObjects];
}
Then it all works great! Took me a while to learn how to use this extension but it works perfect once you figure it all out. I can single finger pan, double finger zoom/pan, set center location for entire scene, limit panning past edges, and set min/max scales. I know people have had a lot of issues with this but it is a great extension, just takes some messing around with to understand it. Let me know if you have any questions. Hope this helps someone else.

cocos2d -CCLabelTTF is not printing more then once

i am losing my mind !!
i have done this so many times and now its just not working !
in my init method i have this label :
teamLabel = [CCLabelTTF labelWithString:#"WAITING..." fontName:#"Marker Felt" fontSize:32];
teamLabel.position = ccp( 150,100);
teamLabel.color = ccc3(150, 50, 80);
[self addChild:teamLabel];
[teamLabel setVisible:YES];
then i call a function which i know it has been called(NSLOG) and there i am trying to print something in all kind of ways:
[teamLabel setString:#"ran"];
[teamLabel setString:[NSString stringWithFormat:#"%ig", (int) (ran)]]; //ran int==5;
the function is fired, but i can still see the first string from the init in my label without a change..
EDIT ::
it now prints a red big square which is in the size of my word. if the word is small i get small red square etc...
whats that ?!?
thanks .
I once came upon similar behavior, and it ended being due to lack of memory to allocate the TTF texture.
Perhaps you have been growing your game/app resource utilization and you are now seeing the same behavior.
Try disabling a number of these other resources, or create the TTF labels only. You can also try moving the creation of these TTFs out of the init method, to check whether there might be a load order/priority problem.
Cheers,