1

我正在 cocos2d 中编写一个模态层,我想使用 OpenGL glScissorAPI 调用来裁剪CCScrollLayer我正在使用的 a 的内部,

基本上,

  1. 呈现某种模态精灵
  2. 将带有资产的 CCScrollLayer 放在模态精灵上
  3. 我想裁剪 CCScrollLayer 使其不会溢出精灵。

看起来很简单。

我遇到的问题是该visit功能似乎永远不会被击中,因此glScissor永远不会被实现。

我不确定我做错了什么。

我做模态的方式是使用块来处理是和否条件/状态。

// This appears in my "Pick City scene"
-(id) init
{

    if ((self = [super init])) 
    {
        NSLog(@"City list");

        for (City *cityObj in listOfCities) 
        {
            citySpriteOff = [CCSprite spriteWithSpriteFrameName:@"city.png"];
            citySpriteOn = [CCSprite spriteWithSpriteFrameName:@"city_on.png"];

            int x = [cityObj.x intValue];
            int y = [cityObj.y intValue];

            CCMenuItemSprite *mapMenuItem = [CCMenuItemSprite itemFromNormalSprite:citySpriteOff selectedSprite:citySpriteOn target:self selector:@selector(btnCity:)];
            [mapMenuItem setTag:i];
            [mapMenuItem setIsRelativeAnchorPoint:YES];
            [mapMenuItem setAnchorPoint:CGPointMake(0, 0)];
            [mapMenuItem setPosition:CGPointMake(x, y)];
            [mapMenuItem setIsEnabled:YES];

            [mapMenu addChild:mapMenuItem];
            i++;
        } // next

        [self addChild:mapMenu z:2];
    }
}


-(void) btnCity:(id)sender
{
    NSLog(@"clicked a city button");
    int tag = [sender tag];

    City *cityObj = [listOfCities objectAtIndex:tag];
    NSLog(@"You clicked on city: %@", cityObj.name);

    [self lockLayers];

    CCLayer *layer = [CCLayer node];
    [self addChild:layer z:100];

    [MapModalLayer ConfirmCity:cityObj onLayer:layer yesBlock:^{[self btnConfirmedCity:cityObj];} noBlock:^{[self unlockLayers];}];

}



-(void) btnConfirmedCity:(City *)cityObj
{
    NSLog(@"confirmed city: %@", cityObj.name);
}




#pragma mark - Lock/Unlock layers

-(void) lockLayers
{
    [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;
                }
            }
        }
        else
            [self MenuStatus:_enable Node:result];
    } // next
}

实际的模态代码出现在这里,

@implementation MapModalLayer

- (id)init {
    self = [super init];
    if (self) {
        // This method never seems to be called
        NSLog(@"MapModalLayer init");
    }
    return self;
}

// This method never seems to be called
- (void) visit {
    NSLog(@"Visit");
    if (!self.visible)
        return;

    glPushMatrix(); 
    glEnable(GL_SCISSOR_TEST);  
    glScissor(50, 50, 100 , 150);

    [super visit];

    glDisable(GL_SCISSOR_TEST);
    glPopMatrix();
}


+ (void) CloseAlert: (CCSprite*) alertDialog onCoverLayer: (CCLayer*) coverLayer executingBlock: (void(^)())block {
    // shrink dialog box
    [alertDialog runAction:[CCScaleTo actionWithDuration:kAnimationTime scale:0]];


    // in parallel, fadeout and remove cover layer and execute block 
    // (note: you can't use CCFadeOut since we don't start at opacity 1!)
    [coverLayer runAction:[CCSequence actions:
                           [CCFadeTo actionWithDuration:0.2f opacity:0], 
                           [CCCallBlock actionWithBlock:^{
                                [coverLayer removeFromParentAndCleanup:YES];
                                if (block) block();
                            }],
                           nil]];
}


+(void) ConfirmCity:(City *)cityObj onLayer:(CCLayer *)layer yesBlock :(void (^)())yesBlock noBlock:(void (^)())noBlock
{

    CCLayerColor *coverLayer = [CoverLayer new];
    [layer addChild:coverLayer z:INT_MAX]; // put to the very top to block application touches
    [coverLayer runAction:[CCFadeTo actionWithDuration:kAnimationTime opacity:80]]; // smooth fade-in to dim with semi-transparency

    CGSize winSize = [[CCDirector sharedDirector] winSize];

    CCSprite *dialog = [CCSprite spriteWithSpriteFrameName:@"modal.png"];
    [dialog setPosition:CGPointMake(winSize.width/2,winSize.height/2)];
    [dialog setTag:kDialogTag]; 

    //
    // We put our CCScrollLayer *scroller  content here... it doesn't matter what it is right now
    //

    //
    // Finally we put our accept/reject buttons
    //

    // Tick/Cross buttons    
    CCSprite *closeButtonOn = [CCSprite spriteWithSpriteFrameName:@"btn_close.png"];
    CCSprite *tickButtonOn  = [CCSprite spriteWithSpriteFrameName:@"btn_accept.png"];



    // add one or two buttons, as needed 
    CCMenuItemSprite *opt1Button = [CCMenuItemSprite itemFromNormalSprite:closeButtonOn
                                                           selectedSprite:nil
                                                                    block:^(id sender){ 
                                                                        // close alert and call opt1block when first button is pressed
                                                                        [self CloseAlert:dialog onCoverLayer: coverLayer executingBlock:noBlock];
                                                                    } ];

    [opt1Button setPosition:CGPointMake(-200, -120)];

    // create second button, if requested
    CCMenuItemSprite *opt2Button = [CCMenuItemSprite itemFromNormalSprite:tickButtonOn
                                             selectedSprite:nil
                                                      block:^(id sender){ 
                                                          // close alert and call opt2block when second button is pressed
                                                          [self CloseAlert:dialog onCoverLayer: coverLayer executingBlock:yesBlock];
                                                      } ];



    [opt2Button setPosition:CGPointMake(40, -120)];

    CCMenu *menu = [CCMenu menuWithItems:opt1Button, opt2Button, nil];
    [menu setContentSize:dialog.contentSize];
    [dialog addChild:menu z:2];


    [coverLayer addChild:dialog];

}  


@end

我认为这是因为我只使用 MapModalLayer 的私有方法。

但我不确定。

有没有办法让我glScissor像上面解释的那样在模态中使用?

我已经尝试将glScissor代码移动到模式的显示,但它似乎从来没有做任何事情。

为了确认它工作正常,我将glScissor代码移到了父级,它似乎工作正常。

因此,我如何使模态层使用/工作glScissor

4

1 回答 1

1

我已经解决了这个问题。

我使用了来自http://pastebin.com/tWsEbxvJ的视口

我这样做的方式是:

  CoverLayer *coverLayer = [CoverLayer new];
    [layer addChild:coverLayer z:INT_MAX]; // put to the very top to block application touches
    [coverLayer runAction:[CCFadeTo actionWithDuration:kAnimationTime opacity:80]]; // smooth fade-in to dim with semi-transparency

    // ------------------------------

    CGSize winSize = [[CCDirector sharedDirector] winSize];

    CCSprite *dialog = [CCSprite spriteWithSpriteFrameName:@"modal.png"];
    [dialog setPosition:CGPointMake(winSize.width/2,winSize.height/2)];
    [dialog setTag:kDialogTag]; 

.. // Build your pagesArray here for ScrollLayer...



    // Now create the scroller and pass-in the pages (set widthOffset to 0 for fullscreen pages)
    CCScrollLayer *scroller = [[CCScrollLayer alloc] initWithLayers:pagesArray widthOffset: 350];
    [scroller setShowPagesIndicator:NO]; 

    // finally add the scroller to your scene
    //[dialog addChild:scroller];


    Viewport *cn = [[Viewport alloc] initWithRect:CGRectMake(3, 0, dialog.contentSize.width-12, dialog.contentSize.height-5)];
    [cn addChild:scroller];

    [scroller release];



    [coverLayer addChild:dialog z:1];

这允许我在层上放置一个模态,放置一个 CCScrollLayer 并确保内容不会溢出我制作的模态精灵的内部(这就是为什么宽度配置看起来有点奇怪)。

谢谢。

于 2012-09-17T09:01:55.433 回答