How to implement Sprite with Buttons - ios

So I'm making a game, and in this game I need to have a certain sprite to appear multiple times.
It's simply an image, with two buttons. One button underneath the image, and one above.
I am using Cocos2d, so any mention of sprite will be the CCSprite class. And the image is actually just a line.
Is there an easy way to implement something like this? I don't want to have to make a separate sprite for the image, and then add each button. Is there a way I can do this all in one sprite?
I'm assuming that I'll probably have to manually add everything (create a method that will create an image and position the buttons relative to the image), but I'm hoping I'm wrong and there is an easier/more efficient way of doing this.
Thanks!

I think you are looking for CCMenuItem and CCMenu
CCSprite *enabledSprite = [CCSprite spriteWithFile:#"myButtonSprite.png"];
CCSprite *selectedSprite = [CCSprite spriteWithFile:#"myButtonSprite.png"];
CCSprite *disabledSprite = [CCSprite spriteWithFile:#"myButtonSprite.png"];
CCMenuItemSprite *item [[[CCMenuItem alloc] initWithNormalSprite:enabledSprite
selectedSprite:selectedSprite
disabledSprite:disabledSprite
target:delegate
selector:selector] autorelease];
item.position = ccp(240, 160);
CCMenu *menu = [CCMenu menuWithItems:item, nil];
menu.position = ccp(0, 0);
[self addChild:menu];

Related

Cocos2d animate CCSprite width/height

Is there any way to animate CCSprite width/height in cocos2d ? I'm looking to animate the menu panel width, scaleX/scaleY property animation is not the solution for my case.
I'm not 100% sure what you want to do as there is very little data.
But you can take a look at CCMoveTo and CCScaleTo.
These will move and scale your sprite over a given time.
You can group these together (I think) to run them both at the same time.
Yes, there are a lot of animations available in cocos2d. you may want to run multiple action on a sprite sequentially or parallel on a node/sprite. For example i have a sprite and i want to scale its size, blink and then fade out to it. Then i would do
CCSPrite *mySprite = [CCSprite spriteWithFile:#"xyz.png"];
.....
CCScaleTo *scale = [CCScaleTo actionWithDuration:0.3 scaleX:20 scaleY:30];
CCBlink *blink = [CCBlink actionWithDuration:0.3 blinks:2];
CCFadeTo *fade = [CCFadeTo actionWithDuration:0.3 opacity:0];
To run all the above actions one after other:
[mySPrite runAction:[CCSequence actions:scale, blink, fade, nil]];
To run all the actions at same time:
[mySprite runAction:[CSPawn actions:scale, blink, fade, nil]];
There are a lot of action like this you implement inorder to get an animation effect. Read the cocos2d documentaion.

CCSprite not showing Background Image

I am facing an unknown error since from yesterday. I am creating CCSprites or CCMenuItemImage but it set black background instead of background image. Following is my code, I know its fine because I used it before many times.
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"challenge_screen.plist"];
CCSprite *bg = [CCSprite spriteWithFile:#"ads.png"];
[bg setPosition:background.position];
// [bg setContentSize:CGSizeMake(100, 100)];
[self addChild:bg z:1000];
//CGSize windowSize = [[CCDirector sharedDirector] winSize];
CCMenuItemImage *coinMenuItem = [[CCMenuItemImage alloc] initWithNormalSprite:[CCSprite spriteWithSpriteFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"coin.png"]] selectedSprite:nil disabledSprite:nil block:^(id sender)
{
NSLog(#"I am Tapped");
}];
coinMenuItem.position = ccp(100, 100);
CCMenu *mainMenu = [CCMenu menuWithItems:coinMenuItem, nil];
mainMenu.position = CGPointZero;
[self addChild:mainMenu];
Attached is screenshot.
Thanks in advance.
I am guessing that you are loading this sprite sheet (challenge_screen.plist and the associated texture file, which frequently is challenge_screen.png or challenge_screen.pvr.*) in a color mode that doesn't have transparency.
First, make sure that the associated texture file shows transparency itself. Maybe something messed with this particular texture.
Once you checked that, if the associated texture is .PNG. then you have to set the texture loading format in code like this. You have to set the texture format before loading the texture itself (the texture loads as a side effect of adding the SpriteFrames to the cache).
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA4444];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"challenge_screen.plist"];`
...
You can also try the kCCTexture2DPixelFormat_RGBA8888 mode if RGBA444 produces banding with your graphics and if you are good regarding free memory.
On the other hand, if the texture is a PVR.*, then the format in which the texture loads is embedded in the file, and setting the texture format in code doesn't make a difference. You will then need to regenerate your sprite sheet using the appropriate format (through TexturePacker or similar).
Is your background in the sprite sheet? If so try:
CCSprite *bg = [CCSprite spriteWithSpriteFrameName:#"ads.png"];
If it is the menu item and you know the code works, it must be an asset issue.

""CCSprite is not using the same texture id"" workaround?

I am animating a whole body through SpriteSheets with CCSpriteBatchNode and CCSpriteFrameCache. Now user can add his own pic to that body which when i try to addChild to Spritesheet crashes with error "CCSprite is not using the same texture id"
Now i know the face CCSprite was not in that cache/texture(it was created through texturepacker) and the crash was normal but i wanted to know if there was a workaround to this as i have to add a face to that body through user interaction and animate that body. And by far using spritesheets is the best option for animation. anyone??
In this case what you can do is You take picture of user , then you make texture from user's image .
Then Add that texture to the CCTextureCache . Now you have texture of user image. Now you can use that texture in animation.
Make Texture from Sprite(You can make sprite from user image)
CCSprite *spr = nil;//your sprite
CCRenderTexture* renderTexture = [CCRenderTexture renderTextureWithWidth:spr.contentSize.width height:spr.contentSize.height];
spr.anchorPoint = ccp(0, 0);
spr.position = ccp(0, 0);
[renderTexture addChild:spr];
[renderTexture begin];
[spr draw]; // or [spr visit];
[renderTexture end];
CCTexture2D *result = renderTexture.sprite.texture;
Add that Texture in to Texture Cache.
[[CCTextureCache sharedTextureCache] addTexture]
When you create a CCSpriteBatchNode it is linked to a single texture. This is the point of a CCSpriteBatchNode: to draw different sprites that use the same texture to reduce OpenGL draw calls and increase efficiency.
The easiest workaround (if you have not reached a performance-critical point) would be to use a regular CCLayer instead of a CCSpriteBatchNode.
If you still want to add different CCSprites (say, the body, the limbs and the head of your character) to the same CCSpriteBatchNode, the you need to build a single sprite sheet (or texture pack) which contains all the body parts that you need to add to the CCSpriteBatchNode. This single sprite sheet will be the only one that the CCSpriteBatchNode will use. You won't be able to add CCSprites that are not using this sprite sheet.
You can not Manually add CCSprite to SpriteSheets. Because When you create animated Sprite using texturepacker then i hope that you know it also created with .plist file and it loas image from it with its size.
When you add manually CCSprite then it is nor found from SpriteFramesWithFile. may be you got error.
another way for add animated CCSprite without use of texturepacker
CCSprite *dog = [CCSprite spriteWithFile:#"dog1.gif"];
dog.position = ccp(winSize.width/2, winSize.height/2);
[self addChild:dog z:2];
NSMutableArray *animFrames = [NSMutableArray array];
for( int i=1;i<=5;i++)
{
NSString* file = [NSString stringWithFormat:#"dog%d.gif", i];
CCTexture2D* texture = [[CCTextureCache sharedTextureCache] addImage:file];
CGSize texSize = texture.contentSize;
CGRect texRect = CGRectMake(0, 0, texSize.width, texSize.height);
CCSpriteFrame* frame = [CCSpriteFrame frameWithTexture:texture rect:texRect];
[animFrames addObject:frame];
}
CCAnimation * animation = [CCAnimation animationWithSpriteFrames:animFrames];
animation.delayPerUnit = 0.07f;
animation.restoreOriginalFrame = YES;
CCAnimate *animAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:animation]];
[dog runAction:animAction];
Above code is just describe that how can you add animated CCSprite without use of texturepacker
Here you can also change array of Images so you may be add manually image also.

Cocos2D: how to tweak CCMenuItem with only one sprite?

how could I tweak CCMenuItemSprite to support only one sprite?
Currently I have:
[CCMenuItemSprite itemWithNormalSprite:one selectedSprite:selectedOne]
But would like to have:
[CCMenuItemSprite itemWithNormalSprite:one]
EDIT: I want to modify CCMenuItem to work only with one CCSprite and not two. So I need to change also the internal methods.
You can just use the same (normal) sprite as the selected sprite. When clicked, the button will then do nothing.
You could just use
[CCMenuItemSprite itemWithNormalSprite:one selectedSprite:one]
this way, nothing would happen when you select the sprite
try this, just change colour of seleted sprite.
CCSprite *sprite1 = [CCSprite spriteWithFile:#"Button.png"];
CCSprite * sprite2 = [CCSprite spriteWithFile:#"Button.png"];
sprite2.color = ccc3(128, 128, 128);
CCMenuItemImage *itemEasyLevelImage = [CCMenuItemImage itemWithNormalSprite:sprite1
selectedSprite:sprite2
block:^(id sender){}];

CCMoveTo not working, node/scene issue?

I have a CCLayer class called SuccessLayer. It gets added to the scene when the level is complete, like so:
SuccessLayer *successLayer = [SuccessLayer node];
[self addChild:successLayer];
In SuccessLayer, I want to have a rock fly by, I'm trying to achieve that with this:
-(void)onEnter{
Asteroid *asteroid = [Asteroid spriteWithFile:#"rocks.png"];
asteroid.position = ccp(0, 500);
[self addChild:asteroid];
CCMoveTo *move = [CCMoveTo actionWithDuration:2.0 position:ccp(1000, 0)];
[asteroid runAction:move];}
However, it seems CCMoveTo isn't working. I see the sprite sitting at its initial coordinates, but nothing more. What am I missing here? Thanks
[super onEnter];
any coco's onSomething, you should super onSomething.
Sovled the problem by casting it as a CCSprite (is that the correct way to say it?)
CCSprite *asteroid = [Asteroid spriteWithFile:#"rocks.png"];
Asteroid is already a subclass of CCSprite, so I have no idea why this works, but it allows me to run actions on it now.

Resources