I have a problem following a tutorial for cocos2d 3.0 in cocos2d 3.1 ... when compilation finish show a warning "CCSpriteBatchNode is deprecated", how can I use the plist now? or isn't used now in cocos2d 3.1? can you write an example, would very helpful :)
#implementation GameScene
{
CCSpriteBatchNode *_batchNode; // WARNING 1 HERE
Hunter *_hunter;
Bird *_bird;
}
-(void)addBackground
{
//1
CGSize viewSize = [CCDirector sharedDirector].viewSize;
//2
CCSprite *background = [CCSprite spriteWithImageNamed:#"game_scene_bg.png"];
//3
background.position = ccp(viewSize.width * 0.5f, viewSize.height * 0.5f);
//4
[self addChild:background];
}
-(void)createBatchNode {
//1
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"Cocohunt.plist"];
//2
_batchNode = [CCSpriteBatchNode batchNodeWithFile:#"Cocohunt.png"]; // WARNING 2 HERE
//3
[self addChild:_batchNode z:1];
}
In version 3.1, the cocos2d renderer was re-made to automatically batch drawn sprites. So CCSpriteBatchNode is no longer needed, just use a CCNode.
#implementation GameScene
{
CCNode *_batchNode; // WARNING 1 HERE
Hunter *_hunter;
Bird *_bird;
}
Related
It seems CCLayerColor not found in Cocos2d 3.0
Here is my Cocos2d 2.0 code, I used CCLayerColor with 20% opacity.
ccColor4B color = {0,0,0,255};
CCLayerColor *fadeLayer = [CCLayerColor layerWithColor:color];
[self addChild:fadeLayer z:5];
fadeLayer.opacity = 128;
In Cocos2d v3, I tried CCNodeColor, but its not semi opaque..always black.
CCNodeColor *fadeLayer = [CCNodeColor nodeWithColor:[CCColor colorWithRed:0 green:0 blue:0]];
[self addChild: fadeLayer z:5];
fadeLayer.opacity = 128;
How can I achieve colour layer with semi transparency in Cocos2d v3 ?
Problem Solved !
Solution is simple, now opacity range 0-1 not 1-255.
CCNodeColor *fadeLayer = [CCNodeColor nodeWithColor:[CCColor colorWithRed:0 green:0 blue:0]];
[self addChild: fadeLayer z:5];
fadeLayer.opacity = 0.25f; // this fixed my problem.
I am trying to make a hole on a CCRenderTexture with Cocos2D 2.0.
More specifically I have:
a CCSprite "stars" that shows some stars repeating a png image;
on top of that I have a CCRenderTexture "dark" that completely covers the "stars" sprite.
I want to be able to cut a hole on "dark" in order to show the stars below.
I am using CCRenderTexture (as suggested in some tutorials) but the hole I manage to make is never fully transparent, so the stars visible through the hole are partially obscured.
I really hope some one can show me the light, I spent over a week on this...
This is the code:
#interface MyBackgroundLayer : CCLayerGradient {
}
#end
#implementation MyBackgroundLayer
CCRenderTexture * dark;
CCSprite * stars;
-(id) init
{
if (self=[super init]) {
CGSize size = [[CCDirector sharedDirector] winSize];
// background
stars = [CCSprite spriteWithFile:#"stars.png" rect:CGRectMake(0, 0, size.width, size.height)];
stars.anchorPoint = ccp(0,0);
ccTexParams params = {GL_LINEAR,GL_LINEAR,GL_REPEAT,GL_REPEAT};
[stars.texture setTexParameters:¶ms];
[self addChild:stars];
// dark layer to cover the background
dark = [CCRenderTexture renderTextureWithWidth:size.width height:size.height];
[dark clear:0 g:0 b:0 a:1.0f];
[self addChild: dark];
dark.position = ccp(size.width/2,size.height/2);
[[dark sprite] setBlendFunc: (ccBlendFunc) { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }];
}
return self;
}
-(void)draw
{
[super draw];
[dark beginWithClear:0 g:0 b:0 a:1];
glColorMask(0, 0, 0, 1);
// Here I am using 0.5 as alpha value, this could seems the reason why the hole is not fully transparent.
// However if I change the alpha value to 1.0f or 0.0f the hole becomes completely opaque
ccColor4F color = ccc4f(1.f, 1.f, 1.f, 0.5f);
ccDrawSolidRect(ccp(0,0), ccp(600, 600), color);
glColorMask(1,1,1,1);
[dark end];
}
#end
I think what you're looking for is something like this ( may need some editing).
As for your code ..i thing the problem is in the blend function. Check this out to see how they work.
I'm using the clipping node here: http://www.learn-cocos2d.com/2011/01/cocos2d-gem-clippingnode
ClippingNode.h
#import "cocos2d.h"
#interface ClippingNode : CCNode {
CGRect clippingRegionInNodeCoordinates;
CGRect clippingRegion;
}
#property (nonatomic) CGRect clippingRegion;
#end
ClippingNode.m
#import "ClippingNode.h"
#interface ClippingNode (PrivateMethods)
-(void) deviceOrientationChanged:(NSNotification*)notification;
#end
#implementation ClippingNode
-(CGRect) clippingRegion {
return clippingRegionInNodeCoordinates;
}
-(void) setClippingRegion:(CGRect)region {
// keep the original region coordinates in case the user wants them back unchanged
clippingRegionInNodeCoordinates = region;
self.position = clippingRegionInNodeCoordinates.origin;
self.contentSize = clippingRegionInNodeCoordinates.size;
// convert to retina coordinates if needed
region = CC_RECT_POINTS_TO_PIXELS(region);
// respect scaling
clippingRegion = CGRectMake(region.origin.x * scaleX_, region.origin.y * scaleY_,
region.size.width * scaleX_, region.size.height * scaleY_);
}
-(void) setScale:(float)newScale {
[super setScale:newScale];
// re-adjust the clipping region according to the current scale factor
[self setClippingRegion:clippingRegionInNodeCoordinates];
}
-(void) deviceOrientationChanged:(NSNotification*)notification {
// re-adjust the clipping region according to the current orientation
[self setClippingRegion:clippingRegionInNodeCoordinates];
}
-(void) visit {
glEnable(GL_SCISSOR_TEST);
CGPoint worldPosition = [self convertToWorldSpace:CGPointZero];
const CGFloat s = [[CCDirector sharedDirector] contentScaleFactor];
glScissor((clippingRegion.origin.x) + (worldPosition.x*s), (clippingRegion.origin.y) + (worldPosition.y*s),
(clippingRegion.size.width), (clippingRegion.size.height));
[super visit];
glDisable(GL_SCISSOR_TEST);
}
#end
However, I need to clip a rotated CCNode. Any idea on how I could accomplish such a task?
Replace the visit method in the class ClippingNode by this
-(void) visit
{
float rotationAngle = 15;
glPushMatrix();
CCRenderTexture* renderTexture = [[CCRenderTexture renderTextureWithWidth:512 height:512] retain];
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, clippingRegion.size.width, clippingRegion.size.height);
[renderTexture begin];
glPushMatrix();
glRotatef(rotationAngle, 0, 0, 1);
glTranslatef(-clippingRegion.origin.x, -clippingRegion.origin.y, 0);
[super visit];
glPopMatrix();
[renderTexture end];
glDisable(GL_SCISSOR_TEST);
renderTexture.sprite.position = CGPointMake(clippingRegion.origin.x , clippingRegion.origin.y);
renderTexture.sprite.anchorPoint = CGPointMake(0, 1);
renderTexture.sprite.rotation = rotationAngle;
[renderTexture.sprite visit];
[renderTexture release];
glPopMatrix();
}
Basically it creates a texture where to render the ClippingNode contents
Then translate the scene so that the origin in the clipping region is now at (0,0)
Rotate the entire scene by rotationAngle
Enable the scissor
Render the scene
Translate, rotate, and render the sprite containing the texture
It only needs CCRenderTexture to finish the job. Any suggestion will be greatly appreciated.
ClippingNode.h
#import "cocos2d.h"
#interface ClippingNode : CCNode
#property (nonatomic, assign) CGSize clippingSize;
#end
ClippingNode.m
#import "ClippingNode.h"
#interface ClippingNode()
#property (nonatomic, strong) CCRenderTexture * renderTexture;
#property (nonatomic, strong) CCSprite * clippedSprite;
#end
#implementation ClippingNode
#synthesize renderTexture;
#synthesize clippedSprite;
#synthesize clippingSize;
- (void) setClippingSize:(CGSize)newClippingSize {
//assignment
clippingSize = newClippingSize;
//set contentSize
self.contentSize = clippingSize;
//configure renderTexture
self.renderTexture = [CCRenderTexture renderTextureWithWidth:clippingSize.width height:clippingSize.height];
renderTexture.contentSize = CGSizeMake(clippingSize.width, clippingSize.height);
//configure the renderTexture sprite
self.clippedSprite = [CCSprite spriteWithTexture:renderTexture.sprite.texture];
clippedSprite.position = self.position;
clippedSprite.rotation = rotation_;
clippedSprite.scaleY = -1;
}
- (void)visit {
[renderTexture beginWithClear:0 g:0 b:0 a:1];
[super visit];
[renderTexture end];
[clippedSprite visit];
}
#end
Usage:
CCSprite * spriteImage = ...;
spriteImage.position = ccp(0,0);
spriteImage.anchorPoint = ccp(0.5,0.5);
//configure clipping Node
self.clippingNode = [ClippingNode node];
clippingNode.position = ccp(size.width * 0.5f, size.height * 0.5f);
clippingNode.anchorPoint = ccp(0.5f, 0.5f);
clippingNode.rotation = -10.0f;
//configure clipping region
[clippingNode setClippingSize:CGSizeMult(spriteImage.boundingBox.size, 1.5f)];
//add content to the clipping node
[clippingNode addChild:spriteImage]
I got a Scene with a layer with the top z-index wich one adds a dark effect to the whole scene setting its opacity. What i am trying to do now is to remove the shadow/dark effect in a concrete region (inside a cone/triangle) as the image shows (inside the red polygon). In other words, i want to have the same "luminosity" (zero opacity) inside the triangle as on the left side of the screen.
code:
-(id) init
{
if( (self=[super initWithColor:ccc4(0,0,0,128)] )) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCLayerColor* layer1 = [CCLayerColor layerWithColor: ccc4(0, 0, 0, 180) width: winSize.width height: winSize.height];
layer1.position = ccp(50,0);
[self addChild: layer1 z:2];
CCSprite *background = [CCSprite spriteWithFile:#"background.png"];
background.position = ccp(background.contentSize.width/2, background.contentSize.height/2);
[self addChild:background];
CCSprite *player = [CCSprite spriteWithFile:#"Player.png"rect:CGRectMake(0, 0, 27, 40)];
player.position = ccp(player.contentSize.width/2, winSize.height/2);
[self addChild:player];
}
return self;
}
any idea on how to do this ?? maybe i should try to do it on another whay and not use a CCLayer to add the dark effect ??
Thanks in advance
The simplest way would be to use a CCSprite with a black image the size of the background. Then cut out the whole you need in an image program and draw that sprite over the background with lowered opacity.
I am using following code for sprite animation in cocos2d
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:
#"AnimBear.plist"];
CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode
batchNodeWithFile:#"AnimBear.png"];
[self addChild:spriteSheet];
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 8; ++i) {
[walkAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"bear%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation
animationWithFrames:walkAnimFrames delay:0.1f];
CGSize winSize = [CCDirector sharedDirector].winSize;
self.bear = [CCSprite spriteWithSpriteFrameName:#"bear1.png"];
_bear.position = ccp(winSize.width/2, winSize.height/2);
self.walkAction = [CCRepeatForever actionWithAction:
[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
[_bear runAction:_walkAction];
[spriteSheet addChild:_bear];
I need not getting clear idea about CCSpriteBatchNode why this is used here?
You do not need to use the CCSpriteBatchNode for a single animation.
The CCSpriteBatchNode is used when you want to display many objects taken from the same sprite sheet. In this case rendering the stuff is much faster than rendering individual sprites.
As long as you use a single sprite there is no speed up since the sprites in an animation are displayed in separate frames.