cocos2d schedule cannot be called - cocos2d-iphone

I have two schedule in class #A.
first one:
- (id) init ()
{
self = [super init];
if ( self ) {
....
[self schedule:#selector(first:) interval:1.0f];
}
}
second:
- (void) setSomething()
{
...
[self schedule:#selector(second:) interval:1.0/30];
}
the second schedule processed correctly.But the first one can not be called once.
And when I set interval of first schedule from 1.0f to 0.The first one could be called.
How can I do for the first schedule?

Dude,check your method name that was called by first scheduler.It should be like
-(void)first:(id)sender
{
....
}

Related

How to schedule or call a method at random time interval in cocos2d iphone

I want to call a method at Irregular time interval means it should be random time plus i want it in some define range too.
Like : it should call at any second between 3 to 8 .
I tried this one :
[NSTimer scheduledTimerWithInterval: 1.0 target:self selector:#selector(myMethod:) userInfo:nil repeats: YES];
void mymethod()
{
if(arc4random() % 10 == 1)
{
// calling my method here;
}
}
This way , i am not getting randomization which i want.
Any one can please help me on this !!!
Here you can make a scheduler which will get called at random interval.
-(void)randomTimeScheduler{
int time = arc4random()%5;
int nextTimeOfCall = 3+time;
NSLog("it will be called after:%d",nextTimeOfCall);
[self performSelector:#selector(randomTimeScheduler) withObject:self afterDelay:nextTimeOfCall];
}
You have to call it from your class and then it will work as a scheduler. And it has finite interval time 3-8.

My CCTargetedAction runs action twice

In cocos2d v3, I could not find something like CCTargetedAction.
It is required in my project, so I copied code from cocos2d v2.
#interface CCTargetedAction : CCActionInterval
/** This is the target that the action will be forced to run with */
#property(readwrite,nonatomic,retain) id forcedTarget;
#property(readwrite,nonatomic,retain) CCActionFiniteTime* action;
/** Create an action with the specified action and forced target */
+(id)actionWithTarget:(id)target
action:(CCActionFiniteTime*)action;
/** Init an action with the specified action and forced target */
-(id)initWithTarget:(id)target
action:(CCActionFiniteTime*)action;
#end
#implementation CCTargetedAction
+(id)actionWithTarget:(id)target
action:(CCActionFiniteTime*)action
{
return [(CCTargetedAction*)[self alloc] initWithTarget:target
action:action];
}
-(id)initWithTarget:(id)target
action:(CCActionFiniteTime*)action
{
self = [super initWithDuration:action.duration];
if(self)
{
self.forcedTarget = target;
self.action = action;
}
return self;
}
-(id)copyWithZone:(NSZone*)zone
{
CCAction *copy = [(CCTargetedAction*) [[self class] allocWithZone: zone]
initWithTarget:_forcedTarget
action:[_action copy]];
return copy;
}
- (void) startWithTarget:(id)aTarget
{
[super startWithTarget:aTarget];
[_action startWithTarget:_forcedTarget];
}
- (void) stop
{
[_action stop];
}
- (void) update:(CCTime) time
{
[_action update:time];
}
#end
But my CCTargetedAction runs action twice.
-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
CCActionCallBlock* block = [CCActionCallBlock actionWithBlock:^{
CCLOG(#"call block");
}];
CCTargetedAction* action = [CCTargetedAction actionWithTarget:self
action:block];
[self runAction:action];
}
If I touch the screen once, then the log message is output twice.
2014-04-07 22:09:57.439 TargetedActionTest[3924:60b] call block
2014-04-07 22:09:57.455 TargetedActionTest[3924:60b] call block
Why this code runs action twice?
Thank you.
This problem is solved by overwriting -(BOOL)isDone method.
-(BOOL)isDone
{
return [_action isDone];
}
I was referring to this post.
http://cocos2d-x.org/forums/6/topics/39546

Schedule overwriting itself

If the below 'delayingTest' is called N times, I expect it to eventually call doIt N times as well. However this is not the case, it seems as if the schedule overwrites any previous schedule, supposedly having the same selector. Anyway around this?
-(void)delayingTest {
if (_delay) {
[self schedule:#selector(delayingTest) interval:1.0f repeat:0 delay:1.0f];
}
else {
[self doIt];
}
}
one way would be :
dont use _delay as int but bind it with timestamp storing it in NSDate and comparing the timestamps when next time your method gets called.
Try This:
-(void)delayingTest
{
if (_delay)
{
[self unschedule:#selector(delayingTest)];
[self schedule:#selector(delayingTest) interval:1.0f];
}
else
{
[self doIt];
}
}

nsmutablearray not adding objects when called

I have an NSMutable array that I want to add Sprites to so that I can check them if they've hit the wall. I use this code to do so:
NSString *bulletName = [NSString stringWithFormat:#"tank%d_bullet.png", _type];
bullet = [CCSprite spriteWithSpriteFrameName:bulletName];
bullet.tag = _type;
bullet.position = ccpAdd(self.position, ccpMult(_shootVector, _turret.contentSize.height));
CCMoveBy * move = [CCMoveBy actionWithDuration:duration position:actualVector];
CCCallBlockN * call = [CCCallBlockN actionWithBlock:^(CCNode *node) {
[node removeFromParentAndCleanup:YES];
}];
if (!bulletIsGone) {
[self schedule:#selector(updator:) interval:0.01];
}
else {
[self unschedule:#selector(updator:)];
}
[bullet runAction:[CCSequence actions:move, call, nil]];
[_layer.batchNode addChild:bullet];
[bulletsArray addObject:bullet];
if ([bulletsArray objectAtIndex:0] == nil) {
NSLog(#"HELP");
}
NSLog(#"%#", [bulletsArray objectAtIndex:0]);
}
-(void)updator: (ccTime) dt{
for(CCSprite *bulletz in bulletsArray){
NSLog(#"this is the for loop");
CGRect rect1 = CGRectMake(bulletz.position.x - bulletz.contentSize.width/2, bulletz.position.y - bulletz.contentSize.height/2, 20, 20);
if ([_layer isWallAtRect:rect1]) {
NSLog(#"bulletHitWall");
[_layer.batchNode removeChild:bulletz cleanup:NO];
bulletIsGone = YES;
}
}
}
However, when I build and run, I get the console output of '(null)' and 'HELP.' The method before the 'updator' is called from touchesEnded. Can someone see what I'm doing wrong?
Thank you!
Do you initialise the array? That would seem like the most likely reason
Try this in your viewDidLoad method...
- (void)viewDidLoad
{
[super viewDidLoad];
bulletsArray = [NSMutableArray alloc] init];
}
Since NSMutableArray cannot hold nil objects, the only way the condition
[bulletsArray objectAtIndex:0] == nil
could evaluate to true is that bulletsArray is nil. You need to make sure that the array is properly allocated. A typical place to do it is the designated initializer of your class.
Why do you want to add bullets to another array? You already have a batch node that contains them all which is _layer.children.
Are you sure that the array itself (bulletsArray) is not nil? where is it initialized?
Finally you should consider looping with CCARRAY_FOREACH which is more performant.

Callback when Cocos2d CCParticleSystem has finished?

I'd like to run a callback/selector when a Cocos2d CCParticleExplosion is completely finished. How do I do this?
I tried using scheduleOnce with the same duration as the emitter, but that finish too soon since I guess the duration of the emitter controls for how long it will emit new particles, but not how long the complete animation lasts.
Try sequencing the action (using CCSequence) with a CCCAllFunc Action. After one action runs, the other runs, the CCCAllFunc can be assigned to the selector/method of your choice.
Not sure if this is acceptable, but I tested and "it works on my mac".
in CCParticleSystem.h
// experimental
typedef void (^onCompletedBlock)();
#property (readwrite, copy) onCompletedBlock onComplete;
in CCParticleSystem.m
#synthesize onComplete;
in the same file update method,
_particleCount--;
if( _particleCount == 0 && self.onComplete)
{
[self onComplete]();
[[self onComplete] release];
}
if( _particleCount == 0 && _autoRemoveOnFinish ) {
[self unscheduleUpdate];
[_parent removeChild:self cleanup:YES];
return;
}
In your code
particleSystem.autoRemoveOnFinish = YES;
particleSystem.position = ccp(screenSize.width/2, screenSize.height/4);
particleSystem.onComplete = ^
{
NSLog(#"completed ..");
};
again, quite experimental..