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];
Related
I have a problem with using CCActionSequence in cocos2d v3.0 (iPhone, Objective-C).
I have created a label with some text. I want it to move up while fading out. After that, remove it from the scene. I created 3 actions: moveBy, Fade, and Remove. Looking at some tutorials on the web, I should be able to chain the actions together with a CCActionSequence. However, when I do this, all three actions run at the same time, essentially removing my label before the fade and move animations kick in.
CCLabelTTF *labelDP = [CCLabelTTF labelWithString:#"Double Points!" fontName:#"Helvetica" fontSize:16.0f];
labelDP.positionType = CCPositionTypeNormalized;
labelDP.position = ccp(0.5f,0.5f);
labelDP.color = [CCColor colorWithWhite:1.0f alpha:1.0f];
[self addChild:labelDP];
CCAction *actionMove = [CCActionMoveBy actionWithDuration:ALERT_FADE_DURATION position:ccp(0.0f, 40.0f)];
CCAction *actionFade = [CCActionFadeOut actionWithDuration:ALERT_FADE_DURATION];
CCAction *actionRemove = [CCActionRemove action];
[labelDP runAction:actionFade];
[labelDP runAction:[CCActionSequence actions:actionMove, actionRemove, nil]];
Is there a setting that makes these animations run in sequence instead of simultaneously? Because from all the tutorials I see, they seem to be able to achieve it with similar lines of code as the above.
Any help would be appreciated.
EDIT: ALERT_FADE_DURATION is a macro defined as 2.0f
I believe the problem is invoking runAction twice on the same node.
EDIT: As LearnCocos2D mentioned in the comments invoking runAction more then once should work as long as the actions are not interfering with each other (i.e. two move actions on the same node running in parallel) so it's either a behavioral change in version 3.x or maybe your ALERT_FADE_DURATION definition is too small (as noted in the comments as well)
Try using the CCActionSpawn action which can run actions in parallel on the same node :
CCAction *spawnAction = [CCActionSpawn actionWithArray:#[actionMove , actionFade]];
CCAction *sequenceAction = [CCActionSequence actionWithArray:#[spawnAction]];
[labelDP runAction:sequenceAction];
This should give you the desired effect. First move and fade the label and only then remove it from its parent node
Try with this:
CCAction *actionMove = [CCActionMoveBy actionWithDuration:ALERT_FADE_DURATION position:ccp(0.0f, 40.0f)];
CCAction *actionFade = [CCActionFadeOut actionWithDuration:ALERT_FADE_DURATION];
CCAction *actionRemove = [CCActionRemove action];
id seq = [CCActionSequence actions:actionMove, actionRemove, nil];
[labelDP runAction:[CCActionSpawn actions:actionFade, seq, nil]];
I'm using UIKit to create a simple game. In my game, I want the ball to completely stop moving if its upMovement is less than -4.
So it appears to freeze in mid air.
What I have is the following:
if (upMovement < -4) {
upMovement = 0;
ball.center = CGPointMake(ball.center.x, ball.center.y);
ball.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"fallingball.png"], nil];
[ball setAnimationRepeatCount:0];
ball.animationDuration = 1;
[ball startAnimating];
}
I thought by adding upMovement = 0; and ball.center = CGPointMake(ball.center.x, ball.center.y) it would freeze the ball as soon as the upMovement < -4 ? but instead it, just makes it move really slow.
Any reasons as to why?
If your ball view is animating because of an UIView animation block or similar, then
[ball.layer removeAllAnimations];
should remove that animation and freeze it in place.
If you're animating it in place by repeatedly changing its frame then you would just have to stop doing that.
I have a CCLayer class called SuccessLayer. It gets added to the scene when the level is complete, like so:
SuccessLayer *successLayer = [SuccessLayer node];
[self addChild:successLayer];
In SuccessLayer, I want to have a rock fly by, I'm trying to achieve that with this:
-(void)onEnter{
Asteroid *asteroid = [Asteroid spriteWithFile:#"rocks.png"];
asteroid.position = ccp(0, 500);
[self addChild:asteroid];
CCMoveTo *move = [CCMoveTo actionWithDuration:2.0 position:ccp(1000, 0)];
[asteroid runAction:move];}
However, it seems CCMoveTo isn't working. I see the sprite sitting at its initial coordinates, but nothing more. What am I missing here? Thanks
[super onEnter];
any coco's onSomething, you should super onSomething.
Sovled the problem by casting it as a CCSprite (is that the correct way to say it?)
CCSprite *asteroid = [Asteroid spriteWithFile:#"rocks.png"];
Asteroid is already a subclass of CCSprite, so I have no idea why this works, but it allows me to run actions on it now.
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];
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