Как остановить ранее запущенную анимацию в Cocos2d

#iphone #objective-c #cocos2d-iphone

#iPhone #objective-c #cocos2d-iphone

Вопрос:

Я создаю игру с использованием cocos2d.

Я перемещаю спрайты, применяя действие CCRepeatForever в методе ccTouchBegan, и когда спрайт сталкивается с другим спрайтом, анимация столкновения выполняется в методе ccTouchMoved.У меня возникли проблемы с остановкой анимации по окончании столкновения — я останавливаю ее с помощью stopAction, но она не работает.

Это код, который я использую:

 - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {    
    [selSprite resumeSchedulerAndActions];
    CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
    [self selectSpriteForTouch:touchLocation];   
    return TRUE;    
}

- (void)selectSpriteForTouch:(CGPoint)touchLocation 
{
    else if(selSprite==FuelTruck) 
    {
        NSMutableArray *FuelTruckWalkAnimFrames = [NSMutableArray array];
        for(int i = FuelTruckTouchStartFrameIndex; i <= FuelTruckTouchEndFrameIndex;   i) {
            [FuelTruckWalkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"ftruck_move_%d.png", i]]];
        }
        FuelTruckWalkAnim = [CCAnimation animationWithFrames:FuelTruckWalkAnimFrames delay:FuelTruckTouchFrameDelay];
        walkFuelTruck = [CCRepeatForever actionWithAction:
                            [CCAnimate actionWithAnimation:FuelTruckWalkAnim restoreOriginalFrame:YES]];
        [selSprite runAction:walkFuelTruck]; 
    }
}

- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event {    

    else if(CGRectIntersectsRect(selSprite.boundingBox,BluePlaneFuelHatch.boundingBox))
    { 
        NSMutableArray *FuelTruckAnimFrames = [NSMutableArray array];
        for(int i = FuelTruckCollisionStartFrameIndex; i <= FuelTruckCollisionEndFrameIndex;   i) 
        {
            [FuelTruckAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"ftruck_col_%d.png", i]]];
        }
        CCAnimation *FuelTruckAnim = [CCAnimation animationWithFrames:FuelTruckAnimFrames delay:FuelTruckCollisionFrameDelay];

        CCAction *FuelTruckCollisionBlue = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:FuelTruckAnim restoreOriginalFrame:NO]];

        [FuelTruck runAction:FuelTruckCollisionBlue];

        isCollided=YES;
    }
    else
    {

        if(isCollided==YES)
        { 
            isCollided=No;
            [FuelTruck stopAction:FuelTruckCollisionBlue];
        }
    }
}        
  

Но это не останавливает анимацию столкновения, когда столкновение завершено. Для завершения анимации требуется несколько миллисекунд, почему это так?

Комментарии:

1. Я обеспокоен тем, что у вас, похоже, есть if s, которые начинаются : else if . Я могу только предположить, что вы пропустили какой-то код. Также, пожалуйста, найдите время для форматирования вашего кода, мне потребовалось всего 5 минут, чтобы все перестроить. Это может даже помочь вам найти проблему.

Ответ №1:

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

     if(CGRectIntersectsRect(selSprite.boundingBox,BluePlaneFuelHatch.boundingBox))
    { //<(1)>
        ...
        //THIS ANIMATION IS ONLY AVAILABLE WITHIN THE BRACES MARKED WITH (1)
        CCAnimation *FuelTruckAnim = [CCAnimation animationWithFrames:FuelTruckAnimFrames delay:FuelTruckCollisionFrameDelay];

        CCAction *FuelTruckCollisionBlue = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:FuelTruckAnim restoreOriginalFrame:NO]];
        ...
        isCollided=YES;
    }//<(1)>
    else
    {

        if(isCollided==YES)
        { 
            isCollided=No;
            //YOU ARE THEN TRYING TO USE THE VARIABLE HERE. IT DOESN'T EXIST IN THIS SCOPE.
            [FuelTruck stopAction:FuelTruckCollisionBlue];
        }
    }
  

Попробуйте это вместо:

     //As a member variable
    CCAction *FuelTruckCollisionBlue;




    if(CGRectIntersectsRect(selSprite.boundingBox,BluePlaneFuelHatch.boundingBox))
    { //<(1)>
        ...
        //THIS ANIMATION IS ONLY AVAILABLE WITHIN THE BRACES MARKED WITH (1)
        CCAnimation *FuelTruckAnim = [CCAnimation animationWithFrames:FuelTruckAnimFrames delay:FuelTruckCollisionFrameDelay];

        FuelTruckCollisonBlue = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:FuelTruckAnim restoreOriginalFrame:NO]];
        ...
        isCollided=YES;
    }//<(1)>
    else
    {

        if(isCollided==YES)
        { 
            isCollided=No;
            //YOU ARE THEN TRYING TO USE THE VARIABLE HERE. IT DOESN'T EXIST IN THIS SCOPE.
            [FuelTruck stopAction:FuelTruckCollisionBlue];
        }
    }
  

Комментарии:

1. Хороший совет, но я бы сделал это только 1, если вы покажете OP, как это исправить (т. Е. объявив FuelTruckCollisionBlue внешний if блок) 🙂

2. Как и было обещано, 1 от меня. Но я только что заметил после перечитывания кода, что это не решает проблему OP, просто потому if , что и else являются эксклюзивными друг для друга, поэтому, если блок «true» выполняется и устанавливается FuelTruckCollisonBlue , код не попадет в блок «false» для stopAction части, наоборот. Что нужно OP, так это добавление FuelTruckCollisonBlue в качестве переменной-члена вместо объявления ее в этом методе.

3. Я пытаюсь использовать код, предложенный Джеймсом, но все равно анимация не останавливается. Пожалуйста, помогите мне разобраться в этой проблеме..

4. Вы предоставили весь необходимый код? Попробуйте правильно отформатировать свой код с помощью отступов строк, и это должно дать вам лучшее визуальное представление о том, где находятся ваши объекты.