如何停止cocos2d中的一个模态层下的所有CCTouch? [英] How to stop all CCTouch under a modal layer in cocos2d?

查看:189
本文介绍了如何停止cocos2d中的一个模态层下的所有CCTouch?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的cocos2d游戏中,我有一个设置按钮,启动一个模式层,意味着锁定它下面的一切。为了做到这一点,我使用一个菜单状态方法,锁定所有CCMenuItems和我使用覆盖层的组合;这两个都在代码中。

In my cocos2d game I have a "Settings" button which launches a modal layer and is meant to lock everything under it. To do this, I use a combination of a menu status method which locks all CCMenuItems and I use a coverlayer; both of which are below in code.

问题是,两个解决方案似乎都不工作在CCScrollLayers。当我点击按钮(它启动模态)CCScrollLayer仍然可以滚动,这不是我想要的。

The problem is that neither solution seems to work on CCScrollLayers. When I click the button (which launches the modal) the CCScrollLayer can still be scrolled which is not what i want.

我想:


  1. 按下按钮禁用所有触摸功能并禁用所有元素,包括CCScrollLayers

  2. 启动模态)

我试过:


  1. 使用Touch使用 CCTargetedTouchDelegate

  1. Using Touch to swallow all touches using the CCTargetedTouchDelegate

[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];


  1. 尝试

self.isTouchEnabled = NO p>

self.isTouchEnabled = NO on the layer launching the modal


  1. 我尝试调整 MenuStatus 方法,使其适用于CCScrollLayers,似乎无效。

  1. I've tried adapting the MenuStatus method so that it works for CCScrollLayers but it does not seem to work.

我不知道我做错了什么。我的代码现在如下。

I'm not sure what I'm doing wrong. My code now follows.

// My main layer which launches the Settings Modal Layer

#pragma mark - Lock/Unlock layers

-(void) doSettings
{    
    [self lockLayers];
    SettingsModalLayer *sml = [[[SettingsModalLayer alloc] init] autorelease];
    [sml showSettingsOnLayer:self closeBlock:^{[self unlockLayers];}];
}

-(void) lockLayers
{
    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
    [self MenuStatus:NO Node:self];   
}

-(void) unlockLayers
{
    [self MenuStatus:YES Node:self];
}


// Disabled/Enable layers
-(void) MenuStatus:(BOOL)_enable Node:(id)_node
{
    for (id result in ((CCNode *)_node).children) {        


        if ([result isKindOfClass:[CCMenu class]]) {
            for (id result1 in ((CCMenu *)result).children) {
                if ([result1 isKindOfClass:[CCMenuItem class]]) {
                    ((CCMenuItem *)result1).isEnabled = _enable;
                }
            } // next
        } 

    } // next

}


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

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Event: %@", event);
    for( UITouch *touch in touches )
    {
        CGPoint location = [touch locationInView: [touch view]];

        location = [[CCDirector sharedDirector] convertToGL: location];        
        CCLayer *gl = (CCLayer *)[self getChildByTag:4];
        [gl setIsTouchEnabled:NO];

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

}


-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
    [self removeFromParentAndCleanup:YES];    
}

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{

    return YES;
}



// Settings Modal Layer

-(void) showSettingsOnLayer:(CCLayer *)layer closeBlock:(void (^)())noBlock 
{
    CoverLayer *coverLayer = [[CoverLayer alloc] init];
    [layer addChild:coverLayer z:1000];
    [coverLayer runAction:[CCFadeTo actionWithDuration:kAnimationTime opacity:155]]; // smooth fade-in to dim with semi-transparency

... // Other stuff goes here

}


    // CoverLayer
    // This is meant to stop all touches, but it doesn't really work on CCScrollLayer

#define kDialogTag 1234
#import "CoverLayer.h"



// class that implements a black colored layer that will cover the whole screen 
// and eats all touches except within the dialog box child

@implementation CoverLayer
- (id)init {
    self = [super init];
    if (self) {
        [self initWithColor:ccc4(0,0,0,0) 
                      width:[CCDirector sharedDirector].winSize.width 
                     height:[CCDirector sharedDirector].winSize.height];
        self.isTouchEnabled = YES;
    }
    return self;
}

- (void)dealloc {
    [[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
    [super dealloc];
}


- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event 
{
    CGPoint touchLocation = [self convertTouchToNodeSpace: touch];
    CCNode *dialogBox = [self getChildByTag: kDialogTag];

    // eat all touches outside of dialog box
    return !CGRectContainsPoint(dialogBox.boundingBox, touchLocation);
}


推荐答案

优先级适用于CCTouchDispatcher。
具有最小优先级值的图层将首先接收触摸事件。

You just need to understand how priority works with CCTouchDispatcher. Layer which has minimum priority value will receive the touch events first. Now you just need to adjust the priorities accordingly.

创建一个阻塞层类,并在CCTouchDispatcher注册时将其优先级设置为最小,并覆盖ccTouchBegan并只返回YES。

Create a blocking layer class and set its priority to minimum when registering with CCTouchDispatcher and override ccTouchBegan and just return YES in it.

如果你看看CCMenu类,你会注意到默认优先级是kCCMenuTouchPriority = -128,这是菜单项具有更高触摸优先级的原因。

If you take a look at the CCMenu class you will notice default priority is kCCMenuTouchPriority = -128, that's the reason menu items have higher touch priority.

这篇关于如何停止cocos2d中的一个模态层下的所有CCTouch?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆