I'm confused on using animations in cocos2d... I've a sprite which has 3 types of animations, like a smiley which laughs, cries and winks eyes... And I have separate sprite sheets for each of these animations... how will I be able to use these animations on the same sprite... Can anybody help me please???
Regards,
Suraj
It would be much easier to have all your animations on the same sprite sheet, as, if your sprite is using a CCBatchnode to do it's draw method, you'd have remove it as a child from 1 sheet, and readd it to another.
In your CCSprite subclass, set some CCAction's as instance variables.
In an initialization method, write those actions and store them to the instance variables.
Then when you want to use an animation, tell your sprite to run it.
E.g.
NSMutableArray *smileFrames = [NSMutableArray array];
[smileFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"character_smile.png"]];
[smileFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"character_smile2.png"]];
[smileFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"character_smile3.png"]];
CCAnimation *smileAnim = [CCAnimation
animationWithFrames:smileFrames delay:0.2f];
self.smileAction = [CCSequence actions:
[CCAnimate actionWithAnimation:smileAnim restoreOriginalFrame:NO],
[CCCallFunc actionWithTarget:self selector:#selector(smileFinished)],
nil];
Then you would simply use..
[sprite runAction:smileAction];
I have added a CCCallFunc to the end of the animation, as you may want to revert back to an idle animation after it is finished.
Don't forget to release any retained actions when the sprite is deallocated.
Related
I'm trying to make a fade in-fade out effect in cocos 2d, using a black png image. Its to make a better way to show something, instead of the casual way...
Is something wrong on this code?
- (void) effectFade {
CCSprite *effectScreen = [CCSprite spriteWithFile:#"black-iphone.png"];
effectScreen.opacity = 0;
[effectScreen runAction:[CCSequence actions:
[CCFadeIn actionWithDuration:1],
[CCCallFunc actionWithTarget:self selector:#selector(hideOutShowIn)],
[CCFadeOut actionWithDuration:1],
[CCCallFunc actionWithTarget:self selector:#selector(finish)],
nil]];
CCFadeTo *fadeIn = [CCFadeIn actionWithDuration:1];
CCFadeTo *fadeOut = [CCFadeOut actionWithDuration:1];
CCSequence *fadeSequence = [CCSequence actionOne:fadeIn two:fadeOut];
}
You don't specify what is not working as expected, but it seems to me that you are not adding effectScreen to any layer or other node, so that it can be displayed.
As to the rest, the code seems correct to me (aside from fadeIn, fadeOut, fadeSequence that are not used).
EDIT:
you are definitely using effectScreen in an ObjC/C sense; what you are not doing is adding it to your scene by doing something like:
[self addChild:effectScene];
(assuming self is your scene or another CCNode class).
The thing about not using fadeSequence is a bit different, since you are not using it in the ObjC/C sense: you define it and never ever reference it again.
I created a new project with cocos2d, and then create a layer and a sprite.
I am trying to apply an animation to my sprite, and I found some samples about that. But I don't understand the difference between CCAnimation and CCAnimate, so I haven't applied any animation for my sprite yet.
What is the difference between these two and what is the real meaning of them? How to use them?
Can any one explain me about that? Please help me.
Here is code from "Working with Sprites, and Sprite batch nodes" in cocos2d-iphone Programming Guide:
......
NSMutableArray *animFrames = [NSMutableArray array];
for(int i = 1; i < 15; i++) {
CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"grossini_dance_%02d.png",i]];
[animFrames addObject:frame];
}
CCAnimation *animation = [CCAnimation animationWithName:#"dance" delay:0.2f frames:animFrames];
[sprite runAction:[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:animation restoreOriginalFrame:NO]]];
As you can see, you need to use both CCAnimate and CCAnimation to run a CCSpriteFrame-based animation on the sprite. Per description of CCAnimation:
The CCAnimation object contains CCSpriteFrame objects, and a possible delay between the frames. You can animate a CCAnimation object by using the CCAnimate action. Example:
[sprite runAction:[CCAnimate actionWithAnimation:animation]];
Generally speaking, CCAnimation is a wrapper of frame container. CCAnimate is the action that the sprite need to do - in fact it is a subclass of CCAction, which represents an action that a sprite can "run", such as moving, jumping, rotating, etc. You can use its other subclasses to do some kinds of animation on your sprite without creating the frames yourself. Have a try with something like CCFadeIn, CCRotateBy, etc.
I'm relatively new to iphone programming, and I've been starting out with cocos2d. I was wondering if there was a way to set opacity for multiple sprites at once? I noticed that opacity isn't implemented for CCLayer, and opacity doesn't seem to propagate down to children of class CCSprite.
Is there any better way to do this than to override setOpacity on a custom ccnode and iterate through and set opacities individually? Or perhaps overriding draw and setting the blending mode manually?
Thanks!
You can loop through all the sprites in your scene, check if they are the sprites you want, then set their opacity like this (assuming you set their tag to OPACITY_SPRITE_TAG when you create the sprites)
for(CCSprite* sprite in [self children])
{
if([sprite tag] == OPACITY_SPRITE_TAG)
{
[sprite setOpacity:NEW_OPACITY];
}
}
Couldn't you just increment through an array of sprites that you want to change. Something like:
for(int i = 0; i < [myArray count]; i++){
CCSprite *mySprite = [myArray objectAtIndex:i];
[mySprite setOpacity:100];
}
Hey guys, I'm new to cocos2d and iPhone development, im currently trying to create a game like "PapiJump",
What I'm currently having problems with, is animating the character CCSprite in my game,
I have created 3 images of my character, character pointing right, left and middle (http://i53.tinypic.com/ngzoyh.png)
so when the character changes its direction (left or right), it wont "jump" directly to the other direction but will animate..
In my code im using the TouchesEnded method, in this method im setting a variable named "touchState",
so if the user touched the right side of the screen it will set "touchState" to 1, otherwise it sets it to 2 (means left).
then in the "init" method i created a "schedule" that runs another method every 0.5 sec that is named: "updateGame",
the "updateGame" method updates the player's position, it works like that:
player.position = ccp(player.position.x , player.position.y - playerGravity.y);
I've read Ray's tutorial on animating CCSprites but i have no idea how to achieve the result that i need..
Thanks in advance and sorry for my bad english!
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 4; ++i)
{
[walkAnimFrames addObject: [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName: [NSString stringWithFormat:#"spr_fillin_0%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.0333f];
_sprite = [CCSprite spriteWithSpriteFrameName:#"spr_fillin_01.png"];
[_sprite runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]]];
[<CCLAYER OR BATCH NODE> addChild:_sprite];
Edit: Looks like you're talking about just flipping the image around. You can just refetch a sprite with
_sprite = [CCSprite spriteWithSpriteFrameName:#"<New Sprite File>"];
(Or cache them and switch)
Can you clarify your question? If you want to set a different sprite frame, you can use setDisplayFrame:
CCSpriteFrame *spriteFrame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:frameName];
[sprite setDisplayFrame:frame];
or if you have an animation:
[sprite runAction:[CCAnimate actionWithAnimation:runAnimation restoreOriginalFrame:NO]];
But I feel like the question is a little vague.
if i got your question properly i can suggest two ways to solve your problem:
first you could rotate your object to till it is upside down, and the continue your previous animations using FlipX(or FlipY) flag marks as true or you can add an animation wich animates only characters rotation and when ever it's finnished change the FLipX(or FlipY) status.
I am writing an application where you push different buttons and a character gets animated. The thing is that I have many images, so I need to use one texture for each animation. Therefore I need to release sprite sheet and frame cash, but it does not seem to be working. Memory gets allocated more and more until the app crashes. Here is the code:
// **** DEFINE THE ANIMATION - EATING 1: ****
// Create a sprite sheet with all the images
CCSpriteSheet *spriteSheet = [CCSpriteSheet spriteSheetWithFile:#"Eating4.png"];
// This loads an image of the same name (but ending in png), and goes through the
// plist to add definitions of each frame to the cache.
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"Eating4.plist"];
[self addChild:spriteSheet];
///[self addChild:spriteSheet2];
// Load up the frames of our animation
NSMutableArray *eating1AnimFrames = [NSMutableArray array];
for(int i = 0; i <= 50; ++i) {
if (i<=9){
[eating1AnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"Eating4_000%d.png", i]]];
}
else if (i>9) {
[eating1AnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"Eating4_00%d.png", i]]];
}
}
CCAnimation *eatingAnim = [CCAnimation animationWithName:#"eating" delay:0.05f frames:eating1AnimFrames];
// Create a sprite for the mouse
CGSize winSize = [CCDirector sharedDirector].winSize;
self.mouse = [CCSprite spriteWithSpriteFrameName:#"Eating4_0000.png"];
_mouse.position = ccp(winSize.width/2+20, winSize.height/2);
// Adjust the size of the Sprite:
[_mouse setScaleX: 1];
[_mouse setScaleY: 1];
//self.eatingAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:eatingAnim restoreOriginalFrame:NO]];
self.eatingAction = [CCAnimate actionWithAnimation:eatingAnim restoreOriginalFrame:NO];
[spriteSheet addChild:_mouse];
[_mouse runAction:_eatingAction];
I try to release memory like this:
[[CCTextureCache sharedTextureCache] removeAllTextures];
[[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFrames];
[[CCTextureCache sharedTextureCache] removeAllTextures];
You don't want to do this! This removes all textures from memory, then reloads all of them that are still in use or the next time they are used. This causes a significant overhead and it's generally bad for your game's performance.
Instead, remove only the texture you need to remove by calling:
[[CCTextureCache sharedTextureCache] removeTexture:tex];
For this to work, you will also have to remove (release) all references to the animation from the Cocos2D node hierarchy.
Calling removeUnusedTextures would be a better choice for clearing up memory used by unused textures:
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
Or you can ask use CCDirector::purgeCachedData that does the same thing internally:
[[CCDirector sharedDirector] purgeCachedData];