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.
Related
I have CCMoveTo action on sprite, which is moving it from one point to another. When user hits a button the sprite should slow down with ease and continue moving to target location with new speed. I have no clue how to make this happen.
Update. Actually I replaced CCMoveTo with CCMoveBy but question still same.
With the current implementation of CCEaseIn/CCEaseOut actions, you can only ease the rate of actions from and to zero. This means that if you ease CCMoveBy/CCMoveTo they will ease the movement speed from/to a standstill.
However, starting from cocos2d 2.1 CCMoveBy/CCMoveTo are stackable. With this feature you can implement a workaround that results in the effect you want.
Setup and simulataneously run two CCMoveBy actions for the sprite: actionA will have the slower movement speed that you get after the button press. actionB will have the speed corresponding to the difference of the faster speed and the slower speed.
Then, when the user presses the button, you can CCEeaseOut actionB (stop CCMoveBy, and then launch it again with the desired CCEaseOut). This will look like the sprite eases from the movement speed of actionA + actionB to the speed of actionA.
Despite this explanation, if you are implementing game controls that you want to precisely fine tune, it might be a better idea to avoid CCActions and just update the sprite position frame-by-frame by implementing custom movement code.
You can use the EaseIn/Out action to get that effect :
id action = [CCMoveTo actionWithDuration:2 position:ccp(100,100)];
id ease = [CCEaseIn actionWithAction:action rate:2];
[sprite runAction: ease];
Taken from here
You can find different types of easing to suit your needs .
To dynamically change the speed of a CCMoveBy/CCMoveTo, there is a CCSpeed action you can implement.
First, when adding the CCMoveBy action, wrap it in a CCSpeed action as follows:
CCSpeed *action = [CCSpeed actionWithAction:[CCMoveBy actionWithDuration:myDuration position:ccp(xPos,yPos)] speed:1];
action.tag = 42;
[mySprite runAction:action];
Then, when you wish to modify the speed, obtain the CCSpeed action and modify it:
CCSpeed *action = (CCSpeed*)[mySprite getActionByTag:42];
[action setSpeed:6];
CGPoint startPoint = ccp(10,100);
CGPoint endPoint = ccp(300,100);
float fastTime = 5.f;
CCSprite *sp = [CCSprite spriteWithFile:#"sprite.png"];
sp.position = ccp(10,100);
[self addChild:sp];
[sp runAction:[CCMoveTo actionWithDuration:fastTime position:endPoint]];
//on hit
float slowTime = 10.f;
[sp stopAllActions];
float newSlowTime = ccpDistance(sp.position, endPoint)*slowTime/ccpDistance(startPoint, endPoint);
[sp runAction:[CCMoveTo actionWithDuration:newSlowTime position:endPoint]];
you can replace the ccmoveto action by ccactionmoveto like:
CCActionMoveTo *mAction = [CCActionMoveTo actionWithDuration:0.2f position:_selectedSpritePos];
[_selectedSprite stopAllActions];
[_selectedSprite runAction:mAction];
I was able to call those methods at run time on a CCSprite object, now that I decided to batch it in a CCSpriteBatchNode it doesn't seem to work anymore:
sprt = [CCSprite spriteWithSpriteFrameName:#"sprt.png"];
sprt.anchorPoint = CGPointMake(0.5f, 0.5f);
sprt.position = CGPointMake(40.0f, 60.0f);
[batchNode addChild:sprt z:-1]; // It used to work when I was simply "adding as child" the sprt object, I guess now doesn't set the order anymore because somehow the CCSpriteBatch node doesn't allow the re-ordering of child added to it
CCCallFunc *callback = [CCCallFunc actionWithTarget:self selector:#selector(moveBackwards)];
CCCallFunc *callback2 = [CCCallFunc actionWithTarget:self selector:#selector(moveForward)];
[sprt runAction: [CCRepeatForever actionWithAction: [CCSequence actions: callback2, callback , nil]]];
-(void) moveBackwards
{
[sprt setZOrder:-1];
}
-(void) moveForward
{
[sprt setZOrder:1];
}
If you have a CCSpriteBatchNode, you have to consider all the CCSprite to be on the same layer (the spritebatch node).
This means that sprites in a sprite batch node can change their z order relative to other sprites in the sprite batch node, but you can not change the z order to make a sprite-batched sprite appear behind or in front of another node that is not a child of the sprite's CCSpriteBatchNode.
I'm pretty sure this is the problem you've run into. If you have trouble grasping this, consider the CCSpriteBatchNode has the same behavior regarding z ordering as a CCLayer (respectively any other node but devs seem to be hung up on CCLayer as the only/main layering construct). Maybe that makes it easier to understand.
Just in case someone else runs across this issue, the following will work to reorder the sprite...
[self.parent reorderChild:self z:x];
Perhaps this question have been repeated many time, but I couldn't found helpful material. Also this is my first project in cocos2D, i want to implement the ProgressBar, CCProgressTimer in cocos2D. I have two sprites, first is moving and the second one is the player (to which you can move), If user successfully eat the first moving object then the progress should be incremented else if it misses then the progress will be decremented. I need your help. Thanks in advance.
Here is my code I used for rounded CCProgressTimers (it looks like clock). You possibly need to have a background sprite and a "movable" sprite above background sprite.
CCSprite *movableSprite = [CCSprite spriteWithFile:#"health100.png"];
CCProgressTimer *healthBar = [CCProgressTimer progressWithSprite:movableSprite];
healthBar.type = kCCProgressTimerTypeRadial; // This is for round progress timer. Possible value for horizontal bar will be kCCProgressTimerTypeHorizontalBarLR
healthBar.midpoint = ccp(0,0.5); // Here is where all magic is
healthBar.barChangeRate = ccp(1, 0); // If you need horizontal bar progress play with these parameters.
// Here we will start an animation process.
// You can do it without animation just setting up healthBar.progress = 45.0f; (45%)
[healthBar runAction:[CCProgressFromTo actionWithDuration:2.0f from:0.0f to:100.0f]];
healthBar.position = ccp(100, 100); // It's your position
[self addChild:healthBar];
I thought doing a simple animation would be easy but is is taking hours and Im not getting even close to have the expected effect...
I need to simulate a simple Flash Motion Tween like for iphone/ipad using xcode
this is the desired effect: http://www.swfcabin.com/open/1340330187
I already tried setup a timer adding X position and it doens't get the same effect, my cooworkers suggested me cocos 2d to do this using actions and sprites, which might would be fine although I wouldn't like to third party frameworks, but if there is a way to do the same with cocos I would definitively use it.
Does anybody have any suggestions, I feel like it might be simpler than I thought
thanks all
If there is no troubles to you, that you will have to do it insinge OpenGL view, it is really very simple. To show some info, you need CCLabel class. To change it's position, you need CCMoveTo/CCMoveBy action, to change opacity, you need CCFadeTo/CCFadeIn/CCFadeOut actions, to make delay you need CCDelayTime. To make it all work together you need CCSpawn and CCSequence.
CCSpawn will run several actions at the same time(for example fade in and move from right to the center), CCSequence will run several actions one by one (sequence to fade in + move to center, delay for same time, sequence to fade out + move from center to the left). Then you should only schedule method, that will create labels and run actions on them. In code it will be something like
lets define full animation time
#define ANIMATION_TIME 4.f
schedule method in any place you want to start animation
[self schedule:#selector(runNextMessage) interval:ANIMATION_TIME];
it will call runNextMessage method every ANIMATION_TIME seconds
- (void) runNextMesage
{
NSString* message = //get next message
CCLabelTTF* label = [CCLabelTTF labelWithString:message
dimensions:desiredDimensionsOfTheLabel
alignment:UITextAlignmentLeft
lineBreakMode:UILineBreakModeWordWrap
fontName:#"Arial"
fontSize:20.f];
CGSize winSize = [[CCDirector sharedDirector] winSize];
// place the label out the right border
[label setPosition: ccp(winSize.width + label.contentSize.width, winSize.height / 2)];
// adding it to the screen
[self addChild:label];
ccTime spawnTime = ANIMATION_TIME / 3;
// create actions to run
id appearSpawn = [CCAction actionOne:[CCMoveTo actionWithDuration:spawnTime]
two:[CCFadeIn actionWithDuration:spawnTime]];
// create show action and disappear action
// create result sequence
id sequence = [CCSequence actions: appearSpawn, showAction, disappearAction, nil];
[label runAction: sequence];
}
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];