views:

255

answers:

1

Hello,

Making a new shooter game here in the vein of "Galaga" (my fav shooter game growing up).

Here's the code I have for bullet physics:

-(IBAction)shootBullet:(id)sender{
imgBullet.hidden = NO;
timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(fireBullet) userInfo:Nil repeats:YES];
}

-(void)fireBullet{
imgBullet.center = CGPointMake(imgBullet.center.x + bulletVelocity.x , imgBullet.center.y + bulletVelocity.y);
if(imgBullet.center.y <= 0){
 imgBullet.hidden = YES;
 imgBullet.center = self.view.center;
 [timer invalidate];
}
}

Anyway, the obvious issue is that once the bullet leaves the screen, its center is being reset, so I'm reusing the same bullet for each press of the "fire" button.

Ideally, I would like the user to be able to spam the "fire" button without causing the program to crash. How would I tinker this existing code so that a bullet object would spawn on the button press each time, and then despawn after it exits the screen, or collides with an enemy?

Thank you for any assistance you can offer!

+3  A: 

You certainly do not want a timer firing for EVERY bullet, asteroid, explosion animation etc., this would be horrendous.

Most games are based on what is termed a finite-state-machine. This is in essence a method that keeps track of the game state (i.e. PLAYING, END_GAME, WAITING_FOR_OTHERPLAYERS) and makes decisions based on that. This method would get called over and over again via ONE timer, much like you have done for the bullet. I would suggest setting up your game like that. Now about those bullets, when the player hits the fire button, add another bullet to an array of things-that-need-to-adjust-themselves-over-time. Then each time through the game loop, when the state dictates, iterate through them and tell them to "updateYourself". This would also be where you would do your collision detection and start explosion animations, remove objects that have gone off-screen etc.

Hope that helps,

Kenny

Update: some pseudo code (i.e. will not compile) that should explain things better. Note that I always like to pass the game time around so that an object knows nothing of the ACTUAL time, this is good practice as it not only allows for reanimating of a game session, great for debugging and sometimes can make for a neat feature, it also means all objects get the SAME time, not milliseconds different than the first object based on where it is in the array. HOT TIP of the DAY!! Woo hoo!!

// implementation in MainGame class

  // After application has had its lunch....
- (void) applicationDidFinishLunching {
    gameTimer = [NSTimer scheduledTimerWithTimeInterval:GAMETIME_INTERVAL target:self selector:@selector(myGameLoop)    userInfo:nil repeats:TRUE];
}

- (void) startGame {
    gameState = PLAYING;
// And most likely a whole bunch of other stuff
}

NSMutableArray * mTransientObjects;

- (void) fireButtonPressed:(float) atY andTime:(NSTimeInterval) fireTime {
    // I will assume only a "Y" variable for this game, Galaga style.
    Bullet * aBullet = [[Bullet alloc] initWithY:atY atTime:fireTime];
    [mTransientObjects addObject:aBullet];

    [aBullet release];
}

// myGameLoop is called via the timer above firing at whatever interval makes sense for your game
- (void) myGameLoop {

switch (gameState) {
    case PLAYING:
        for (nextObject in mTransientObjects)
            [nextObject updateYourself:gameTime];

        // Now check for dead object, add explosions to mTransientObjects
        // Remove dead things, add anything new etc.
            etc.
}

// implementation in Bullet subclass
// Bullet is SubClass of your overall Sprite class
- (void) updateYourself:(NSTimerInterval) timeInterval  {
// Do any movement, change of animation frame, start sound....etc. etc.
}
Kenny
I understand the issue of gamestates, for sure. That shouldn't be a problem.However, I'm still a little confused about your description about what should happen when the user presses the "fire" button. Is there a way you could explain it in a little more detail? Thank you for your help so far!
Still having issues... mind giving me a little more explanation, please? :P
Still a little confused. :(I'm trying to figure out why the array is implemented as well as what it's supposed to do. Mind providing a little more detail? I understand the rest of the pseudo-code pretty well. Also, is the "fire button pressed" method supposed to represent the IBAction?Thanks!
First question: Why the array is implemented, and what it's supposed to do. - I guess a question may be the best way to achieve understanding. You have an unknown number of objects of the same class, and need to perform a specific action on each of those over time. What data structures or design pattern would solve this problem?Fire button pressed can be an IBAction if you want to use Interface Builder to connect up your UI. But it was more to show the idea of creating a bullet and placing it in the array of sprites.
Kenny