views:

46

answers:

3

Hello!

Sorry to bother, but I am in a bit of a pickle and I was wondering if anyone here could give me a hand.

I am currently designing a game in which enemies appear on the left side of the screen (out of boundaries) and move to the right. I have used a number of codes (this is using Sparrow Framework) and pretty much the number of enemies increases as you beat them. i.e. lvl 1-> 1 enemy, lvl 2-> 2 enemies, lvl3-> 3 enemies, etc...

I am having some trouble though with producing enemies. I have them appearing on 1 of 5 set paths (path numbers in NSMutableArray), selected by a random number generator, however they often appear on the same path, 1 on top of the other.

To produce the enemies, i am running a number of methods: addEnemy -> produces the enemies (animations) which then travel from left to right. onTouchEnemy -> if i touch the enemy, they die. activates drawEnemies drawEnemies -> calls addEnemy a number of times equal to your lvl. coded as:

for(int i = 0; i < level; i++){
  [self performSelector:@selector(addEnemy) withObject:nil afterDelay:3.0];
}

Is there a way to program so that there is a delay between activating the produce enemies method? I tried this afterDelay, but for some reason the program just ignores the 3 second delay and just produces enemies all in 1 go. This is rather irritating since i would like them to appear in a more orderly fashion.

I thank anyone willing to give me a hand with this. Sjkato.

A: 

Try to look through NSTimer class.
There are some methods that provide ability to perform selectors with predefined delay and loop conditions.

NR4TR
Thanks for the tip! I'll test out Jasarien's suggested code, then have a closer look at the NSTimer class.
SKato
A: 

Did you mean to do this, with a extra "*i" at the end? Like this:

for(int i = 0; i < level; i++){
    [self performSelector:@selector(addEnemy) withObject:nil afterDelay:3.0 * i];
}
Graham Perks
Er, sorry, but you kinda lost me with the '*i' added to the end of your code...do you mean that this will cause the program to delay at different times rather than just fire off all the addEnemy commands after 3 seconds?
SKato
Yes, that's exactly what I mean. You said they were all appearing at the same time. I thought you were maybe trying to stagger each enemy. In your code they'd all appear at the 3 second point.Note that performSelector:withObject:afterDelay: returns immediately. It doesn't pause for 3 seconds. So your code is queuing up a bunch of addEnemy calls which will all get called at the same time, 3 seconds hence. The "* i" will stagger them out, 3 seconds apart, if that's what you want.The method works fine, no need to switch to NSTimer.
Graham Perks
Thank you so much! I hadnt realised that you could do this and make the command work. I was having some issues trying to make Jasarien's suggestion work, but I wasnt sure how much of my entire code i would have to change to make it work. This is much simpler...thank you so much!
SKato
Great! Glad it worked. BTW it's normal on stackoverflow to click the up arrow or checkbox on responses you find helpful :) There are several on this page that might qualify. That way you're more likely to have questions answered in the future.
Graham Perks
A: 

performSelector:withObject:afterDelay: appears to ignore its delay because of the way the code executes. That for loop will iterate almost instantly, queuing up 3 calls to the addEnemy method. After 3 seconds the addEnemy methods execute, almost all at the same time.

To get a better result, you should look at NSTimer. You could set an interval of 3 seconds and tell it to repeat (you can invalidate the timer after the desired number of enemies has been produced).

Something like:

// creates and returns a new timer
// the timer is retained by the run loop for as long as it is valid
// invalidating the timer will cause the runloop to release it.
myTimer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                 target:self
                               selector:@selector(addEnemy)
                               userInfo:nil
                                repeats:YES];

This will cause the addEnemy method to be fired once every 3 seconds. You should keep a tally of how many enemies you have already made, and after the last one is made, stop the timer so that it doesn't fire again.

if (numberOfDesiredEnemies == numberOfEnemiesProduced)
{
    [myTimer invalidate], timer = nil;
}
Jasarien
Thank you very much for the responce. I think I understand the delay code a little better now that my suspicions were confirmed. I will try this code out then try out a varient to see if i can spice things up a little :)
SKato