开发者

runAction animation crash problem - what's missing

开发者 https://www.devze.com 2023-03-31 09:13 出处:网络
Need a little help with a Cocos2d problem. I am running a animations from the same sprite sheet and need the sprite to play a different

Need a little help with a Cocos2d problem.

I am running a animations from the same sprite sheet and need the sprite to play a different animation when it is moving left to right and, up and down.

Iv'e tried a few different methods to get this to happen, the code below should be the nearest version, and it should work. But, it just crashes now (probably a memory leak).

The animation code I'm using originally comes from the great tutorials from the http://www.raywenderlich.com blog site.

Here is the snippet of code that I am having crashed with. Can anyone give me any pointers as to what is missing?

thx Richg

#import "HelloWorldSce开发者_开发知识库ne.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;
}

This is the part that matters --- between here

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

    [_gameMan runAction:_walkAction];

else {

    [_gameMan runAction:_walkAction2];  
}

to here!

[_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


You have to stop the _walkAction and the _walkAction2 before to run them.

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'runAction: Action already running'

This line means that the action is already running and cocos2d can't run it one more time. So before to run each action, you have to be sure that it's already finished or stop it. The fix should look like this:

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

精彩评论

暂无评论...
验证码 换一张
取 消