Cocos2d iphone CoCoS2D2.0-截图过程中的奇怪行为
我有一个基于层的类,它包含两个作为子对象的精灵。让我们称它们为:背景和树 在这个类中,我有一个方法来捕获该层的屏幕截图。这种方法很有效。每次我拍摄该层的屏幕截图时,我都会获得背景上树的组成。好的在某一点上,我想得到没有树的那一层的截图。所以我要做的是,隐藏这棵树,截图并再次显示这棵树。。。像这样:Cocos2d iphone CoCoS2D2.0-截图过程中的奇怪行为,cocos2d-iphone,Cocos2d Iphone,我有一个基于层的类,它包含两个作为子对象的精灵。让我们称它们为:背景和树 在这个类中,我有一个方法来捕获该层的屏幕截图。这种方法很有效。每次我拍摄该层的屏幕截图时,我都会获得背景上树的组成。好的在某一点上,我想得到没有树的那一层的截图。所以我要做的是,隐藏这棵树,截图并再次显示这棵树。。。像这样: [myLayer hideTree]; UIImage *screenshot = [myLayer screenshot]; [myLayer showTree]; 令我惊讶的是,以这种方式生成的
[myLayer hideTree];
UIImage *screenshot = [myLayer screenshot];
[myLayer showTree];
令我惊讶的是,以这种方式生成的屏幕截图总是包含树
这是hideTree和showTree:
- (void) hideTree {
[treeLayer setOpacity:0];
// I have also tried [treelayer setVisible:NO];
}
- (void) showTree {
[treeLayer setOpacity:255];
// I have also tried [treelayer setVisible:YES];
}
我在cocos2d论坛上使用此方法截图:
-(UIImage*) screenshot
{
CGSize displaySize = [[CCDirector sharedDirector] winSize];
CGSize winSize = [self winSize];
//Create buffer for pixels
GLuint bufferLength = displaySize.width * displaySize.height * 4;
GLubyte* buffer = (GLubyte*)malloc(bufferLength);
//Read Pixels from OpenGL
glReadPixels(0, 0, displaySize.width, displaySize.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
//Make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL);
//Configure image
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * displaySize.width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(displaySize.width, displaySize.height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
uint32_t* pixels = (uint32_t*)malloc(bufferLength);
CGContextRef context = CGBitmapContextCreate(pixels, winSize.width, winSize.height, 8, winSize.width * 4, CGImageGetColorSpace(iref), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextTranslateCTM(context, 0, displaySize.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
switch (orientation)
{
case UIDeviceOrientationPortrait: break;
case UIDeviceOrientationPortraitUpsideDown:
CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(180));
CGContextTranslateCTM(context, -displaySize.width, -displaySize.height);
break;
case UIDeviceOrientationLandscapeLeft:
CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(-90));
CGContextTranslateCTM(context, -displaySize.height, 0);
break;
case UIDeviceOrientationLandscapeRight:
CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(90));
CGContextTranslateCTM(context, displaySize.width * 0.5f, -displaySize.height);
break;
case UIDeviceOrientationUnknown:
break;
case UIDeviceOrientationFaceUp:
break;
case UIDeviceOrientationFaceDown:
break;
}
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, displaySize.width, displaySize.height), iref);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage *outputImage = [UIImage imageWithCGImage:imageRef];
//Dealloc
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGImageRelease(iref);
CGColorSpaceRelease(colorSpaceRef);
CGContextRelease(context);
free(buffer);
free(pixels);
return outputImage;
}
我错过了什么?为什么树总是显示?在游戏循环的更新过程中,您的代码正在运行 屏幕截图获取用于创建UIImage的当前像素 当您告诉树不可见或不透明度为零时,这将在下一个绘制周期之前生效 要解决问题,需要隐藏树,执行绘制循环,然后在下一次更新中捕获未显示树的帧
有道理吗 您的代码正在游戏循环的更新过程中运行 屏幕截图获取用于创建UIImage的当前像素 当您告诉树不可见或不透明度为零时,这将在下一个绘制周期之前生效 要解决问题,需要隐藏树,执行绘制循环,然后在下一次更新中捕获未显示树的帧
有道理吗 更改树的不透明度时,仅在下次屏幕更新时生效 有一次我遇到了这个问题,我做了一些安排。而不是
[myLayer hideTree];
UIImage *screenshot = [myLayer screenshot];
[myLayer showTree];
做
并将以下方法添加到场景中:
-(void)takeScreenshot {
[self unschedule:@selector(takeScreenshot)];
UIImage *screenshot = [myLayer screenshot];
[myLayer showTree];
}
基本上,我们设置了0.05秒的间隔,以允许屏幕更新。这应该行得通
上面的方法对我很有效,但我认为如果在隐藏树后调用
[self-visit]
,同样有效。但我从未测试过。当您更改树的不透明度时,它只会在下次屏幕更新时生效
有一次我遇到了这个问题,我做了一些安排。而不是
[myLayer hideTree];
UIImage *screenshot = [myLayer screenshot];
[myLayer showTree];
做
并将以下方法添加到场景中:
-(void)takeScreenshot {
[self unschedule:@selector(takeScreenshot)];
UIImage *screenshot = [myLayer screenshot];
[myLayer showTree];
}
基本上,我们设置了0.05秒的间隔,以允许屏幕更新。这应该行得通
上面的方法对我很有效,但我认为如果在隐藏树后调用
[self-visit]
,同样有效。但是我从来没有测试过。是的,有。我怀疑问题是这样的,但我如何按照你的建议进行“抽签循环”呢?找到了。我需要添加[[CCDirector sharedDirector]drawScene];是的。我怀疑问题是这样的,但我如何按照你的建议进行“抽签循环”呢?找到了。我需要添加[[CCDirector sharedDirector]drawScene]+1的努力,但另一个答案给了我搜索强制重画的想法,我找到了一个更简单的解决方案,只添加了一个[[CCDirector sharedDirector]drawScene];隐藏树后强制重新绘制。无论如何,谢谢你+1的努力,但另一个答案给了我搜索强制重画的想法,我找到了一个更简单的解决方案,只添加了一个[[CCDirector sharedDirector]drawScene];隐藏树后强制重新绘制。无论如何,谢谢你!!!!!!