How To Have The Same Sprite In Multiple Locations Cocos2d - cocos2d-iphone

How To Have The Same Sprite In Multiple Locations Cocos2d Please Help
I have searched all over and cannot find answer

Just create multiple Sprites (CCSprite instances). They can all use the same texture (bitmap-file).
CCSprite * mySprite1;
CCSprite * mySprite2;
CCSprite * mySprite3;
// create several sprites from the same bitmap file
mySprite1 = [CCSprite spriteWithFile:#"spriteBitmap.png"];
mySprite2 = [CCSprite spriteWithFile:#"spriteBitmap.png"];
mySprite3 = [CCSprite spriteWithFile:#"spriteBitmap.png"];
mySprite1.position = ccp(100, 100);
mySprite2.position = ccp(200, 200);
mySprite3.position = ccp(300, 300);

You can not add the same CCSprite as a child to multiple CCNodes but you can make Cocos2D render the same CCSprite multiple times.
To achieve this you need to create a subclass of CCNode that will store the reference to your CCSprite and draw it in its -draw method applying required transformations.
For example
-(void)draw
{
[super draw];
CGPoint initialPosition = [_node position];
float initialScale = [_node scale];
[_node setScale:self.scale];
[_node setPosition:self.position];
[_node visit];
[_node setPosition:initialPosition];
[_node setScale:initialScale];
}
You may have to to use glScissor if you need picture-in-picture appearance.
Then you just need to addChild an instance of this class for every time you want an additional copy of your original CCSprite rendered.

Put a method on a for loop.
Inside the method create the CCSprite and modify it.
This is best suited for static sprites, since I don't know how you would access these outside of the method.

Related

Fixed sprite on the tile map cocos2d?

I can't figure out how to handle with tile map layer and other node. I want to make another one layer(CCNode) for such things as menu button, score, joystick that must always stay fixed(not scrolled), when the whole map is scrolled.
self.theMap=[CCTiledMap tiledMapWithFile:#"map.tmx"];
self.bgLayer=[theMap layerNamed:#"bg"];
[self addChild:theMap z:-1];
CCNode *joystickNode;
joystickNode=[CCNode node];
[bgLayer.parent addChild:joystickNode z:2];
upArrowFrame=[CCSpriteFrame frameWithImageNamed:#"uparrow.png"];
upArrow=[CCButton buttonWithTitle:#"" spriteFrame:upArrowFrame];
[upArrow setTarget:self selector:#selector(upArrowPressed)];
upArrow.position= ccp(190,190);
[joystickNode addChild:upArrow z:2];
Now upArrow is not visible on the screen at all. If I add to self instead of joystickNode, it will appear.
I can't even understand, what parent should new CCNode have. Can anyone explain it to me? I also tried to add new CCNode as a child of self and theMap.
EDIT: Oops, it's actually moving the camera. How to implement it in this case?
-(void)setCenterOfScreen :(CGPoint) position {
CGSize screenSize=[[CCDirector sharedDirector]viewSize];
int x=MAX(position.x, screenSize.width/2);
int y=MAX(position.y, screenSize.height/2);
x= MIN(x, theMap.mapSize.width * theMap.tileSize.width - screenSize.width/2);
y= MIN(y, theMap.mapSize.height * theMap.tileSize.height - screenSize.height/2);
CGPoint goodPoint =ccp(x,y);
CGPoint centerOfScreen = ccp(screenSize.width/2, screenSize.height/2);
CGPoint difference = ccpSub(centerOfScreen, goodPoint);
self.position=difference;
}
- (void)update:(CCTime)dt{
[self setCenterOfScreen:hero.position];
}

Choose Random Sprite Cocos2d 3.0

I have 4 sprites, every time the game starts it would randomly choose 1 from the 4 sprites to be the main sprite.
How can I do this?
I know I would need to use arc4random
The easiest way would be -- First name you image (.png) files with some numbers for e.g. sprite1.png, sprite2.png ....
int rndSprtNum = (arc4random() % 4) + 1;
CCSPrite *mainSprite = [CCSprite spriteWithFile:[NSString StringWithFormat:#"sprite%d.png",rndSprtNum]];
mainSprite.position = ccp(x,y);
[self addChild:mainSprite];
This way you no need to take a mutable array etc. Hope this helps.
First of all you are add all sprite in NSMutableArray as below code.
Allocate Array
NSMutableArray *AryT = [[NSMutableArray alloc]init];
Differnt sprite
CCSprite *torpedoOne1 = [CCSprite spriteWithFile:#"A#2x.png"];
CCSprite *torpedoOne2 = [CCSprite spriteWithFile:#"B#2x.png"];
CCSprite *torpedoOne3 = [CCSprite spriteWithFile:#"C#2x.png"];
Add All This sprite in define Array
[AryT addObject:torpedoOne1];
[AryT addObject:torpedoOne2];
[AryT addObject:torpedoOne3];
Take Random number from array
int RandomIndex = arc4random_uniform(AryT.count);
Randomaly sprite
[self addchild:[AryT objectAtIndesx:RandomIndex]];
Here's another approach, in case you don't want to rename your files you can simply put their names in an array:
NSString *names[4] = {#"RedSprite.png", #"GreenSprite.png", #"YellowSprite.png", #"PurpleSprite.png"};
CCSprite *sprite = [CCSprite spriteWithFile:names[arc4random_uniform(4)]];
[self addChild:sprite];

Clip a CCSprite added to CCSpriteBatchNode

I'm clipping my sprite with this code:
//At my CCSprite subclass m.
-(void)visit
{
CGPoint worldOrg = [self convertToWorldSpace:ccp(0, 0)];
CGPoint dest = [self convertToWorldSpace:ccp(self.contentSize.width, self.contentSize.height)];
CGPoint dims = ccpSub(dest, worldOrg);
glEnable(GL_SCISSOR_TEST);
glScissor(worldOrg.x, worldOrg.y, dims.x, dims.y);
#define SHOW_CLIPPED_AREA 1
#if SHOW_CLIPPED_AREA
//Draws a red rectangle showing clipped area
ccDrawSolidRect(ccp(0, 0), ccp(1024, 1024), ccc4f(64, 0, 0, 128));
#endif
[super visit];
glDisable(GL_SCISSOR_TEST);
}
Then just create the sprite as usual, adjust the sprite.contentSize property to whatever I need:
CCSprite aSprite = [CCSprite spriteWith...];
aSprite.contentSize = CGSizeMake(20,20);
//Add it to my layer
[self addChild:aSprite];
And it works as expected!
Problem...
When adding it to a CCSpriteBatchNode, it wont clip the sprite... it shows the sprite but without clipping it.
Can someone please help me out with this, I've googled everywhere with no answer to this.
I've also used the ClippingNode class from Steffen Itterheim, but I'm also having issues adding it to a CCSpriteBatchNode.
Any help will be appreciated.
Clipping or any custom drawing won't work with sprite-batched sprites.
The CCSpriteBatchNode will not call visit (nor draw) methods on their children because the batch node takes over rendering of the children. Therefore any code you write in draw or visit methods of a CCSprite will have no effect when you sprite-batch the sprite.

Cocos2d - Orbiting/spinning one sprite around another

I've got to sprites, essentially a nucleus (parent) and an electron (child). I'm trying to find a way to have the electron orbit the nucleus. I've found a few posts here and there on moving anchor points, but that is apparently related to the texture of the sprite, not the sprite itself.
This is my current init method for my parent sprite:
self = [super init];
if (self) {
CCSprite *orbitAnchor = [CCSprite new];
[self addChild:orbitAnchor];
orbitAnchor.position = ccp(32,32);
CCSprite *orbiter = [CCSprite spriteWithFile:#"line.png" rect:CGRectMake(0, 0, 8, 8)];
[orbitAnchor addChild:orbiter];
orbiter.position = ccp(40,40);
CCAction *orbitAction = [CCRepeatForever actionWithAction:[CCRotateTo actionWithDuration:1 angle:720]];
[orbitAnchor runAction:orbitAction];
[self initAnimations];
}
return self;
Those numbers are all totally arbitrary though - I just stuck them in there and got what looked best. I'm sure there's a more programatic way to do what I want.
Basically, I'm looking for a way to set the child's axis point at the center of the parent, and then have it rotate around that point. It seems like a relatively simple thing to do using CCRotate and such, but I think I'm missing what to search for in order to move the anchor point of the child. Any suggestions/other posts?
Thanks
You have [CCSprite new] which is an unusual use, probably not supported. Unless the orbit anchor node should display a texture, you can just use a CCNode as anchor.
Technically you're doing everything correct from what I can see. You might want to try without the rotate actions and instead change the direction manually in a scheduled update method.
CCNode *orbitAnchor = [CCNode node];
[self addChild:orbitAnchor z:0 tag:1];
orbitAnchor.position = ccp(32,32);
CCSprite *orbiter = [CCSprite spriteWithFile:#"line.png" rect:CGRectMake(0, 0, 8, 8)];
[orbitAnchor addChild:orbiter z:0 tag:2];
orbiter.position = ccp(40,40);
[self scheduleUpdate];
Update method:
-(void) update:(ccTime)delta
{
CCNode* orbitAnchor = [self getChildByTag:1];
orbitAnchor.direction += 5;
}
From the image filename it looks like you're trying to draw a line from the orbitAnchor to the orbiter. You can do that with ccDrawLine:
-(void) draw
{
CCNode* orbitAnchor = [self getChildByTag:1];
CCNode* orbiter = [self getChildByTag:2];
ccDrawLine(orbitAnchor.position, orbiter.position);
}
Anchor points. Automatically, objects are placed based on the center of an object right? with anchor points you can move that around, so if you rotate the object it will rotate around the anchorpoint. http://www.qcmat.com/understanding-anchorpoint-in-cocos2d/

Problem with migrating from Texture2D to CCTexture2D (Setting CCSprite texture)

My problem is that whenever I change the texture of a sprite, the new texture will retain the size of the original sprite's texture.
I have this code:
mySprite = [CCSprite spriteWithFile:#"mySprite.png"]];
...
// change current stage here
CCTexture2D *newTexture=[[[CCTexture2D alloc]initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"stage number %d.png",currentStageNumber]]]autorelease];
[mySprite setTexture:newTexture];
The new sprite is stretched or compressed depending on the size of the original sprite.
If the original sprite is larger, the new texture is stretched.
I didn't have this problem when I was using cocos2d v0.8
What am I doing wrong?
Solved:
mySprite = [CCSprite spriteWithFile:#"mySprite.png"]];
...
// change current stage here
CCTexture2D *newTexture=[[[CCTexture2D alloc]initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"stage number %d.png",currentStageNumber]]]autorelease];
[mySprite setTexture:newTexture];
[mySprite setTextureRect:CGRectMake(0,0, newTexture.contentSize.width, newTexture.contentSize.height)];
:)
or:
CCTexture2D* texture=[[CCTexture2D alloc] initWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"sky" ofType:#"png"]] ];
CCSprite *sprTile=[CCSprite spriteWithTexture:texture];
[self addChild:sprTile];
[texture release];