So I have a selector that need to be perform after certain amount of delay / interval, and I still can't find the solution. Put CCDelayTime before the CCCallFunc in CCSequence doesn't work. But it's working at simply put something like schedule:interval: or performselector:afterdelay.
if (shootDelay > kBlastBombLaunchingDelay) {
[self createFireProgressBar];
action = [CCSequence actions:
[CCDelayTime actionWithDuration: kBlastBombLaunchingDelay],
[CCCallFunc actionWithTarget:self selector:#selector(launchBomb)],
nil];
//[self performSelector:#selector(launchBomb) withObject:nil afterDelay:kBlastBombLaunchingDelay];
//[self schedule:#selector(launchBomb) interval:kBlastBombLaunchingDelay];
shootDelay = 0;
}
[self runAction:action];
Somehow, the selector launchBomb is not called. Sorry for the silly question.
You don't seem to have called:
[self runAction:action];
User found own solution
I think I've found the solution. Just like I said earlier, it's a silly question, the error was because of my messy algorithm. Put a lower value than kBlastBombLaunchingDelay for the CCDelayTime and change the if position to the statement which change my hero state. And it works now.
Related
I've got a problem in my current game.
I'm trying to move a sprite based on the movement of a other physic body, for a map. This is my code:
...
NSMutableArray *mapObjetcs = [[[NSMutableArray alloc]init]autorelease];
[mapObjetcs addObject:swordman];
[mapObjetcs addObject:icon];
CCCallFuncND* iconMap = [CCCallFuncND actionWithTarget:self selector:#selector(mapLoc:mapObj:) data:mapObjetcs];
CCSequence* iconMapSequence = [CCSequence actions:[CCDelayTime actionWithDuration:1.0f/60.0f], iconMap, nil];;
CCRepeatForever* iconRef = [CCRepeatForever actionWithAction:iconMapSequence];
[self runAction:iconRef];
}
-(void) mapLoc:(ccTime)delta mapObj:(NSMutableArray*)mapObj
{
GB2Sprite *swordmanTemp = (GB2Sprite*)[mapObj objectAtIndex:0];
CCSprite *iconTemp = (CCSprite*)[mapObj objectAtIndex:1];
CGPoint swordmanPos = [swordmanTemp ccPosition];
float pos = (swordmanPos.x/convFactor)+65;
iconTemp.position = ccp(pos, 290);
}
Every time i run the code with the CCRepeatForever the games freezes, if i run the code without the CCRepeatForever the game run grat but dont refresh the icon in map.
Can anybody help me??? Thanks
Its a problem with running CCRepeatForever on layer itself.. Ofcourse it will freeze the game.. You can try for alternate solution I guess.. Instead of using a separate CCRepeatForever loop, use the update method of your layer.. As its already doing same thing that you want to do with your own action..
Another solution is make a same CCRepeatForever for your icon sprite.. and in its CCCallFuncND take the position of other object....
Hope this helps.. Try yourself.. If it doesn't work.. I'll try 2 give you code... Don't run CCRepeatForever Loop on your layer itself.. :)
To avoud such actions you can simply schedule some method with needed interval. smth like
[self schedule: #selector(methodToBeCalled) interval: intervalInSeconds];
just don't forget to unschedule it later
I'm using CCSequence Actions and I want my sprite to hold at a specific action while touch and hold and continue the sequence once the touch is ended.
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{
id downward = [CCRotateTo actionWithDuration:0.1 angle:45];
id straight = [CCRotateTo actionWithDuration:0.1 angle:0];
id stable = [CCSequence actionWithDuration:1.0];
id upward = [CCRotateTo actionWithDuration:0.1 angle:-45];
id Seq = [CCSequence actions:downward, straight, stable, upward, nil];
[mySprite runAction:Seq];
}
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event{
}
I want this "id stable = [CCSequence actionWithDuration:1.0];" replaced with a float of time interval while the Touch is on Hold. And reset it when the touch ends.
Any help is much appreciated.
If i recall well you should be able to set a tag to your action (setTag).
You could set the tag in ccTouchBegan and retrieve this particular action from its node using this tag in ccTouchEnded, which would allow you to pause, terminate, or replace the action as needed.
I have a CCSprite called sprite that is a child of a CCLayer called movingLayer that is itself a child of the current CCLayer running my game logic, so it is self in this case. movingLayer is moving back and forth across the screen in a repeat forever action and sprite is riding along on it. I want to get sprite to "get off" of movingLayer and "get on" to self where it can do some actions of its own.
When I try to do this, I need to tell movingLayer to remove sprite and self to add sprite. This is what I did...
- (void)attack:(id)sender
{
[sprite stopAllActions];
[movingLayer removeChild:sprite cleanup:YES];
[self addChild:sprite z:1];
CGFloat distance = ccpDistance(sprite.position, ccp(sprite.position.x, -sprite.contentSize.height/2));
id goDown = [CCMoveTo actionWithDuration:distance/moveDuration position:ccp(sprite.position.x, -sprite.contentSize.height/2)];
id repeatDown = [CCRepeatForever actionWithAction:[CCSequence actions:[CCMoveTo actionWithDuration:0 position:ccp(sprite.position.x, sprite.contentSize.height/2+self.contentSize.height)], [CCMoveTo actionWithDuration:moveDuration position:ccp(sprite.position.x, -sprite.contentSize.height/2)], nil]];
id attackAction = [CCSequence actions:goDown, repeatDown, nil];
[sprite runAction:attackAction];
}
I think stopAllActions is redundant, but that's not the problem. If I remove sprite from movingLayer before adding it to self I crash for accessing a zombie, and if I try to add it to self first, I crash for trying to add something already added.
Have you tried setting cleanup to NO?
Alternatively, try to retain sprite before you remove it from movingLayer, then release it when you're done with it:
[sprite retain];
[movingLayer removeChild:sprite cleanup:YES];
[self addChild:sprite z:1];
[sprite release];
I have 3 question.
How to keep fps rate constant(almost) in cocos2d.When lots of CCSprite created and removed within a small interval like (5-8) per second is it possible to keep frame rate lmost constant??
Is [self removeChild:sprite cleanup:YES] is enough or I should also use
CCTexture2D *texture = [sprite texture]; [[CCTextureCache sharedTextureCache] removeTexture: texture];
The following Part of code is responsible for my frame drop.How to accomplish same task in better way?
id fadeout = [CCFadeOut actionWithDuration:1.4f];
id call = [CCCallFunc actionWithTarget:self
selector:#selector(RemoveSmashedSprite:)];
CCSequence* sequence= [CCSequence
actions:fadeout, call, nil];
[smash runAction:sequence];
... and...
> -(void)RemoveSmashedSprite:(id)sender
{
CCSprite *sp = (CCSprite *)sender;
[self removeChild:sp cleanup:YES];
}
This is called 5-8 times per second. So the frame rate goes down. Can any one help me?
You shouldn't remove textures if you're going to reuse them in the short term. It would only benefit memory while having a great drawback in performance.
To maintain a constant frame rate you could try reusing the sprites instead of creating and removing them. Instead of calling removeChild you could set visible = NO and add it to an array of unused sprites. Then when you need a new of these sprites you check if there is any in that unused array and only create a new one if it's empty. This way you would minimize the amount of sprites created and destroyed.
Change this:
id call = [CCCallFunc actionWithTarget:self selector:#selector(RemoveSmashedSprite:)];
Into this:
id call = [CCCallFuncN actionWithTarget:self selector:#selector(RemoveSmashedSprite:)];
You can use remove action as your last action, instead of CCCallFunc.
id action = [CCActionRemove action];
This action will remove the node running this action from its parent
i am spending a lot for my time for a simple things i think.I want to hide and show a sprite
in scene.
myS = [CCSprite spriteWithFile:#"Background_Pause_pad.png"];
[myS setPosition:ccp(384,470)];
myS.opacity = 0;
[self addChild:myS z:1];
and when i need to appear it..
[myS runAction:[CCFadeIn actionWithDuration:1]];
and hide it
[myS runAction:[CCFadeOut actionWithDuration:1]];
but it does not work.....can anyone plz help??
Why do you use a Sequence for one action ?
You have to choose the animation you want !
E.g : if you choose CCFadeIn
[mySprite runAction:[CCFadeIn actionWithDuration:0.5f]];
I think you can try the below stuff of the code. It would work for you
id action1 = [CCFadeIn actionWithDuration:1];
id action2 = [CCDelayTime actionWithDuration:1];
id action3 = [CCFadeOut actionWithDuration:1];
[myS runAction:[CCSequence actions:action1,action2,action3,nil]];
As you need the fadein fadeout action it would generate it and display the Same.