How can I synchronize both movement and an animation using cocos2d? - iphone

I need help getting a CCSprite to animate and move in a synchronized fashion repeatedly. For example I need to move the sprite from one game board space to the next while walking. While I can call each action right after one another, I have found that when run in rapid succession the two don't fire at the same time causing either an additional animation cycle to run between moves or movements to not be aligned with the start/end of the animation.
Here are examples of how I'm creating the animation and movement actions.
CCAnimation *animRunUR_ = [CCAnimation animationWithFrame:#"actor_run_ur" frameCount:8 delay:runAnimDuration_];
CCAction *_actionAnimRunUR = [[CCSequence actions:
[CCAnimate actionWithAnimation:animRunUR_],
[CCCallFunc actionWithTarget:self selector:#selector(animationFinished)],
nil] retain];
CCAction *_action = [[CCSequence actions:
[CCMoveTo actionWithDuration:duration_ position:gridbox_.center],
[CCCallFunc actionWithTarget:self selector:#selector(nextMovement)],
nil] retain];
Each of the above actions are called directly on the CCSprite as follows.
[self.sprite runAction:_action];
[self.sprite runAction:_actionAnimRunUR];
The duration of the animation is calculated to be equal to the amount of time it takes to move to the next game board space. In addition, these are fairly straight forward actions but I'm really having a hard time keeping them synced as they continually repeat.
Any best practices or suggestions would be greatly appreciated as I'm sure this is a common issue in game development with sprites that continually animate while moving. Then trying to keep smooth transitions between things like walk, run, and jump without split second pauses between actions. Thanks for your feedback and suggestions.

Related

Replaying a Core Animation animation?

I was wondering, what if I want to replay an animation I have already added to the layer? Do I need to add the animation to the layer each and every time I want it to play, or there's a way to replay an animation I have already added?
Thanks,
iLyrical.
Once animation gets finished then to repeat animation u will have to add new animation like this:
[yourView.layer removeAllAnimations];
[yourView.layer addAnimation:yourAnimation forKey:#"Key here"];
You can configure the animation to repeat a certain number of times before it finishes using the repeatCount property but if you want to repeat an animation that has already finished you have to add it to the layer again.

How to add transition effect in Current running scene in cocos2d iphone

How to add transition effect in Current running scene in cocos2d iphone. Means I am making a game and after each goal I want to give a fade effect or any type of effect on the current running scene.
If I write this, It replace current scene to its new scene. But I don't want to replace scene.
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0f scene:[GamePage scene]]];
Is there some way to show effect on the current page like this. I know that it is wrong but I want something like this :
[self transitionEffect:[CCTransitionFade actionWithDuration:0.5]];
For Scene,Layer (Subclass of CCNode) action related to Opacity will not work. !
You can Either Use transition, or Must have to apply CCFadeTo to all of your sprite.
But If you are choosing to CCFadeTo to all sprites, this will require allocation of lots of actions suddenly ! FPS slow down !!
Another best approach:
Tell to your designer, to make 1 x 1 pixel Square black dot image.
Add this code at last in the init method.
CCSprite *temp=[CCSprite spriteWithFile:#"squaredotBlack.png"];
temp.position=ccp(s.w/2,s.h/2);
[self addChild:temp z:50000]; //set as most top layer
temp.scaleX=s.w;
temp.scaleY=s.h;
temp.opacity=0;
Then Apply, For "Fade out" process of whole screen, Increase the opacity.
temp.opacity=0;
[temp runAction:[CCFadeTo actionWithDuration:1 opacity:255]]; //0 to 255
Then Apply, For "Fade In" process of whole screen, decrease the opacity.
temp.opacity=255; // this will cover whole screen with black color
[temp runAction:[CCFadeTo actionWithDuration:1 opacity:0]]; //255 to 0
you can run an action on the entire CCLayer
[self runAction:[CCFadeOut actionWithDuration:0.5f]];
or you can use CCFadeTo to fade to a desired opacity.

cocos2d iphone wait for action to complete/finish

I'm trying to force an action to complete before another action can be called. I've looked all over for different examples of timing delays and CCSequencing and this is what i have so far, but it still isn't working. I need the full .5 to come out before another action (whether it be left, right or down) can be called. Everything is working as long as you don't hit the buttons before an action finishes, thats when the previous action is cut short.
-(void) moveup{
CCNode *mySprite = [self getChildByTag:kTagSprite];
//moves sprite up 30 pixels in 1/2 second
[mySprite runAction: [CCMoveTo actionWithDuration:.5 position:ccp(mySprite.position.x, mySprite.position.y+30)]];
}
//this is inside CCtouchesbegan. upsprite is a box that gets clicked to move the object up
if(CGRectContainsPoint([upsprite boundingBox], point)){
//should call CCSequence of events, method moveup, and then CCDelayTime, forcing a pause
[self runAction:[CCSequence actions:[CCCallFuncND actionWithTarget:self selector:#selector(moveup) data:nil], [CCDelayTime actionWithDuration:.5], nil]];
}
I've tried pausing using [[CCDirector sharedDirector] pause] but this freezes everything, including the sprite I'm moving. The CCDelayTime doesn't seem to be working in my current example.
I know this question is kind of a duplicate of a couple others about ccsequencing, so if it needs to be marked as a dupe, that's fine, but I'd really like some help as it's really holding me back.
You could make a BOOL "lock" variable, and only run the action on "mySprite" :
if(lock) {[mySprite runAction:...];}
set the BOOL lock to NO in the beginning and everytime you begin the action set it to "YES"...then add a CCCallFunc to the CCSequence to set the lock back to "NO"

Showing a frame when collision is detected (cocos2d iPhone)

I have a hero character all set up with a CCSpriteBatchNode, which has all the animation and frames. But I wonder, how do I display a frame when the hero is hit (I set up collision detection already). How do I make this happen? Do I put it inside the CCSpriteBatchNode? It's not part of moving, only for special occasions.
You can set your hero invisible ( [sprite setVisible: NO]) and show another sprite at the hero's position.
More then it, you can keep this sprite in your hero class object and provide a method which will change the visible sprite when collision happens. Something like this
-(void) onCollision
{
[heroMainSprite setVisible:NO];
[heroCollisionSprite setVisible:YES];
}
Such solution will also preserve all your logic, that has been done before.
When hero gets hit.. Change the texture..
[spr setTextureRect:CGRectMake(startX, startY, width, height)];
It needs to be in the same batch node as the rest of the animation..

Animate Train in iphone

I want to animate a 20 wagon train in iphone. The train will move left to right. Each wagon will have a different animation. I was confused how to do it. Because the images are large and 20 images at one time would cause memory warnings.
Can anyone suggest how to go about it. Should I use cocos2d for this?
Thanks!
I would do that in cocos2d.
I would create a 'Wagon'-class and then start by initiate two of them (just because I think that two wagons will fill the screen). And then start moving the wagons. Each time a wagon is completely out of the screen I would release it. When it's time for the next wagon I would initiate that and so on.
How many frames does the animations have, and how big are they? Maybe you'll have to make one atlas per wagon. You can always call:
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
and:
[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
Cocos2D is best!
Create sprites, set actions to it and IMHO!!!
If you want to do using UIImageViews, look for
UIImageView.animationImages
UIImageView.animationDuration
UIImageView.animationRepeatCount
and
[UIView beginAnimations:(NSString *)animationID context:(void *)context];
[UIView setAnimationDuration:(NSTimeInterval)duration]
// make the changes in your view which you want to occur in given duration
[UIView commitAnimations];
But again, this will definitely give you a hard time, better go for Cocos2D.