animated sprite won't stop animation - cocos2d - ios

I have an animated sprite using two pngs. The animation works fine. I have another method that is run when the game is over.
//Grey mouse with Pompom
greyMousePomPom = [CCSprite spriteWithFile:#"pink_mice_pom_anime_01.png"];
greyMousePomPom.tag=132;
[self addChild:greyMousePomPom z:6];
greyMousePomPom.position = CGPointMake(550, 70);
//Grey Pom Pom Mouse animation
CCAnimation *greyMousePomPomAnimate = [CCAnimation animation];
[greyMousePomPomAnimate addFrameWithFilename:#"gray_mice_pom_anime_01.png"];
[greyMousePomPomAnimate addFrameWithFilename:#"gray_mice_pom_anime_02.png"];
id greyMousePopPomAnimationAction = [CCAnimate actionWithDuration:1.3f animation:greyMousePomPomAnimate restoreOriginalFrame:NO];
repeatAnimationPomPom2 = [CCRepeatForever actionWithAction:greyMousePopPomAnimationAction];
[greyMousePomPom runAction:repeatAnimationPomPom2];
When I run my method to change the animated sprites texture and to stop them the animation continues behind the new texture.
-(void) changePomPomMiceToSadFaceForFreeFall
{
NSLog(#"making the mice sad");
[self stopAllActions];
[greyMousePomPom setTexture:[[CCTextureCache sharedTextureCache] addImage:#"gray_mice_pom_anime_03.png"]];
}
I know this method is working because it is NSLogging and the textures are changing. But why aren't the animations stopping? I have tried to remove it by tag and by declaring the action but no success.
I know there are a lot of people out there that are smarter than me.. can you help?

What you're doing right now is stop all animations added to the current node:
self
If you added any action to self, this command would be perfectly fine to stop all of them.
Instead what you need to do is, you need to call the stopAllActions method on the object you added the actions to:
[greyMousePomPom stopAllActions];
HTH

Related

Stop Sprite Animation in cocos2d

This is the code to show sprite sheet animation if something happens in the game, animation works perfect but it is not stopping after the animation frames sequence complete, i had done so many things to stop the animation, but nothing is giving me solution, here is my code
if(m_bEffectChangeColor){
`
m_gamecoinffect = [CCSprite spriteWithSpriteFrameName:#"powerup0001"];
[self addChild:m_gamecoinffect z:3];
CCAnimate *coineffect = [CCAnimate actionWithSpriteSequence:#"powerup%04d" numFrames:30 delay:0.1f restoreOriginalFrame:NO];
[m_gamecoinffect runAction:[CCRepeatForever actionWithAction:coineffect]];
m_gamecoinffect.position = ptEffectPos;
CCCallBlock *block = [CCCallBlock actionWithBlock:^{
//[m_gamecoinffect stopAllActions];
[self removeChild:m_gamecoinffect cleanup:YES];
}];
CCDelayTime *time = [CCDelayTime actionWithDuration:1];
[m_gamecoinffect runAction:[CCSequence actions:time, block, nil]];
`
Above code i tried to add timer and everything i know, but nothing is working,,, i would like to stop animation and remove those sprite from the layer.
Thanks in advance.
The animation does not stop because the CCRepeatForever is the action which animates forever means continuously. Change below line:
[m_gamecoinffect runAction:[CCRepeatForever actionWithAction:coineffect]];
With
[m_gamecoinffect runAction:coineffect];

CCActionRemove / addChild is not being manifested consistently in scheduled method

Please bear with me because I'm very new to OOP/ObjC/Cocos2d.
I have a method that is triggered every second like so: [self schedule:#selector(eyelidsBlink:) interval:1.0];
The schedule method is this:
-(CCTimer *) schedule:(SEL)selector interval:(CCTime)interval
{
return [self schedule:selector interval:interval repeat:CCTimerRepeatForever delay:interval];
}
The method is below:
- (void)eyelidsBlink:(CCTime)dt{
CCActionRemove *actionRemoveEyelidsNormal = [CCActionRemove action];
[_whiteGuy_EyelidsNormal runAction:actionRemoveEyelidsNormal];
_whiteGuy_EyelidsBlink = [CCSprite spriteWithImageNamed:#"EyelidsBlink_iPhone4.png"];
_whiteGuy_EyelidsBlink.position = ccp(self.contentSize.width/2,self.contentSize.height/2);
[_whiteGuy_EyelidsBlink setScale:0.5];
[self addChild:_whiteGuy_EyelidsBlink];
CCActionRemove *remove_eyelidsBlink = [CCActionRemove action];
[_whiteGuy_EyelidsBlink runAction:remove_eyelidsBlink];
NSLog(#"Eyelids blinked");
_whiteGuy_EyelidsNormal = [CCSprite spriteWithImageNamed:#"EyelidsNormal_iPhone4.png"];
_whiteGuy_EyelidsNormal.position = ccp(self.contentSize.width/2,self.contentSize.height/2);
[_whiteGuy_EyelidsNormal setScale:0.5];
[self addChild:_whiteGuy_EyelidsNormal];
}
I can see the first blink, but I can't see any others after that. My NSLog is printing in the console every second, so I know the eyelidsBlink method is being called.
Can anyone help me figure out why I can't see any blinks after the first? Let me know if you need more information, or if you can suggest any tests to troubleshoot.
There's practically no time for the blink sprite to be rendered because you remove it the instant it was added. You'd have to schedule another selector once, ie eyeLidsBlinkOff that runs 0.1 seconds later and hides the blink sprite.
Note: This code is very inefficient. Creating sprites is a relatively slow operation. Instead keep both sprites as children but set one sprite's visible property to NO. While blinking simply flip each sprite's visible flag. This will make the code a lot shorter too.

iOS Cocos3D adding .pod files outside initializeScene method

#All Hello,
I am trying to add and display .pod files outside initializeScene method. I can add them and display them properly inside initializeScene method but i need to show some of the .pod files dynamically after initializing scene.
I checked there is method onOpen but i tried adding there but it does not show up.
I am trying with below methods:-
-(void) initializeScene {
_autoRotate = TRUE;
[self setTouchEnabled:YES];
// Create the camera, place it back a bit, and add it to the scene
cam = [CC3Camera nodeWithName: #"Camera"];
cam.location = cc3v( 0.0, 0.0, 8.0 );
_cameraAngle = M_PI / 2.0f;
_cameraAngleY = M_PI / 2.0f;
_cameraHeight = INIT_VIEW_HEIGHT;
_cameraDistance = INIT_VIEW_DISTANCE;
_swipeSpeed = 0.0f;
[self addChild: cam];
// Create a light, place it back and to the left at a specific
// position (not just directional lighting), and add it to the scene
CC3Light* lamp = [CC3Light nodeWithName: #"Lamp"];
lamp.location = cc3v( -2.0, 0.0, 0.0 );
lamp.isDirectionalOnly = NO;
[cam addChild: lamp];
[self createGLBuffers];
[self releaseRedundantContent];
[self selectShaderPrograms];
[self createBoundingVolumes];
LogInfo(#"The structure of this scene is: %#", [self structureDescription]);
// ------------------------------------------
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
-(void) onOpen {
[self.viewSurfaceManager.backgrounder runBlock: ^{
[self addSceneContentAsynchronously];
}];
}
-(void) addSceneContentAsynchronously {
[self addContentFromPODFile:#"myObject.pod" withName:#"Mesh1"];
CC3MeshNode *meshNode = (CC3MeshNode *) [self getNodeNamed:#"Mesh1"];
[self addChild:meshNode];
self.activeCamera.target = meshNode;
self.activeCamera.shouldTrackTarget = YES;
[self.activeCamera moveWithDuration: 0.5 toShowAllOf: self withPadding: 2.5f];
}
I have .pod models separately so i just need to add them into scene and show them in camera. But asynchronously and dynamically.
Also if i add .pod files in initializeScene method it all works fine.
In cocos3d, when you load assets on the background thread, each occurrence of the addChild: method actually dispatches back from the background thread to the rendering thread to actually add the node to its parent.
The reason for this is to synchronize the thread activity, specifically, to avoid the new node being added into the node structure while the renderer is iterating that same structure to draw the nodes. Review the implementation of the CC3Node addChild: method if you want to see the ugly details.
Because of this double-dispatch, in your addSceneContentAsynchronously implementation, your node has probably not actually been added to the scene yet when the moveWithDuration:toShowAllOf:withPadding: runs.
The moveWithDuration:toShowAllOf:withPadding: method surveys the scene once, at the beginning of the method, to determine where the camera should move to. So, the result is that the camera likely doesn't know of the existence of your newly added node when it performs that survey.
You can likely resolve this by placing a short sleep into the background thread just before invoking moveWithDuration:toShowAllOf:withPadding:.
[NSThread sleepForTimeInterval: 0.1];
Another option would be to override the addChildNow: method in your custom CC3Scene implementation, so that it invokes the superclass implementation, and then moves the camera. The addChildNow: method is what runs on the rendering thread, as a result of the double-dispatch, to actually add the node to its parent.
However, that might get cumbersome if you're adding a lot of content to your scene, as it will cause the camera to bounce around each time something new is added. But then again, maybe that will make sense in your app.

CocosBuilder Animations not running

I'm creating a simple animation with CocosBuilder that just moves a CCLayerColor from top right to bottom left and for some reason the animations will not perform. I have the timeline set to auto play and over a duration of 2 seconds. I have a class that splits up all layers and then adds those layers to a CCScrollLayer. I'm just wondering if the problem is when i remove the layers from the scene and add then to the CCScrollLayer that the animations are removed and in turn not performed.
CCScene* scene = [CCBReader sceneWithNodeGraphFromFile:#"Untitled.ccbi"];
self.scrollLayer = [[CCScrollLayer alloc] init];
CCLayer* child = [[scene children] objectAtIndex:0];
for (CCNode* layer in [child children]) {
[layer removeFromParent];
[self.scrollLayer addChild:layer];
[layer resumeSchedulerAndActions];
}
[self.scrollLayer updatePages];
self.scrollLayer.delegate = self;
[self addChild:self.scrollLayer];
I can see the CCLayerColor object added to the screen but its just not animating.
i've added some custom code to the CCScrollLayer to deal with the situation but i'm just confused as to why the animations are not performing. any help would be great!
EDIT: Maybe a better question would be in CocosBuilder are the actions on the timeline directly linked to the object performing the action or somehow linked through the scene to that object?
Perhaps you forgot to add the scrollLayer as child?
[self addChild:self.scrollLayer];
In the sample code the node created from a ccbi is not referenced either. Maybe you aren't actually using it?

background image is not properly scrolling in cocos2d

I write the code for scrolling image in background of game. Simply define two sprite and set their position.
CGSize screenSize=[[CCDirector sharedDirector]winSize];
sky1 = [CCSprite spriteWithFile:#"sky1.png"];
sky1.position=ccp(screenSize.width/2, screenSize.height/2);
[self addChild:sky1];
CCLOG(#"sky1 position width=%f height=%f",sky1.position.x,sky1.position.y);
sky2=[CCSprite spriteWithFile:#"sky2.png"];
sky2.position=ccp(screenSize.width/2, sky1.position.y+sky1.contentSize.height/2+sky2.contentSize.height/2);
[self addChild:sky2];
[self schedule:#selector(scroll:) interval:0.01f];
And write the code for scrolling in scroll method:
-(void)scroll:(ccTime)delta{
CGSize screen=[[CCDirector sharedDirector] winSize];
CCLOG(#"come from schedule method pos.y=%f",sky1.position.y);
sky1.position=ccp(sky1.position.x, sky1.position.y-1);
sky2.position=ccp(sky2.position.x, sky2.position.y-1);
if(sky1.position.y <= -([sky1 boundingBox].size.height));
{
sky1.position=ccp(sky1.position.x, sky2.position.y+[sky2 boundingBox].size.height);
CCLOG(#"COMING IN first ifin scroll mwthod position width=%f pos.y=%f",sky1.position.x,sky1.position.y);
}
if(sky2.position.y<= -[sky2 boundingBox].size.height);
{
sky2.position=ccp(sky2.position.x, sky1.position.y+[sky1 boundingBox].size.height);
CCLOG(#"coming in secnond if ");
}
}
When I remove the if conditions then it works properly for one time. I don't know what is wrong with my condition and what the hell is going on with my code.
Can anybody explain?
I'm not too sure why your code isn't working properly. One thought that pops in my head is your interval may be too short. In other words, 0.01f (1/100) is shorter than your game update speed which is most likely 0.016 (1/60). So first thing I would try is tweaking your interval to maybe 0.02f. You could also drop the interval argument from the schedule call so it just runs once every frame. I would also try dropping the ccTime argument since it isn't being used.
[self schedule:#selector(scroll)];
-(void)scroll {}
But besides all that, this is probably best handled using CCActions. This looks like a simple pair of CCMoveTo actions combined with a CCRepeatForever to get the effect you want. This is the way I would go.
EDIT: here is a bit more detail about using CCActions to accomplish this. There are multiple ways of doing the same thing, but here is one you could try:
float moveDuration = 3; // or however fast you want it to scroll
CGPoint initialPosition = ccp(screenSize.width/2, screenSize.height/2);
CGPoint dp = ccp(0, -1*sky1.contentSize.height); // how far you want it to scroll down
CCMoveBy *scrollSky1 = [CCMoveBy actionWithDuration:moveDuration position:dp];
CCMoveTo *resetSky1 = [CCMoveTo actionWithDuration:0 position:initialPosition];
CCSequence *sequence = [CCSequence actionOne:scrollSky1 two:resetSky1];
CCRepeatForever *repeat = [CCRepeatForever actionWithAction:sequence];
[sky1 runAction:repeat];

Resources