0

私は Cocos2D をいじり始め、スプライト シートを使ってスプライト アニメーションを作成する方法を見つけました。

今、画面上を小さなロボットが歩き回っています。しかし、あるアニメーションを別のアニメーションにどのように配置できるか疑問に思っています。

たとえば、私のロボットには歩行アニメーションがあり、腕を別々に動かしたいと考えています。しかし、彼の肩は歩行中に上下し、腕は肩の位置に対して動くはずです。

私の歩行アニメーションには 5 つのスプライトがあり、9 つの異なる腕の位置があります。これで、9 つの腕の位置すべてについて、すべての歩行スプライトに腕を追加できました。しかし、そうすると、14 ではなく 45 の画像が表示されます。

4

1 に答える 1

0

それは良い質問です (最後に!)。

私がすることは、あなたのキャラクターを、それ自体でアニメート可能なさまざまなスプライトに分離することです (あなたはすでにこれを行っています)。

次に、そのアニメーションのフレームが表示されるたびに、腕のアニメーションの位置を変更するコード ブロックを実行して、肩と一致するようにします。

そのコード ブロックを実行するには、Cocos 1.1 以降が必要です。そこに CCAnimationFrame が追加されているためです。ただし、これらのフレームは NSNotification 経由でしかコードを実行できないため、フレームにブロックを設定できるように改善しました。そのブロックは、そのフレームが表示されるたびに実行されます。

CCAnimation.h を見つけて、CCAnimationFrame インターフェイスを次のように変更します。

typedef void(^FrameBlock)(CCSprite *sprite);

/** CCAnimationFrame
 A frame of the animation. It contains information like:
 - sprite frame name
 - # of delay units.
 - offset

 @since v1.1
 */
@interface CCAnimationFrame : NSObject <NSCopying>
{
    CCSpriteFrame* spriteFrame_;
    float delayUnits_;
    NSDictionary *userInfo_;

    FrameBlock frameBlock;
}
/** CCSpriteFrameName to be used */
@property (nonatomic, readwrite, retain) CCSpriteFrame* spriteFrame;

/**  how many units of time the frame takes */
@property (nonatomic, readwrite) float delayUnits;

/**  A CCAnimationFrameDisplayedNotification notification will be broadcasted when the frame is displayed with this dictionary as UserInfo. If UserInfo is nil, then no notification will be broadcasted. */
@property (nonatomic, readwrite, retain) NSDictionary *userInfo;

/**  If the block is not NULL, it will be executed when the frame becomes visible **/
@property (nonatomic, readwrite, copy) FrameBlock frameBlock;

/** initializes the animation frame with a spriteframe, number of delay units and a notification user info */
-(id) initWithSpriteFrame:(CCSpriteFrame*)spriteFrame delayUnits:(float)delayUnits userInfo:(NSDictionary*)userInfo;
-(id) initWithSpriteFrame:(CCSpriteFrame*)spriteFrame delayUnits:(float)delayUnits block:(FrameBlock)block;
@end

そして、CCAnimation.m を開いて、CCAnimationFrame の実装が次のようになっていることを確認します。

@implementation CCAnimationFrame

@synthesize spriteFrame = spriteFrame_, delayUnits = delayUnits_, userInfo=userInfo_;

@synthesize frameBlock;

-(id) initWithSpriteFrame:(CCSpriteFrame *)spriteFrame delayUnits:(float)delayUnits userInfo:(NSDictionary*)userInfo
{
    if( (self=[super init]) ) {
        self.spriteFrame = spriteFrame;
        self.delayUnits = delayUnits;
        self.userInfo = userInfo;
    }

    return self;
}

-(id) initWithSpriteFrame:(CCSpriteFrame*)spriteFrame delayUnits:(float)delayUnits block:(FrameBlock)block{
    self = [self initWithSpriteFrame:spriteFrame delayUnits:delayUnits userInfo:nil];
    if(self){
        [self setFrameBlock:block];
    }
    return self;
}

-(void) dealloc
{    
    CCLOGINFO( @"cocos2d: deallocing %@", self);

    [spriteFrame_ release];
    [userInfo_ release];

    [super dealloc];
}

-(id) copyWithZone: (NSZone*) zone
{
    CCAnimationFrame *copy = [[[self class] allocWithZone: zone] initWithSpriteFrame:[[spriteFrame_ copy] autorelease] delayUnits:delayUnits_ userInfo:[[userInfo_ copy] autorelease] ];
    return copy;
}

-(NSString*) description
{
    return [NSString stringWithFormat:@"<%@ = %08X | SpriteFrame = %08X, delayUnits = %0.2f >", [self class], self, spriteFrame_, delayUnits_ ];
}
@end

次に、アニメーション フレームを作成するときに、腕の位置を肩に合わせて設定するブロックをフレームに追加します。

お役に立てば幸いです。

于 2012-04-19T18:38:42.810 に答える