Permalink
Browse files

add CCParticleSystemAnimation class

  • Loading branch information...
alanf committed Apr 22, 2011
1 parent ffb1108 commit 7a3ce1db103cca328437cc1e645738c770c038a2
Showing with 102 additions and 0 deletions.
  1. +45 −0 cocos2d/CCParticleSystemAnimation.h
  2. +57 −0 cocos2d/CCParticleSystemAnimation.m
@@ -0,0 +1,45 @@
+/*
+ * cocos2d for iPhone: http://www.cocos2d-iphone.org
+ *
+ * Copyright (c) 2011 Alan Fineberg (alan@pocketgems.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#import "CCParticleSystemQuad.h"
+#import "CCAnimation.h"
+
+/** CCParticleSystemAnimation is a subclass of CCParticleSystemQuad
+
+ It includes all the features of ParticleSystemQuad.
+
+ Special features and Limitations:
+ - The particle quads may be animated using CCAnimation
+ @since v0.xx
+ */
+@interface CCParticleSystemAnimation : CCParticleSystemQuad {
+ CCAnimation *animation_;
+}
+
+/** Sets a new animation for the particles.
+ @since v0.xxx
+ */
+-(void) setAnimation:(CCAnimation *)animation;
+@end
@@ -0,0 +1,57 @@
+/*
+ * cocos2d for iPhone: http://www.cocos2d-iphone.org
+ *
+ * Copyright (c) 2011 Alan Fineberg (alan@pocketgems.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#import "CCParticleSystemAnimation.h"
+
+@implementation CCParticleSystemAnimation
+
+-(void) dealloc
+{
+ [animation_ release];
+ [super dealloc];
+}
+
+-(void) setAnimation:(CCAnimation *)animation {
+ animation_ = animation;
+ [animation_ retain];
+}
+
+-(void) update: (ccTime) dt
+{
+ if ( active && emissionRate && [animation_ frames] ) {
+ NSArray *frames = [animation_ frames];
+ NSUInteger numberOfFrames = [frames count];
+
+ NSUInteger idx = dt * numberOfFrames;
+
+ if( idx >= numberOfFrames )
+ idx = numberOfFrames -1;
+
+ [self setDisplayFrame:[frames objectAtIndex:idx]];
+ }
+ [super update:dt];
+}
+@end
+
+

3 comments on commit 7a3ce1d

Hello,

Thank you for posting this class. I am using Cocos2d-iPhone r1.0 and am having difficulty using this class.
In the CCParticleSystemAnimation update method, the (ccTime) dt does not change very much between calls. From stepping through the code and comparing it, it looks like you based the update function off of CCAnimate update method. However, the method that calls the CCParticleSystemAnimation update method is the CCScheduler tick: method. What is required to properly setup a CCParticleSystemAnimation object?
It appears to be that you initialize it, create a CCAnimation object, and then call the setAnimation method, and should be good to go, but like this, I never get a frame past index 1 displayed.

excerpt from CCScheduler tick: that calls CCParticleSystemAnimation update :
// updates with priority > 0
DL_FOREACH_SAFE( updatesPos, entry, tmp ) {
if( ! entry->paused && !entry->markedForDeletion )
entry->impMethod( entry->target, updateSelector, dt );
}

CCActionInterval step method that calls CCAnimate update method
-(void) step: (ccTime) dt
{
if( firstTick_ ) {
firstTick_ = NO;
elapsed_ = 0;
} else
elapsed_ += dt;

[self update: MIN(1, elapsed_/duration_)];

}

CCAnimate update method
-(void) update: (ccTime) t
{
NSArray *frames = [animation_ frames];
NSUInteger numberOfFrames = [frames count];

NSUInteger idx = t * numberOfFrames;

if( idx >= numberOfFrames )
    idx = numberOfFrames -1;

CCSprite *sprite = target_;
if (! [sprite isFrameDisplayed: [frames objectAtIndex: idx]] )
    [sprite setDisplayFrame: [frames objectAtIndex:idx]];

}

Thank you for any help with this.

-Seth

Owner

alanf replied Apr 18, 2012

Hi Seth,

Thanks for pointing this out. Looking at it now, it does seem incorrect. To get the correct behavior, I would modify the class to:

  • store the current frame idx
  • accumulate the dt at each update (t += dt)
  • when the accumulated dt >= the CCAnimation delay, increment the current frame idx while subtracting delay from t. Increment idx until the number of elapsed frames*delay > t (i.e. take into account that we may need to skip frames).
  • set the display frame to the current frame

Hi Alan, thanks for your help with this class! I am having some confusion with the 3rd step you gave me. Below is what I implemented, but the index increments do not make sense, and it does not work (I used elapsed_ like in CCActionInterval instead of "t" and made a repeat BOOL because I want the animation to repeat over and over until the particle dies) :

  • (void) update: (ccTime) dt
    {
    elapsed_ += dt;

    if ( active && emissionRate && [animation_ frames] ) {
    NSArray *frames = [animation_ frames];
    NSUInteger numberOfFrames = [frames count];

    if (elapsed_ >= [animation_ delay]) 
    {            
        float dur = frameIdx*[animation_ delay] ; 
        if (dur < elapsed_) 
        {
            frameIdx ++ ;
        }
        else if (repeat)
        {
            frameIdx = 0 ;
            elapsed_ = 0.0f ;
        }
    
        elapsed_ -= [animation_ delay] ;
    
        [self setDisplayFrame: [frames objectAtIndex:frameIdx]];
    }
    

    }

    [super update:dt];

}

Please sign in to comment.