3 votes

Jeu de tir sur iPhone : la physique des balles !

Je crée ici un nouveau jeu de tir dans la veine de "Galaga" (mon jeu de tir préféré en grandissant).

Voici le code que j'ai pour la physique des balles :

-(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];
}
}

Quoi qu'il en soit, le problème évident est qu'une fois que la balle quitte l'écran, son centre est réinitialisé, ce qui fait que je réutilise la même balle à chaque fois que j'appuie sur le bouton "feu".

Idéalement, je voudrais que l'utilisateur puisse spammer le bouton "fire" sans faire planter le programme. Comment modifier le code existant pour qu'un objet balle apparaisse à chaque fois que l'on appuie sur le bouton, puis disparaisse après avoir quitté l'écran ou être entré en collision avec un ennemi ?

Merci de toute l'aide que vous pourrez m'apporter !

3voto

gnasher Points 1283

Vous ne voulez certainement pas qu'une minuterie se déclenche pour CHAQUE balle, astéroïde, animation d'explosion, etc.

La plupart des jeux sont basés sur ce que l'on appelle une machine à états finis. Il s'agit essentiellement d'une méthode qui garde trace de l'état du jeu (c'est-à-dire PLAYING, END_GAME, WAITING_FOR_OTHERPLAYERS) et prend des décisions en fonction de cela. Cette méthode serait appelée encore et encore via UN timer, comme vous l'avez fait pour la balle. Je vous suggère de configurer votre jeu de cette façon. Maintenant, à propos de ces balles, lorsque le joueur appuie sur le bouton de tir, ajoutez une autre balle à un tableau de choses qui doivent s'ajuster au fil du temps. Ensuite, à chaque fois que la boucle de jeu est activée, lorsque l'état l'exige, parcourez-les et dites-leur de "se mettre à jour". C'est également à ce moment-là que vous ferez la détection des collisions, que vous lancerez les animations d'explosion, que vous retirerez les objets qui sont sortis de l'écran, etc.

J'espère que cela vous aidera,

Kenny

Mise à jour : un pseudo code (qui ne compilera pas) qui devrait mieux expliquer les choses. Notez que j'aime toujours faire passer le temps de jeu afin qu'un objet ne connaisse pas le temps réel, c'est une bonne pratique car cela permet non seulement de réanimer une session de jeu, ce qui est excellent pour le débogage et peut parfois créer une fonctionnalité intéressante, mais cela signifie aussi que tous les objets ont le MÊME temps, et non pas des millisecondes différentes du premier objet en fonction de sa position dans le tableau. 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.
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X