Cocos2d handling touch with multiple layers

前端 未结 1 665
后悔当初
后悔当初 2020-12-23 19:09

I\'ve been busy for a few days trying to figure out how to handle touch in my Cocos2d project. The situation is a bit different as normal. I have a few different game layers

相关标签:
1条回答
  • 2020-12-23 19:40

    The easiest and simplest way to solve your problem, IMO, is by using ccTouchBegan/Moved/Ended instead of ccTouchesBegan/Moved/Ended. Meaning, you are handling a single touch at a particular moment so you avoid getting confuses over multiple touches, plus the most important feature of ccTouchBegan is a CCLayer can 'consume' the touch and stop it from propagating to the next layers. More explanation after code samples below.

    Here are steps to do it. Implement these sets of methods in all CCLayer subclasses that should handle touch events:

    First, register with CCTouchDispatcher:

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

    Next, implement ccTouchBegan, example below is from a game I've created (some part omitted of course):

    - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
        if (scene.state != lvlPlaying) {
            // don't accept touch if not playing
            return NO;
        }
        CGPoint location = [self convertTouchToNodeSpace:touch];
        if (scene.mode == modePlaying && !firstTouch) {
            if (CGRectContainsPoint(snb_putt.sprite.boundingBox, location)) {
                touchOnPutt = touch.timestamp;
    
                // do stuff
    
                // return YES to consume the touch
                return YES;
             }
        }
        // default to not consume touch
        return NO;
    }
    

    And finally implement ccTouchMoved and ccTouchEnded like the ccTouches* counterparts, except that they handle single touch instead of touches. The touch that is passed to these methods is restricted to the one that is consumed in ccTouchBegan so no need to do validation in these two methods.

    Basically this is how it works. A touch event is passed by CCScene to each of its CCLayers one by one based on the z-ordering (i.e starts from the top layer to the bottom layer), until any of the layers consume the touch. So if a layer at the top (e.g. control layer) consume the touch, the touch won't be propagated to the next layer (e.g. object layer). This way each layer only has to worry about itself to decide whether to consume the touch or not. If it decides that the touch cannot be used, then it just has to not consume the touch (return NO from ccTouchBegan) and the touch will automatically propagate down the layers.

    Hope this helps.

    0 讨论(0)
提交回复
热议问题