IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Programmation d'un tir dans un jeu style shoot'em up vertical


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 447
    Par défaut Programmation d'un tir dans un jeu style shoot'em up vertical
    Bonjour, cela fait plusieurs jours que j'essaye de faire un tire dans mon jeu mais je ne suis pas satisfait du résultat. Pourriez-vous m'aider notamment sur la démarche a suivre pour réaliser un tire, comment le faire en faite ou me faire un début d'algorithme dans les grandes lignes.

    Car après moulte difficulté rencontrer je suis arrivé a un résultat peu satisfaisant en faite je veux que 4 tire soit envoyer que je face une pression ou bien que je reste appuyer sur la touche de tire (V en l'occurrence).
    Le problème c'est que soit j'ai un tire qui part ou 2 tires si je fait une pression, et si je reste appuyer sur la touche de tire alors 1 fois j'ai 2 tires et ensuite 4 tire.
    Je trouve aussi que quand le tire part c'est saccadé.

    Je vous met le jeu en téléchargement si sa vous dit de regarder :ShootHBX.rar

    Je vous met une partie de mon code si vous voulez prendre le temps d'y jeté un oeil :

    Dans le main je vous met juste le code de la boucle qui tourne toute les 20 millisecondes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
      while(stop)
        {  
          timeA  = SDL_GetTicks(); 
          if(timeA-lasttimeA>TIME)
    	{
    	  stop=loop_event(events);
    	  if(ImgScr->NbBallScr)
    	    if(!pause)
    	      {  
    move(BoardSpr,ImgScr,ClashSplit,initSdl,events,time,&count,&SFXsys,&SFXBallBall,&SFXBallScr,&SFXBlastBall,&SFXshoot,i,&gap);
    		blit(BoardSpr,ImgScr,initSdl,time,grid);
    	      }
    	  lasttimeA=timeA;
    	  i++; /*Le i est mis dans move qui aura pour but de lancer dans la fonction move_shootStart les tires */
    	  if(i==ImgScr->NbShootScr)
    	    i=0;
    	}
          pause=events->key[events->tabkey[events->k_p]];
        }
    Ensuite la fonction move :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    void move(Sprites* S,dataImageScr* D, Clash_SplitScr* CS,InitSdl* A,EventsKeyMouse* E,TimeImgAnim** T,bool* count,
    FMOD_SYSTEM** sys, FMOD_SOUND** BallBall,FMOD_SOUND** BallScr,FMOD_SOUND** shoot,FMOD_SOUND** BlastBall,int i,int* gap)
    {
      int nb=0;
      nb=0;
      T=0;
      move_ball(S,D,CS,A,&*sys,&*BallScr);
      if(D->NbBallScr>=2)
        {
          clash_sortBallSplitScr(D);
          clash_ball(S,D,&*sys,&*BallBall);
        }
     
      move_ship(S,D,A,E);
     
      if(E->key[E->tabkey[E->k_v]] && i==0)
        *count=move_shootKey_V(D); /*cette fonction sert à vérifier si on a pas tiré*/
     
      if(*count)
        {
          move_shootStart(S,D,&*sys,&*shoot,gap,i);/*cette fonction a pour but de déclencher le tire quand on appuie sur la touche V le 1er tire par ensuite le 2eme,3eme et 4eme on se sert de i pour dire que toutes les 20 millisecondes on lance le tire suivant quand on arrive au dernier tire on arrête et move shoot prends le relais*/
          if(i==D->NbShootScr-1)
    	{
    	  *count=FALSE;
    	  *gap=0;
    	}
        }
     
      if(!*count)
        move_shoot(S,D,E,count,&*sys,&*shoot); /*move_shoot prends le relai de move_shootStart pour faire donc avancé les tire dans l'écran*/
     
      if(D->shoot->ScrPos!=-1)
        clash_ShootBall(S,D,&*sys,&*BlastBall);
     
      if(D->NbBallScr==0)
        printf("Vous avez gagner\n");
    }
    Voilà merci par avance pour votre aide.

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Ton code est un peu spaghetti. Tu as notamment deux fonctions pour créer des projectiles, qui au final font la même chose.

    C'est un problème intéressant, même si j'ai eu un peu de mal à comprendre ce que tu cherchais à obtenir. Arrête-moi donc si je me trompe : tu veux que lors de l'appui sur la touche de tir (évènement ponctuel), le vaisseau balance une rafale non simultanée de N projectiles, à raison d'un projectile toutes les T millisecondes ?

    Perso lorsque je veux obtenir un truc de ce style :

    • en premier lieu je m'assure d'avoir une fréquence de simulation fixe, décorrélée de la fréquence de dessin / rendu (qui elle est variable) ; ce que ça veut dire c'est : « 60 fois par seconde (par exemple), j'appelle update(), quoiqu'il arrive » (si la machine ne suit pas alors le jeu est ralenti, ou plutôt : le temps y est dilaté) ;
    • j'assigne un identifiant unique (uid, entier non signé) à chaque frame de simulation en les numérotant à partir de zéro ;
    • j'ai une fréquence fixe, je sais donc qu'entre les frames N et N + k, il y a k * T millisecondes d'écart ;
    • j'ai une liste d'évènements futurs triée chronologiquement (les éléments y sont insérés à leur place), chaque évènement étant « taggé » avec la date à laquelle il doit avoir lieu, à savoir l'identifiant du pas de simulation correspondant ;
    • lorsque le vaisseau doit émettre une rafale, j'ajoute N évènements « création de projectile », espacés du nombre de frames requis par la cadence de tir ;
    • à chaque nouveau pas de simulation, je retire de la liste les évènements qui correspondent à cette « date » et je les exécute ; à mesure que la liste d'évènement est ainsi « déroulée », les projectiles auparavant « prévus » sont instanciés.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 447
    Par défaut
    Merci pour ton aide Matt_Houston ; oui c'est exactement ça.
    En faite je voudrais reproduire la même chose que dans le jeu raiden voici une vidéo :

    https://youtu.be/-xSDwcl4wwM

    Je n'arrivais pas à voire comment faire autrement mais avec la marche a suivre que tu m'a données j'y vois un peu plus claire.
    Maintenant le plus difficile va être de bien tout comprendre ce que tu as mis et de voir si j'arrive a y implémenter ce qui est une autre paire de manche.

    Je te remercie beaucoup pour ton aide et le temps que tu as consacré pour me répondre.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 447
    Par défaut
    Voilà j'ai refait mon code c'est pas encore tout a fait ça mais on y arrivera dans le temps:
    Le main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
      while(stop)
        {  
          timeA  = SDL_GetTicks(); 
     
          if(timeA-lasttimeA>TIME)
    	{
    	  stop=loop_event(events);
    	  if(ImgScr->NbBallScr)
    	    {
    	      if(!pause)
    	      {  
    		move(BoardSpr,ImgScr,ClashSplit,initSdl,events,&SFX_sys,&SFX_ClashBallEdgeScr,&SFX_Shoot,&i);
    		blit(BoardSpr,ImgScr,initSdl,time,grid);
    	      }
    	    }
    	  lasttimeA=timeA;
    	}
          pause=events->key[events->tabkey[events->k_p]];
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    void move(Sprites* S,dataImageScr* D, Clash_SplitScr* CS,InitSdl* A,EventsKeyMouse* E,FMOD_SYSTEM** SFX_sys,FMOD_SOUND** ClashBallEdgeScr,FMOD_SOUND** SFX_Shoot,int* i)
    {
      SFX_Shoot=0;
      move_ball(S,D,CS,A,&*SFX_sys,&*ClashBallEdgeScr);
      if(D->NbBallScr>=2)
        {
          clash_sortBallSplitScr(D);
          clash_ball(S,D);
        }
     
      move_ship(S,D,A,E);
     
      if(E->key[E->tabkey[E->k_v]])
        {
          if(*i<D->NbShootScr)
    	{
    	  move_shootStart(S,D,*i);
    	  (*i)++;
    	}
        }
     
      move_shoot(S,D);
      if(move_shootKey_V(D))
        *i=0;
     
      if(D->NbBallScr==0)
        printf("Vous avez gagner\n");
     
    }
    Ps1: Je n'ai pas réussis a enlever move_shoot donc sa fait toujours un peu spagetti
    Ps2: Si quelqu'un veut les sources pour les fonctions move_shootStart et move_shoot dite le moi.

  5. #5
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 226
    Par défaut
    Pour ma part le code est mal pensé et mal séparer du coup normal que cela soit galère.
    Déjà je déconseille d'utiliser SDL_GetTicks(); pour le tir.
    Si tu veux une cadence de tir une simple variable suffit (la cadence dépendra du framerate comme tout les jeux quoi ).


    Il y a deux méthode pour gérer le tir :
    La première optimiser la boucle du bullet , donc ta boucle fera n = nombre de bullet , mais cette méthode est plus 'chiante' vu que ça demande d'échanger certain valeur entre ceux qui sont en dehors du tableau et a l'intérieur.
    La deuxième est plus simple a mettre en place si tu as une idée plus ou moins précise du nombre de bullet a l'écran , tu fait une boucle fixe (je sais pas genre 100) et ensuite tu affiche tout les bullets 'on' (ceux qui sont a l'écran) , ça demande pas un code faramineux et les bullets sont facile a gérer (je l'utilise principalement sur mes jeux en assembleur) , ceux qui sorte de l'écran tu peux les mettre en 'off'.

    Dans les deux cas le bouton du tir est différent , la méthode 1 ne demande que a incrémenter le nombre de bullet (tu décrémente des qu'un bullet sort de l'écran).
    La méthode deux , c'est faire une boucle jusqu’à tu trouve une place libre.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 447
    Par défaut
    Désolé pour la réponse tardive merci Kannagi pour ton aide je vais voir ce que je peux faire.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Aide pour programmer la prise majoritaire dans un jeu de dames
    Par Mehdi017 dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 30/01/2014, 20h52
  2. [WD-2010] Fixer les marges dans un jeu de styles
    Par Tartampionne dans le forum Word
    Réponses: 1
    Dernier message: 21/01/2013, 21h35
  3. Programmation pattern missile pour jeu style shoot'em up
    Par mixka13 dans le forum XNA/Monogame
    Réponses: 7
    Dernier message: 19/05/2012, 14h36
  4. Réponses: 4
    Dernier message: 26/05/2011, 22h30
  5. Programmation d'une fonction dans Rn
    Par simone.51 dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 12/11/2004, 11h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo