我正在编码cocos2d中的模态层,我想使用OpenGL glScissor
API调用来裁剪我正在使用的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 :(得分: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并确保内容不会溢出我所做的模态精灵的内部(这就是为什么宽度配置看起来有点奇怪)。 / p>
感谢。