2012-08-07 20 views
1

我編碼在cocos2d模態層,我想使用的OpenGL glScissor API調用來裁剪CCScrollLayer,我使用的內模層上用glScissor,在cocos2d

基本上,

  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

+0

我要嘗試不同的路線;也許init'd和不使用私人方法。希望這能解決我的問題。 – zardon 2012-08-09 16:57:45

回答

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並確保內容不會溢出我所做的模式精靈的內部(這就是寬度配置看起來有點奇怪的原因)。

謝謝。