1

cocos2dでモーダルレイヤーをコーディングしていますが、OpenGL glScissorAPI呼び出しを使用して、使用している内部をトリミングしたいCCScrollLayerと思います。

基本的に、

  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 に答える