RunAction анимация проблемы сбоя - чего не хватает - PullRequest
1 голос
/ 26 августа 2011

Нужна небольшая помощь с проблемой Cocos2d.

Я запускаю анимацию с одного и того же листа спрайта анимация при движении слева направо и вверх и вниз.

Iv'e попробовал несколько разных способов, чтобы это произошло, код ниже должен быть ближайшей версией, и он должен работать. Но теперь он просто падает (возможно, утечка памяти).

Код анимации, который я использую, изначально взят из великолепных учебников с блога http://www.raywenderlich.com.

Вот фрагмент кода, с которым я столкнулся. Кто-нибудь может дать мне какие-нибудь указания относительно того, чего не хватает?

ТНХ Richg

#import "HelloWorldScene.h"

// HelloWorld implementation
@implementation HelloWorld
@synthesize gameMan = _gameMan;
@synthesize moveAction = _moveAction;
@synthesize walkAction = _walkAction;
@synthesize walkAction2 = _walkAction2;


+(id) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];

// 'layer' is an autorelease object.
HelloWorld *layer = [HelloWorld node];

// add layer as a child to scene
[scene addChild: layer];

// return the scene
return scene;
}

// on "init" you need to initialize your instance
-(id) init
{

if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {

    [[CCSpriteFrameCache sharedSpriteFrameCache]    addSpriteFramesWithFile:@"gameMan.plist"];

    CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode   batchNodeWithFile:@"gameMan.png"];
    [self addChild:spriteSheet];

    //Loop thru frames and add a cache of the frames
    NSMutableArray *walkAnimFrames =[NSMutableArray array];
    for (int i = 1; i <= 4; ++i) {
        [walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
                                   [NSString stringWithFormat:@"Man%d.png", i]]];
    }

        CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];    



    NSMutableArray *walkAnimFrames2 =[NSMutableArray array];
    for (int i = 1; i <= 2; ++i) {
        [walkAnimFrames2 addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
                                   [NSString stringWithFormat:@"Man_up%d.png", i]]];

    }
    CCAnimation *walkAnim2 = [CCAnimation animationWithFrames:walkAnimFrames2 delay:0.1f];  



    //Create the sprite and run the animation                    
    CGSize winSize = [CCDirector sharedDirector].winSize;
    self.gameMan = [CCSprite spriteWithSpriteFrameName:@"Man1.png"];

    _gameMan.position = ccp(winSize.width/2, winSize.height/2);
    self.walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
    self.walkAction2 = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim2 restoreOriginalFrame:NO]];
    //[_Man runAction:_walkAction
    //[self addChild:spriteSheet];
    [spriteSheet addChild:_gameMan];

    self.isTouchEnabled = YES;

}
return self;
}

-(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 
                                           swallowsTouches:YES];
}

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
return YES;
}
//Methods for controlling the animation

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {  
//determine touch location  
CGPoint touchLocation = [touch locationInView: [touch view]];       
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
touchLocation = [self convertToNodeSpace:touchLocation];

//set velocity, time it takes for the sprite across the iPhone screen
float manVelocity = 480.0/4.0;
//figure out amount moved in X and Y
CGPoint moveDifference = ccpSub(touchLocation, _gameMan.position);
//Figure out actual length moved
float distanceToMove = ccpLength(moveDifference);
//Figure out how long move will take
float moveDuration = distanceToMove / manVelocity;
//if moving other direction, flip direction of sprite
if (moveDifference.x < 0) {
    _gameMan.flipX = YES;
} else {
    _gameMan.flipX = NO;
}

Это та часть, которая имеет значение --- здесь

if (abs(moveDifference.x) > abs(moveDifference.y)) {

    [_gameMan runAction:_walkAction];

else {

    [_gameMan runAction:_walkAction2];  
}

сюда!

[_gameMan stopAction:_moveAction];

if (!_moving) {
    [_gameMan runAction:_walkAction];
}


self.moveAction = [CCSequence actions:                          
                   [CCMoveTo actionWithDuration:moveDuration position:touchLocation],
                   [CCCallFunc actionWithTarget:self selector:@selector(manMoveEnded)],
                   nil];

[_gameMan runAction:_moveAction];   
_moving = TRUE;

}

-(void)manMoveEnded {
[_gameMan stopAction:_walkAction];
_moving = FALSE;

}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
self.gameMan = nil;
self.walkAction = nil;
self.walkAction2 = nil;

// don't forget to call "super dealloc"
[super dealloc];
}
@end

1 Ответ

0 голосов
/ 27 августа 2011

Вы должны остановить _walkAction и _walkAction2, прежде чем запускать их.

Завершение работы приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «runAction: действие уже выполняется»

Эта строка означает, что действие уже запущено, и cocos2d не может запустить его еще раз.Поэтому, прежде чем запускать каждое действие, вы должны быть уверены, что оно уже завершено, или остановить его.Исправление должно выглядеть следующим образом:

if (abs(moveDifference.x) > abs(moveDifference.y)) {
    [_gameMan stopAction:_walkAction];
    [_gameMan runAction:_walkAction];
else {
    [_gameMan stopAction:_walkAction2];
    [_gameMan runAction:_walkAction2];
}
...