So i have the action build to make my frog jump but i have 5 images and i want to run them in the order 1,2,3,4,5,4,3,2,1 using the coordinates. I only want to loop them once everytime the from jumps.
Thanks
while defining your image you can use the following code:
CCAnimation* anim = [CCAnimation animationWithName:#"frog"];
CCSpriteFrame* frames[5];
CGRect Rect;
// some code to initialize Rect position
for(int i=0;i<5;i++)
{
frames[i] = [CCSpriteFrame frameWithTexture:#"frog.png" rect:Rect];
// some code to move Rect so that it will mark next frame;
}
for(int i=0;i<5;i++)
[anim addFrame:frames[i]];
for(int i=3;i>=0;i--)
[anim addFrame:frames[i]];
use ccanimation and ccspritebatchnodefile
save your image sequence in spritesheet
Related
I am new to cocos2d .Can any one suggest me a method to give animation for the transition between one frame to another frame.
this is my code to fetch frames and just display
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"spritesheet.plist"];
// Create a sprite sheet with the Happy Bear images
CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"spritesheet.png"];
[self addChild:spriteSheet];
// Load up the frames of our animation
walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <=7; ++i) {
[walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"sprite%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];
// Create a sprite for our bear
CGSize winSize = [CCDirector sharedDirector].winSize;
self.sprite = [CCSprite spriteWithSpriteFrameName:#"sprite.png"];
self.sprite.position=ccp(320,480);
self.sprite.anchorPoint=ccp(1,1);
self.walkAction = [CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO];
How to do the animation for the transition between frames
thanks in advance
You can not "transition" (morph) between two frames (images), if that's what you mean.
It sounds to me like you want something that's called keyframe interpolation, which is normally used in 3D animations. A 2D animation displays one frame after another. You can not interpolate between two frames graphically (morphing), you can only interpolate properties like position.
Hello I am trying to create snakes and ladder type board game. and I am moving player pieces with UIView animations.But it is moving player pieces with shortest path it found. I want to move player pieces horizontally , vertical and diagonally .I used below code
[UIView animateWithDuration:1.0f
animations:^{
playerOneImage.center = boardView.center;
// Here you can disable the game play so that while animation is in progress, player cannot do other operations like rotating the dice, etc...
}
completion:^(BOOL finished){
if(finished) {
NSLog(#"Player moved to square:");
// Here you can enable the game play that disabled when animation started...
}
} ];
Please help
Use a CAKeyframeAnimation on the view's layer, instead of using +[UIView animateWithDuration:...].
First, you may need to add the QuartzCore framework to your target. If you don't know how to do that, read How to "add existing frameworks" in Xcode 4? Also add #import <QuartzCore/QuartzCore.h> to your app's .pch header file.
Now you can animate the view along a path. First, create a UIPath for the path you want the view to follow. This example will move the view to the right 50 points, and then down 100 points:
CGPoint position = self.playerOneImage.layer.position;
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:position];
position.x += 50; [path addLineToPoint:position];
position.y += 100; [path addLineToPoint:position];
Next, create a CAKeyframeAnimation that will animate the position property along that path:
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
animation.duration = 1.0f;
animation.path = path.CGPath;
animation.calculationMode = kCAAnimationPaced;
There are lots of options for changing the speed at which the layer moves along the path - check the docs.
Next, you have to set the layer's position to the final position, where you want it to be after the animation is over. It seems weird, but it's absolutely necessary:
// Important: you must actually set the layer's position!
// Otherwise the animation will put it back at the start
// when the animation ends. You should set the layer's
// final position, then add the animation.
self.playerOneImage.layer.position = position;
Finally, add the animation to the layer:
[self.playerOneImage.layer addAnimation:animation forKey:#"position"];
And you're done.
All together for easy cut/paste:
CGPoint position = self.playerOneImage.layer.position;
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:position];
position.x += 50; [path addLineToPoint:position];
position.y += 100; [path addLineToPoint:position];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
animation.duration = 1.0f;
animation.path = path.CGPath;
animation.calculationMode = kCAAnimationPaced;
// Important: you must actually set the layer's position!
// Otherwise the animation will put it back at the start
// when the animation ends. You should set the layer's
// final position, then add the animation.
self.playerOneImage.layer.position = position;
[self.playerOneImage.layer addAnimation:animation forKey:#"position"];
I have made a CCAnimationHelper class that performs the following. You give it a fileName, a frameCount, and a Delay and it will give you back an animation. The thing I want to know is how to set the frame of the animation so instead of starting at frame 1, it will start at frame 10 instead. Here is my code
// Creates an animation from sprite frames.
+(CCAnimation*) animationWithFrame:(NSString*)frame frameCount:(int)frameCount delay:(float)delay
{
// load the ship's animation frames as textures and create a sprite frame
NSMutableArray* frames = [NSMutableArray arrayWithCapacity:frameCount];
for (int i = 1; i < frameCount; i++)
{
NSString* file = [NSString stringWithFormat:#"%#%i.png", frame, i];
CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
CCSpriteFrame* frame = [frameCache spriteFrameByName:file];
[frames addObject:frame];
}
// return an animation object from all the sprite animation frames
return [CCAnimation animationWithFrames:frames delay:delay]; //Is there another method I should be using here to set the frame
}
There isn't a built in funcion that does that, but you can simply create your animation and pass it the NSArray starting at the frame you want:
CCAnimation *animation = [CCAnimation animation];
NSArray *offset = [NSArray arrayWithObjects:frame3, frame4, nil];
[animation initWithFrames:offset];
I have one UIView, which I'm using as my main view, and I want to repeat the subview across the screen. How exactly can I do this?
You can look at Core Animation. There is a layer called the CAReplicatorLayer that might help you. Alternatively you can use generic CALayers and set their contents all to the same image. You would just need to figure out the width of your parent view and how big you want each tile to be and then just create CALayers for each tile shifting the position of each new layer depending on your grid dimensions. Something like this:
UIImage *imageToReplicate = [UImage imageNamed:#"tile"];
for (i = 0; i < 10; ++i)
{
for (j=0; j < 10; ++j)
{
CGFloat xPos = 0.0; // Calculate your x position
CGFloat yPos = 0.0; // Calculate your y position
CALayer *layer = [CALayer layer];
[layer setBounds:CGRectMake(0.0f, 0.0f, TILE_WIDTH, TILE_HEIGHT)];
[layer setPosition:CGPointMake(xPos, yPos)];
[layer setContents:(id)[image CGImage]];
[[[self view] layer] addSublayer:layer];
}
}
You'll have to figure out the calculation for each iteration of your layer positions. Remember that by default the anchor point of the layer is its center. You either calculate it by subtracting half of the layer tile size or you can change the anchor point to be a corner instead. For more information on that, take a look at the layer geometry section of the Core Animation documentation.
I am using AtlasSpriteManager and AltasSprite to create frame by fram animation with 1 one file. I wanna write something that at first show a simple picture, without any animation and for example when I touch it, it shows some animation and return to the first position and frame. I just can't show the first frame without animation using this code :
Sprite *checker = [Sprite spriteWithFile:#"test.png"];
float frameWidth = [checker boundingBox].size.width / frameNumber;
float frameHeight = [checker boundingBox].size.height;
AtlasSpriteManager *mgr = [AtlasSpriteManager spriteManagerWithFile:fileName];
AtlasSprite *sprite = [AtlasSprite spriteWithRect:CGRectMake(pos.x, pos.y, frameWidth, frameHeight) spriteManager:mgr];
sprite.position = ccp(pos.x, pos.y);
[mgr addChild:sprite];
[layer addChild:mgr];
AtlasAnimation* animation = [AtlasAnimation animationWithName:#"Animation" delay:delay];
assert( animation != nil );
for(int i = 0; i < frameNumber; i++){
[animation addFrameWithRect:CGRectMake(i * frameWidth, 0, frameWidth, frameHeight)];
}
id action = [Animate actionWithAnimation:animation];
assert( action != nil );
id repeatAction;
if(repeatNumber == 0){
repeatAction = [RepeatForever actionWithAction:action];
}else{
repeatAction = [Repeat actionWithAction:action times:repeatNumber];
}
[sprite runAction:repeatAction];
any idea how to do that?
thanx in advance
Updated Answer
I don't think I understood your question as you intended it.
As I understand now, you have a sprite whih you have an animation for. But when the animation is finished, it doesn't return to the frame that you want the sprite to be set to when standing still.
In our code you use actionWithAnimation:, have you tried setting that to actionWithAnimation:restoreOrigionalFrame: and then set restoreOrigionalFrame part to YES?
That should render the animation, but then when it stops, return to the frame it was before the animation.
Alternatively, you can make the action run, then when it stops, return to a certain frame manually by calling setTextureRect: on the AtlasSprite.
[sprite setTextureRect:CGRectMake( x, y, width, height )];
below this marker is my old answer:
The code that you have now will animate it immediately.
If you want the animation to start on touch, you'll have to check for touches. Then add the code to start the animation in the method that receives the touch.
There is sample code on how to use touches in the cocos2d download.
Basically: make your sprite a TargetedTouchDelegate (or create a new object to do that, but that's a bit of a hassle) and implement -(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
I think that you need CallFunc action combined with Sequence action.
From your code:
}
.....
.....
id action = [Animate actionWithAnimation:animation];
assert( action != nil );
id repeatAction;
if(repeatNumber == 0){
repeatAction = [RepeatForever actionWithAction:action];
}else{
repeatAction = [Repeat actionWithAction:action times:repeatNumber];
}
id actionCallFunc = [CallFunc actionWithTarget:self selector:#selector(resetSprite)];
id actionSequence = [Sequence actions: repeatAction, actionCallFunc, nil];
[sprite runAction:repeatAction];
....
}
-(void)resetSprite{
[sprite runAction:repeatAction];
}
First will be executed your repeatAction and when it ends the actionCallFunc will be executed calling resetSprite method where you can do what you want with your sprite.