Perfectly Sync'd Animations?

Forums Programming cocos2d support (graphics engine) Perfectly Sync'd Animations?

This topic contains 10 replies, has 7 voices, and was last updated by  shadowhorst 2 years, 2 months ago.

Viewing 11 posts - 1 through 11 (of 11 total)
Author Posts
Author Posts
October 14, 2009 at 6:59 pm #217905

malphigian
@malphigian

I have a character in my game who is constructed from 6 AtlasSprites (and accompanying AtlasAnimations) layered on top of one another.

My problem is it does not seem to work consistently. The animations will frequently get “out of sync”, slightly off from one another so that it looks disjointed. Is there any way in the current system to make sure all my animation frames are in sync?

I can think of several ways to hack this in (e.g. drop the Animation action and create a separate timer which handles setting the animtion frames), but I want to make sure I’m not missing a simpler approach.

October 14, 2009 at 7:14 pm #263789

bradparks
Participant
@bradparks

This post talks about adding this feature to Cocos:

http://www.cocos2d-iphone.org/forum/topic/1713

In short, it’s in the works. If you really want this right now, then you could try using the code from zwoptex:

http://zwoptex.zwopple.com/zwoptex-code.zip

which is being merged to some extent with the cocos code sometime soon… It does a frame base animation system, more like flash.

October 14, 2009 at 9:34 pm #263790

PhilM
Participant
@philm

How long are your animations running?

I have a repeat forever animation running on custom characters currently made up of 2 atlas sprites.

As long as I preload the actions/animations they ‘seem’ to stay in sync so far, although I haven’t tested it extensively yet, and am planing to add one or 2 more atlas sprites into the mix, so may still come across your issue.

I had thought about doing it through a custom set frame schedule like you mention malphigian if I need this functionality before the zwoptex code has been integrated as bradparks says.

October 16, 2009 at 6:04 pm #263791

malphigian
@malphigian

bradparks: thanks for the link, the zwopple code appears to be working pretty well so far.

However, for some reason it seems to have globally changed the way my PNGs are handled. Looks like glDisable(GL_BLEND); is called by ZWAtlasFrame, commenting this out fixed the issue (and hopefully didn’t cause some other problem I’m not seeing).

October 16, 2009 at 6:23 pm #263792

bradparks
Participant
@bradparks

hey… thanks for letting us know about the glDisable(GL_BLEND) thing… I have yet to actually add animations to my game as I’m working on other things, and when I get to it, i’m sure that’ll be nice to know ;-)

February 28, 2010 at 8:35 pm #263793

MancingDols
@mancingdols

Hi everyone !

I’m quite new to Cocos2D and I’m trying to get two animations to be perfectly synchronised, like the original purpose of this thread.

I read the post given by bradparks, but as I understand it, it doesn’t end up with a way of syncing animations, but with a way of optimising their drawing. Am I wrong ?

If not, is there a way in Cocos to force animations to be perfectly synced, or does it need some additional development ?

Thanks for your help !

March 1, 2010 at 3:56 pm #263794

shadaz
Participant
@shadaz

I originally had issues with syncing animations. If you run 2 or more separate animate actions they will never be in sync. There is a way but you have to change the frames manually at the same time using your own timer. I put an example of sync’ing actions (same idea) in this thread.

http://www.cocos2d-iphone.org/forum/topic/4619

March 1, 2010 at 5:45 pm #263795

MancingDols
@mancingdols

Thanks shadaz :) !

I resolve this by creating a custom CCAction (called CCSyncAnimates). It works perfectly well and I do keep all the advantages of the CCActions (sequencing, …).

March 2, 2010 at 2:56 am #263796

CJ
Moderator
@wiseganesha

@MancingDols can you elaborate on your implementation of CCSyncAnimates to help the rest of us out?

March 3, 2010 at 7:52 pm #263797

MancingDols
@mancingdols

Yes, of course, I can even show you the code :

#import "RA_CCSyncedAnimates.h"

@implementation RA_CCSyncedAnimates

@synthesize animationMaster = animationMaster_;
@synthesize animationSlave = animationSlave_;
@synthesize targetSlave = targetSlave_;

+(id) actionWithDuration:(ccTime)duration animationMaster:(id<CCAnimationProtocol>)animMaster animationSlave:(id<CCAnimationProtocol>)animSlave targetSlave:(id)targetSlave
{
return [[[self alloc] initWithDuration:duration animationMaster:animMaster animationSlave:animSlave targetSlave:targetSlave] autorelease];
}

-(id) initWithDuration:(ccTime)Duration animationMaster:(id<CCAnimationProtocol>)animMaster animationSlave:(id<CCAnimationProtocol>)animSlave targetSlave:(id)targetSlave
{
NSAssert( animMaster!=nil, @"Animate: argument animMaster must be non-nil");
NSAssert( animSlave!=nil, @"Animate: argument animSlave must be non-nil");
NSAssert( targetSlave!=nil, @"Animate: argument targetSlave must be non-nil");

#ifdef COCOS2D_DEBUG
NSArray *framesMaster = [animMaster frames];
NSUInteger numberOfMasterFrames = [framesMaster count];
NSArray *framesSlave = [animSlave frames];
NSUInteger numberOfSlaveFrames = [framesSlave count];
NSAssert(numberOfMasterFrames == numberOfSlaveFrames, @"Trying to sync 2 animations with different frame number");
#endif //COCOS2D_DEBUG

if( (self=[super initWithDuration:Duration] ) )
{
self.animationMaster = animMaster;
self.animationSlave = animSlave;
targetSlave_ = targetSlave;
}
return self;
}

-(id) copyWithZone: (NSZone*) zone
{
return [[[self class] allocWithZone: zone] initWithDuration:duration animationMaster:animationMaster_ animationSlave:animationSlave_ targetSlave:targetSlave_];
}

-(void) dealloc
{
[animationMaster_ release];
[animationSlave_ release];
[super dealloc];
}

-(void) startWithTarget:(id)aTarget
{
[super startWithTarget:aTarget];
}

-(void) stop
{
[super stop];
}

-(void) update: (ccTime) t
{
NSUInteger idx=0;

NSArray *framesMaster = [animationMaster_ frames];
NSUInteger numberOfMasterFrames = [framesMaster count];
NSArray *framesSlave = [animationSlave_ frames];
#ifdef COCOS2D_DEBUG
NSUInteger numberOfSlaveFrames = [framesSlave count];
NSAssert(numberOfMasterFrames == numberOfSlaveFrames, @"update : Trying to sync 2 animations with different frame number");
#endif //COCOS2D_DEBUG
ccTime slice = 1.0f / numberOfMasterFrames;

if(t !=0 )
idx = t/ slice;

if( idx >= numberOfMasterFrames ) {
idx = numberOfMasterFrames -1;
}
id<CCFrameProtocol> spriteMaster = (id<CCFrameProtocol>) target;
id<CCFrameProtocol> spriteSlave = (id<CCFrameProtocol>) targetSlave_;
if (! [spriteMaster isFrameDisplayed: [framesMaster objectAtIndex: idx]] ) {
[spriteMaster setDisplayFrame: [framesMaster objectAtIndex:idx]];
[spriteSlave setDisplayFrame: [framesSlave objectAtIndex:idx]];
}
}

/*- (CCIntervalAction *) reverse
{
NSArray *oldArray = [animation_ frames];
NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:[oldArray count]];
NSEnumerator *enumerator = [oldArray reverseObjectEnumerator];
for (id element in enumerator) {
[newArray addObject:element copy] autorelease;
}

CCAnimation *newAnim = [CCAnimation animationWithName:animation_.name delay:animation_.delay frames:newArray];
return [[self class] actionWithDuration:duration animation:newAnim restoreOriginalFrame:restoreOriginalFrame];
}*/

@end

It’s based on CCAnimate of course, and it’s a rough implementation that suits my need only (sync of only 2 animations, no reverse, not very safe handling of the second target, …)

If you have any question about it, feel free to ask :).

February 15, 2012 at 3:32 pm #263798

shadowhorst
@shadowhorst

I know this topic is quite old, but I came across the same issue a few days ago. Here is my updated class based on the code posted by MancingDols. Btw, thanks for this great work.

http://helpfactory.wordpress.com/?p=246&preview=true

Viewing 11 posts - 1 through 11 (of 11 total)

You must be logged in to reply to this topic.