How to Convert a CCSprite image to UIImage? - cocos2d-iphone

As the title, I have mentioned the code below
CCSprite *sprite = (CCSprite *)node;
CCTexture2D *texture2d = [sprite texture];
How can I get a UIImage *p from sprite?

In your case just add next methood into your class:
- (UIImage *) imageFromSprite :(CCSprite *)sprite
{
int tx = sprite.contentSize.width;
int ty = sprite.contentSize.height;
CCRenderTexture *renderer = [CCRenderTexture renderTextureWithWidth:tx height:ty];
sprite.anchorPoint = CGPointZero;
[renderer begin];
[sprite visit];
[renderer end];
return [renderer getUIImage];
}
how to use:
CCSprite *sprite = (CCSprite *)node;
UIImage *p = [self imageFromSprite:sprite]

uhh...
I think this is a better to way. Add this as a category on CCNode.
-(UIImage*)image {
CCRenderTexture* renderer = [CCRenderTexture renderTextureWithWidth:self.contentSize.width height:self.contentSize.height];
const CGPoint ANCHORBEFORE = self.anchorPoint;
self.anchorPoint = CGPointZero;
[renderer begin];
[self visit];
[renderer end];
self.anchorPoint = ANCHORBEFORE;
return [renderer getUIImage];
}

If you are using cocos2d 2.x, render sprite into CCRenderTexture and call getUIImage method of that render texture.

By looking at the source code of both CCSprite and CCTexture2D you can see that the image is used only for creating the texture data and the image object is not kept but temporarily used.
CCTexture2D source :
http://code.google.com/p/cocos2d-iphone/source/browse/trunk/cocos2d/CCTexture2D.m?r=1882
CCSprite source :
http://code.google.com/p/cocos2d-iphone/source/browse/trunk/cocos2d/CCSprite.m?r=1747
Look in the init methods that use CGImageRef

Related

How to take screenshot of a user defined rectangular area in cocos2d

I need to take the screenshot in my cocos2d application. I've searched a lot, even in stack overflow. Then I found the following code:
+(UIImage*) screenshotWithStartNode:(CCNode*)stNode
{
[CCDirector sharedDirector].nextDeltaTimeZero = YES;
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCRenderTexture* renTxture =
[CCRenderTexture renderTextureWithWidth:winSize.width
height:winSize.height];
[renTxture begin];
[stNode visit];
[renTxture end];
return [renTxture getUIImage];
}
Now,
Problem: The above code gives me the entire screenshot. But I am in need of the screenshot of a custom are, such as, within a CGRect(50,50,100,200).
Can anyone please help me..? Thanks...
Wow... found out what I need. I've changed the above method like:
-(UIImage*) screenshotWithStartNode:(CCNode*)startNode
{
[CCDirector sharedDirector].nextDeltaTimeZero = YES;
CGSize winSize = [CCDirector sharedDirector].winSize;
CCRenderTexture* rtx =
[CCRenderTexture renderTextureWithWidth:winSize.width
height:winSize.height];
[rtx begin];
[startNode visit];
[rtx end];
UIImage *tempImage = [rtx getUIImage];
CGRect imageBoundary = CGRectMake(100, 100, 300, 300);
UIGraphicsBeginImageContext(imageBoundary.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// translated rectangle for drawing sub image
CGRect drawRect = CGRectMake(-imageBoundary.origin.x, -imageBoundary.origin.y, tempImage.size.width, tempImage.size.height);
// clip to the bounds of the image context
CGContextClipToRect(context, CGRectMake(0, 0, imageBoundary.size.width, imageBoundary.size.height));
// draw image
[tempImage drawInRect:drawRect];
// grab image
UIImage* subImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return subImage;
}

Cocos2d Screen capture and get sprite from UIImage

I'm very headache about this problem, I'm using these code for capturing a part of the screen
-(UIImage *) glToUIImage {
userphotoCount++;
[CCDirector sharedDirector].nextDeltaTimeZero = YES;
CGSize winSize = [CCDirector sharedDirector].winSize;
CCLayerColor* whitePage = [CCLayerColor layerWithColor:ccc4(255, 255, 255, 0) width:winSize.width height:winSize.height];
whitePage.position = ccp(winSize.width/2, winSize.height/2);
CCRenderTexture* rtx = [CCRenderTexture renderTextureWithWidth:815 height:532];
[rtx begin];
[whitePage visit];
[[[CCDirector sharedDirector] runningScene] visit];
[rtx end];
return [rtx getUIImageFromBuffer];
}
I can get my UIImage by
image = [self glToUIImage];
Then I try to use this code to generate a sprite by the UIImage
-(void) ImageSprite{
image = [self glToUIImage];
userAns = [CCSprite spriteWithCGImage:image.CGImage key:[NSString stringWithFormat:#"photoCap%d.png", userphotoCount]];
userAns.position=ccp(780,410);
userAns.scale=0.6;
[self addChild:userAns z:20];
}
I can get image by these code at first time, but after I changed the screen's contents and use these code to generate new sprite(new UIImage) with the new contents, I'm failed.... the image doesn't change to new image...
How can I get the new image sprite when every time I run the "imageSprite" code?
You can get the new image sprite, but you must to change key
[CCSprite spriteWithCGImage:image.CGImage key:key];

Issues with creating a CCParallaxNode in cocos2d?

I'm using a CCParallaxNode for a scrolling background in my GameLayer and I'm getting a bunch of errors and I can't figure out why.
"Initializer element is not a compile-time constant" and also "Unk
#implementation Background
// Load the sprites for each parallax layer, from background to foreground.
CCSprite* para1 = [CCSprite spriteWithFile:#"color.png"];
CCSprite* para2= [CCSprite spriteWithFile:#"ship-hd.png"];
CCSprite* para3 = [CCSprite spriteWithFile:#"twit.png"];
CCSprite* para4 = [CCSprite spriteWithFile:#"Start.png"];
// Set the correct offsets depending on the screen and image sizes.
para1.anchorPoint = CGPointMake(0, 1);
para2.anchorPoint = CGPointMake(0, 1);
para3.anchorPoint = CGPointMake(0, 0.6f);
para4.anchorPoint = CGPointMake(0, 0);
CGPoint topOffset = CGPointMake(0, screenSize.height);
CGPoint midOffset = CGPointMake(0, screenSize.height / 2);
CGPoint downOffset = CGPointZero;
// Create a parallax node and add the sprites to it.
CCParallaxNode* paraNode = [CCParallaxNode node];
[paraNode addChild:para1 z:1 parallaxRatio:CGPointMake(0.5f, 0) ositionOffset:topOffset];
[paraNode addChild:para2 z:2 parallaxRatio:CGPointMake(1, 0) positionOffset:topOffset];
[paraNode addChild:para3 z:4 parallaxRatio:CGPointMake(2, 0) positionOffset:midOffset];
[paraNode addChild:para4 z:3 parallaxRatio:CGPointMake(3, 0) positionOffset:downOffset];
[self addChild:paraNode z:0 tag:ParallaxSceneTagParallaxNode];
// Move the parallax node to show the parallaxing effect.
CCMoveBy* move1 = [CCMoveBy actionWithDuration:5 position:CGPointMake(−160, 0)];
CCMoveBy* move2 = [CCMoveBy actionWithDuration:15 position:CGPointMake(160, 0)];
CCSequence* sequence = [CCSequence actions:move1, move2, nil];
CCRepeatForever* repeat = [CCRepeatForever actionWithAction:sequence];
[paraNode runAction:repeat];
#end
You need to enclose your code in an -(id)init method, like this:
#implementation Background
- (id)init
{
if (self = [super init]) {
// Load the sprites for each parallax layer, from background to foreground.
CCSprite* para1 = [CCSprite spriteWithFile:#"color.png"];
// ... the rest of your code ... //
}
return self;
}
#end

How to Convert CCSpriteBatchNode to UIImage?

I want to convert CCSpriteBatchNode to a UIImage, is there a possible way to do it? I know it is possible to convert CCSprite to UIImage, but when I try it with CCSpriteBatchNode, it crashes :
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'CCSpriteBatchNode should NOT be root node'
Thanks!
Here is the code to convert CCSprite to UIImage.
+ (UIImage *)renderUIImageFromSprite:(CCSprite *)sprite {
CCRenderTexture *renderer = [CCRenderTexture renderTextureWithWidth:sprite.contentSize.width; height:sprite.contentSize.height;];
[renderer begin];
[sprite visit];
[renderer end];
return [renderer getUIImageFromBuffer];
}
EDIT :
This is the working code.
+ (UIImage *)renderUIImageFromCCLabelBMFont:(CCLabelBMFont *)bmfont {
GLProgram *program = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionTextureColor];
glUseProgram(program->program_);
int textureWidth = bmfont.contentSize.width;
int textureHeight = bmfont.contentSize.height;
CCRenderTexture *renderer = [CCRenderTexture renderTextureWithWidth:textureWidth height:textureHeight];
bmfont.anchorPoint = ccp(0.0, 0.0);
CCNode *node = [CCNode node];
[node addChild:bmfont];
[renderer begin];
[node visit];
[renderer end];
return [renderer getUIImageFromBuffer];
}
Needed this myself. This is ARC code and set up as a category for CCLabelBMFont.
CCLabelBMFont+UIImage.h
#interface CCLabelBMFont (UIImage)
- (UIImage *)image;
#end
CCLabelBMFont+UIImage.m
#implementation CCLabelBMFont (UIImage)
- (UIImage *)image
{
CCGLProgram *program = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionTextureColor];
glUseProgram(program->program_);
CCRenderTexture *renderer = [[CCRenderTexture alloc] initWithWidth:(int)self.contentSize.width
height:(int)self.contentSize.height
pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
CCLabelBMFont *labelBMFont = [[CCLabelBMFont alloc] initWithString:string_
fntFile:fntFile_
width:width_
alignment:alignment_
imageOffset:imageOffset_];
labelBMFont.anchorPoint = ccp(0.0, 0.0);
CCNode *node = [CCNode node];
[node addChild:labelBMFont];
[renderer begin];
[node visit];
[renderer end];
return [renderer getUIImage];
}
#end

cocos2d Children sprite collision detection with parent sprite

Hi stackoverflow community!
How do you detect a children sprite collision with a parent sprite in cocos2d?
Currently I have my codes like this:
CGSize screenSize = [[CCDirector sharedDirector]winSize];
parentJumper = [CCSprite spriteWithFile:#"inviBtn.png"];
jumper = [CCSprite spriteWithFile:#"jumperRight.png"];
plat = [[Platform alloc]init];
plat = [Platform spriteWithFile:#"platformBlack.png"];
plat.position = ccp(160,100);
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0/60)];
jumper.anchorPoint = ccp(0.5, 0);
jumper.position = ccp(0, 20);
parentJumper.position = ccp(screenSize.width/2, 0);
[self addChild:plat];
[self addChild:parentJumper];
[parentJumper addChild:jumper];
Now how do I detect the collision between "jumper" & "plat"?
Thanks for your help!
Usually you can check collision like this:
if(CGRectIntersectsRect([jumper boundingBox], [plat boundingBox])) {
//Handle collision<br>
}