FAQ: cocos2d for iPhone: How do i find out if an Action has finished/stopped? Comments Feed" href="http://www.learn-cocos2d.com/knowledge-base/cocos2d-iphone-faq/feed/"/>

FAQ: cocos2d for iPhone: How do i find out if an Action has finished/stopped?

Search my cocos2d for iPhone FAQs & Tutorials

Please note that the blog search in the upper right corner doesn’t search my FAQs and Tutorials.
 

  • Note: please do not share direct download links to PDF files, the download links expire after a couple minutes!

You're running an action on a node and you want to know when that action is done. It could mean that the node has arrived somewhere, that time has elapsed, or something else entirely. You just need to know when that action has done its job - so how would you do this?

Download Lesson PDF

Defining the Problem

You are running a MoveBy action and want to know when that action has stopped.

Solution: CallFunc and Sequence

The solution is to use a CCSequence which runs both the MoveBy and once that is finished, runs the CCCallFunc which in turn will call the given selector.

You need the CCCallFunc and supply it with the target, in this case self (the enemy) but it can be any other object. The selector is a method that gets called when CCCallFunc is run. The CCSequence makes sure that the actions are run in sequence, it starts with the CCMoveBy action and when that is done, it will run the CCCallFunc action and then the CCSequence has done its job and is removed from the enemy's actions as well.

CCSequence takes a list of actions that it should run in sequence. It can be any number of actions so it is very useful to create longer chains of actions and thus create interesting behavior, especially for enemy AI. Don't forget that the last action in the list must always be nil!

Note: when you make this change don't forget to use sequence for [enemy runAction:sequence]

-(void) iHaveStopped

Just another function with the same name of the CCCallFunc selector. You can choose whatever name you want as long as you match the one for CCCallFunc.

Comments (0)

11 Responses to “FAQ: cocos2d for iPhone: How do i find out if an Action has finished/stopped?”

  1. Max says:

    Enlightening post. Thanks!

    And, of course, I have a few question :)

    - everything is relative, but for common code is better to use NSString, NSArray (and pay the cost of creating new objects) or the mutable ones? Which can be the parameters to choose between each one?

    - I am wondering if the new iPhone 4.0′s greater performance will be an issue. Games that run smoothly in iPhone 1st and 2nd generation devices will probably run too fast?

    • GamingHorror says:

      Hi Max,

      i doubt the NSMutable* datasets are performance killers. I haven’t made any tests but i’m pretty sure that if you don’t change them at all they’ll probably perform just as good as the non-mutable ones. Now, once you *do* need to change the arrays or strings it’s good to have them mutable so that stuff is taken care for you behind the scenes. On the other hand, if you know that you’ll only be creating the items once but never re-order, remove or add others then use the non-mutable ones. For me it’s a matter of use case rather than performance.

      Games won’t run faster on newer devices. cocos2d’s CCDirector makes sure of that. You do get better framerates of course but not faster gameplay. That holds true for all modern game engines.

  2. Sean says:

    Hi gaminghorror. Thanks for all the great info on your blog :) Really finding this useful.

    I wanted to ask about your parallax background code above - I am using this in a test project, but can’t seem to get the tiling to fit perfectly next to eachother. In other words, my sprite that I am tiling (which is 480, 320 in size) is tiling, but when the new sprite starts, there is a black gap about 25 pixels wide between the new and the old. Is there any way to elliminate this gap? I have tried searching the cocos2d forums etc, and found info on 2D projection turning off etc… but none of that has helped me so far… To try and illustrate what I am getting, this is what I get scrolling across the device screen (x’s are the sprite white space is the black gap I get):

    xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxxxxx| |xxxxxxx

    • GamingHorror says:

      This seems to be a placement offset, are you sure the sprites are exactly 480 pixels apart each? Both also need to have the same anchorPoint. And if you change the scale of the sprites, the offset also needs to be adjusted appropriately.
      You might want to test the placement with smaller sprites so that at least two of them fit entirely on the screen.

      • Sean says:

        Hi GamingHorror, thanks so much for the reply :) So this morning I woke up and had a clear mind - thought about it for a while- My sprite for the background is exactly 480×320 - i.e. screensize. The gap I was seeing kind of looked around 20-30 pixels between each repeated sprite. So I thought, hey, at 480, I am just being given a texture that is 512 in size right? So maybe its doing a full 512pixel texture. So I went back to photoshop, and increased my sprite width to 512 (as I wouldnt lose any performance anyway) and gave this a try, using your code:

        CCSprite *background = [CCSprite spriteWithFile:@"tile1.png"
        rect:CGRectMake(0,0, 480*50, 320)];
        [self addChild:background];
        [background setPosition:ccp(winSize.width/2,winSize.height/2)];
        ccTexParams params = {GL_LINEAR,GL_LINEAR,GL_REPEAT,GL_REPEAT};
        [background.texture setTexParameters:¶ms];

        and this sorted it out! No more gaps. Thanks so much for the pointers too - I hadn’t thought about anchorPoints! Thanks again for the great blog. I am subscribed!

  3. Sean says:

    So another quick question… I guess it won’t be possible to use a spritesheet with GL_REPEAT? Especially the way you need to create a CGRect…

    Currently I do other graphics from spritesheets like this:

    CCSprite *projectile = [CCSprite spriteWithSpriteFrameName:@"missile.png"];

    Which are loaded from my .plist / spritesheet. Not possible to assign the GL_REPEAT background like this?

    • Since GL_REPEAT is a texture parameter, it applies to the whole texture, so you’ll need to use a single image texture, and the size must be a power of 2, eg 128×16 or 256×256.

      That also rules out the spritesheet use.

  4. Mattis says:

    When using this technique it works well in the simulator, but on the device the texture is super-blocky and pixellated. I’m running this test on cocos2d 0.99.5.

    Ive tried with both 256×256 and 512×512 textures, and the result is the same. Simulator repeats perfectly, device stretches and pixellates the texture horribly.

    Do you have any idea why this happens?

Leave a Reply