سؤال

I am having trouble temporarily disabling touch interactions while performing an action. Current I have my character doing a jump flip when I swipe up, but if you swipe up again right away, it flips again. I want to disable any interaction while performing the action.

I have the following code which is calls a "begin" function which is suppose to temporarily disable touch, and an "end" function which should re-enable touch interaction after the action is complete, all within a ccactionspawn, but it is not working.

-(void)begin
{
[[UIApplication sharedApplication]beginIgnoringInteractionEvents];
}

-(void)end
{
[[UIApplication sharedApplication]endIgnoringInteractionEvents];

}


-(void)jump
{
CCActionRotateBy* flip = [CCActionRotateBy actionWithDuration:0.8f angle:360];
CCActionJumpBy* jump = [CCActionJumpBy actionWithDuration:0.8f position:CGPointMake(150, 0) height:130 jumps:1];
CCAction *actionMove = [CCActionMoveTo actionWithDuration:1.0f position:CGPointMake(-_character.contentSize.width/2, self.contentSize.height/4)];
CCActionSpawn *flipJump = [CCActionSpawn actions:[CCActionCallFunc actionWithTarget:self selector:@selector(begin)], jump, flip, actionMove, [CCActionCallFunc actionWithTarget:self selector:@selector(end)], nil];
[_character runAction:flipJump];
}

Thanks for the help!

-edit with working code.
Thanks for all of the help guys! Here is my working code if anyone needs it:

-(void)begin
{
self.userInteractionEnabled = FALSE;
}

-(void)end
{
self.userInteractionEnabled = TRUE;
}


-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchLoc1 = [touch locationInNode:self];
firstTouch = touchLoc1;
CCLOG(@"touched");
}

-(void) touchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchLoc2 = [touch locationInNode:self];
lastTouch = touchLoc2;

//Minimum length of the swipe
float swipeLength = ccpDistance(firstTouch, lastTouch);

//Check if the swipe is an up swipe and long enough
if (firstTouch.y < lastTouch.y && swipeLength > 10) {
        CCActionRotateBy* flip = [CCActionRotateBy actionWithDuration:0.8f angle:360];
        CCActionJumpBy* jump = [CCActionJumpBy actionWithDuration:0.8f position:CGPointMake(150, 0) height:130 jumps:1];
        CCAction *actionMove = [CCActionMoveTo actionWithDuration:1.0f position:CGPointMake(-_character.contentSize.width/2, self.contentSize.height/4)];
        CCActionSequence *flipJump = [CCActionSequence actions:[CCActionCallFunc actionWithTarget:self selector:@selector(begin)], flip, actionMove, [CCActionCallFunc actionWithTarget:self selector:@selector(end)], nil];
        [_character runAction:jump];
    [_character runAction:flipJump];
    }
}
هل كانت مفيدة؟

المحلول

A CCActionSpawn performs all these actions at once and in parallel. That means that you are not waiting until the animation is complete. Instead of using CCActionSpawn you should use CCActionSequence which performs all actions after each other.

Creating the sequence should look like this:

CCActionSequence *flipJump = [[CCActionSequence actions:[CCActionCallFunc actionWithTarget:self selector:@selector(begin)], jump, flip, actionMove, [CCActionCallFunc actionWithTarget:self selector:@selector(end)], nil];

Additionally you need to either set userInteractionEnabled to TRUE and FALSE int the begin and end method or maintain another flag and use that flag inside the touch methods to check wether touches should be handled or not.

Example for first option:

-(void)begin
{
 self.userInteractionEnabled = FALSE;
}

-(void)end
{
 self.userInteractionEnabled = TRUE;
}

نصائح أخرى

Don't disable touch, just keep a state variable and check to see if you are flipping and don't flip if you are already flipping.

edited to write the code...

-(void)begin
{
}

-(void)end
{
    isFlipping = NO;
}


-(void)jump
{
    if (!isFlipping) {
        isFlipping = YES;
        CCActionRotateBy* flip = [CCActionRotateBy actionWithDuration:0.8f angle:360];
        CCActionJumpBy* jump = [CCActionJumpBy actionWithDuration:0.8f position:CGPointMake(150, 0) height:130 jumps:1];
        CCAction *actionMove = [CCActionMoveTo actionWithDuration:1.0f position:CGPointMake(-_fufunaken.contentSize.width/2, self.contentSize.height/4)];
        CCActionSpawn *flipJump = [CCActionSpawn actions:[CCActionCallFunc actionWithTarget:self selector:@selector(begin)], jump, flip, actionMove, [CCActionCallFunc actionWithTarget:self selector:@selector(end)], nil];
        [_character runAction:flipJump];
    }
}

isFlipping will be a BOOL, probably in your view controller. You may want to wrap the body of jump in an @synchronized (self) block to avoid threading issues, but in reality that could just slow things down too much. And if he flips twice, is that really a big deal?

Try with this:

-(void)begin
{
 self.userInteractionEnabled = FALSE;
}

-(void)end
{
 self.userInteractionEnabled = TRUE;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top