0

私のゲームでは、敵のためにCCSprite(cocos2d)のサブクラスを作成しました。このサブクラスのすべてのインスタンス内からアニメーションを制御したいので、敵をロードするメインクラスのアニメーションコードをこのサブクラスに変換する必要がありました。

これはかなり難しいと思いましたが....しばらくすると魔法のように機能し始めました。

残念ながら、このサブクラスでプロパティを作成して設定した後、奇妙なクラッシュが発生し始めました。彼らはcocosDenshionや私の敵のクラスとは関係のない他の場所にいるので、私のコードとネットで徹底的に調査した後、私はそのある種のデータ破損を確信しています、そして私はそれが理由でほぼ完全に確信しています私は敵のクラスを彼のアニメーションコードで完全に間違った方法で行いました。

正直なところ、私はもうここで何が起こっているのか、そしてこれが実際にどのように機能するのかについて頭を悩ませることさえできません:S...私は完全に立ち往生しています。どんな助けでも大歓迎です!

したがって、私の主な質問は次のようになります。CCSpriteサブクラスにアニメーションを実装する適切な方法は何ですか?/ここで何が間違っているのですか?

ここで私のコードを簡略化しました:(アニメーションを2秒ごとにトリガーして、使用方法を示します)

#import "cocos2d.h"

@interface Npc : CCSprite 
{
    CCAction *_runAnimation;
    NSString* name;
    int strength;
}

@property (nonatomic, retain) CCAction *runAnimation;
@property int strength;
@property (nonatomic, retain) NSString* name;

- (Npc*)loadAnimation;
- (void)animate;
@end

#import "Npc.h"

@implementation Npc

@synthesize runAnimation = _runAnimation;
@synthesize name;
@synthesize strength;

-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect
{
    if( (self=[super initWithTexture:texture rect:rect]))
    {
    }
    return self;
}

- (Npc*)loadAnimation
{

    int lastFrame = 11;
    NSString *creatureFile = @"vis 1";

    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:
     [NSString stringWithFormat:@"%@.plist", creatureFile]];
    CCSpriteBatchNode* sheet = [CCSpriteBatchNode batchNodeWithFile:
                                [NSString stringWithFormat:@"%@.png", creatureFile]];

    self = [Npc spriteWithTexture:sheet.texture];
    NSMutableArray* animFrames = [[NSMutableArray alloc] init];     

    for (int x = 0; x < lastFrame; x++) 
    {
        [animFrames addObject:
         [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
          [NSString stringWithFormat:@"%@ %d.png", creatureFile, x]]];              
    }

    CCAnimation* anim = [CCAnimation animationWithFrames: animFrames delay: 0.1];

    self.runAnimation = [CCAnimate actionWithAnimation:anim restoreOriginalFrame:NO];

    [self runAction:_runAnimation];

    return self;
}

- (void)animate
{
    [self runAction:self.runAnimation]; 
}

- (void)dealloc 
{
    [super dealloc];

    [name release];
}

@end

#import "HelloWorldLayer.h"
#import "Npc.h"

@implementation HelloWorldLayer

+(CCScene *) scene
{
    CCScene *scene = [CCScene node];
    HelloWorldLayer *layer = [HelloWorldLayer node];
    [scene addChild: layer];
    return scene;
}


-(id) init
{

if( (self=[super init])) 
{
    timer = 0; 

    creatureTemp = [Npc spriteWithFile:@"Icon.png"];
    creature = [creatureTemp loadAnimation];
    creature.position = ccp(100,100);
    [self addChild:creature];

    [self schedule:@selector(nextFrame:)];

}
return self;
}


- (void)nextFrame:(ccTime)dt
{
    timer += dt;
    if (timer > 2.)
    {
        [creature animate];
        timer = 0.;
    }
}

- (void) dealloc
{
    [super dealloc];
}
@end

- - - - - - - - - -編集 - - - - - - - - - -

Ray Wenderlichによるチュートリアルを使用してコードを変更しました:http ://www.raywenderlich.com/3888/how-to-create-a-game-like-tiny-wings-part-1

これは、あるべき姿にはるかに近いと思います。残念ながら、SimpleAudioEngine(私が正しく実装している)のiphone(シミュレーターではない)でまだクラッシュするので、私はまだ何か間違ったことをしています。

Npcクラスの上に:

@synthesize batchNode = _batchNode;

Npcクラスの初期化:

-(id) initNpc
{
    if( (self=[super initWithSpriteFrameName:@"vis 1 0.png"]))
    {
        _normalAnim = [[CCAnimation alloc] init];

        NSMutableArray* animFrames = [[NSMutableArray alloc] init]; 

        int lastFrame = 11;

        for (int x = 0; x < lastFrame; x++) 
        {
            [animFrames addObject:
             [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
              [NSString stringWithFormat:@"vis 1 %d.png", x]]]; 
        }

        _normalAnim = [CCAnimation animationWithFrames: animFrames delay: 0.1];
        self.runAnimation = [CCAnimate actionWithAnimation:_normalAnim restoreOriginalFrame:NO];


    }
    return self;
}

とHelloWorldLayerの初期化

-(id) init
{

    if( (self=[super init])) 
    {
        timer = 0; 


        _batchNode = [CCSpriteBatchNode batchNodeWithFile:@"vis 1.png"];
        [self addChild:_batchNode];
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"vis 1.plist"];

        creature = [[[Npc alloc] initNpc] autorelease];
        creature.position = ccp(200,200);

        [_batchNode addChild:creature];

        [self schedule:@selector(nextFrame:)];

        [[SimpleAudioEngine sharedEngine] preloadEffect:@"super1.mp3"];

    }
    return self;
}
4

2 に答える 2

2

loadAnimation で自己を再割り当てしています:

 self = [Npc spriteWithTexture:sheet.texture];

その時点で、私はコードを読むのをやめました。self は既に Npc クラスのインスタンスであるため、loadAnimation のような Npc インスタンス メソッドでこれを行う理由を自問する必要があります。

于 2012-08-10T13:52:43.413 に答える
0

だから、私はそれを手に入れました....ここにコードがあります:

Npc.h:

#import "cocos2d.h"

@interface Npc : CCSprite 
{
    CCAction *_runAnimation;

    CCAnimation *_normalAnim;
    CCAnimate *_normalAnimate;

}

@property (nonatomic, retain) CCAction *runAnimation;


- (void)animate;
- (id)initNpc;

@end

Npc.m

@synthesize runAnimation = _runAnimation;
@synthesize batchNode = _batchNode;

-(id) initNpc
{  
    if( (self=[super initWithSpriteFrameName:@"vis 1 0.png"]))
    {
        _normalAnim = [[CCAnimation alloc] init];        
        NSMutableArray* animFrames = [[NSMutableArray alloc] init];         
        int lastFrame = 7;        
        for (int x = 0; x < lastFrame; x++) 
        {
            [animFrames addObject:
             [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
              [NSString stringWithFormat:@"vis 1 %d.png", x]]]; 
        }        
        _normalAnim = [CCAnimation animationWithFrames: animFrames delay: 0.1];
        self.runAnimation = [CCAnimate actionWithAnimation:_normalAnim restoreOriginalFrame:NO];       
    }
    return self;
}

- (void)animate
{
    [self runAction:_runAnimation];
}

HelloWorldLayer.m で

-(id) init
{

    if( (self=[super init])) 
    {

        _batchNode = [CCSpriteBatchNode batchNodeWithFile:@"vis 1.png"];
        [self addChild:_batchNode];
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"vis 1.plist"];

        timer = 0; 

        creature = [[[Npc alloc] initNpc] autorelease];
        creature.position = ccp(200,200);

        [_batchNode addChild:creature];

        [self schedule:@selector(nextFrame:)];

    }
    return self;
}

- (void)nextFrame:(ccTime)dt
{
    timer += dt;
    if (timer > 2.)
    {
        [creature animate];
        timer = 0.;

    }
}

そして、cocosDension の奇妙なクラッシュについて。それも解決されました...それは、例外ブレークポイントがアクティブな場合にのみ例外をスローする、SimpleAudioEngine の既知のバグであることが判明しました。回避策: サウンドのクラスを作成し、例外ブレークポイントが必要な場合は、サウンドをコメントアウトします...

-- 言わざるを得ませんが、私は次のことを好みます。

_batchNode = [CCSpriteBatchNode batchNodeWithFile:@"vis 1.png"];
    [self addChild:_batchNode];
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"vis 1.plist"];

Npcクラスの内部ですが、それは私には高度すぎます。誰かがそれを知っているなら、私に知らせてください...実際に知って、おっとをよりよく理解するために素晴らしいでしょう. しかし、それは厳密には必要ではありません...

于 2012-08-24T01:35:41.203 に答える