Se connecter avec
S'enregistrer | Connectez-vous

Probleme avec FMOD en C

Dernière réponse : dans Programmation

slt tous le monde je tente un petit exercice pour reviser mes cours de C mais j'ai un petit probleme pour jouer un son court avec FMOD c'est un tir de fusil, j'utilise la SDL : avec SDL_WaitEvent sa marche mais avec SDL_PollEvent le son déraille, en gros au lieu de "PAN" sa fait "Pranzazing".... voici ma boucle while, je ne peux pas poster le code entier c'est trop long....

/* EVENEMENTS */
while (continuer == 1)

{// debut WHILE

if (pause ==0)
SDL_ShowCursor(SDL_DISABLE);


else
SDL_ShowCursor(SDL_ENABLE);

SDL_PollEvent (& event);
switch (event.type)
{// début SWITCH

/**/ case SDL_QUIT:
/**/ continuer =0;
/**/ break;

/**/ case SDL_KEYDOWN:
/**/ switch(event.key.keysym.sym)
{//evenement clavier

/**/ case SDLK_ESCAPE:
/**/ continuer = 0 ;
/**/ break;


/**/ case SDLK_p:


/**/ pause = 1;
/**/ posViseurPause.x = posViseur.x;
/**/ posViseurPause.y = posViseur.y;

/**/ break;
/**/
/**/ case SDLK_o:

/**/ if (pause != 0) {//début if en pause
/**/ SDL_WarpMouse(posViseurPause.x+viseur-> w/2,posViseurPause.y+viseur-> h/2);

/**/ pause =0;
/**/
}//fin if en pause
}//fin evenement clavier retour evenement souris et autre
/**/ break;



/**/ if (pause == 0) { // debut if ! en pause

/**/ case SDL_MOUSEMOTION:// le pointeur de la souris "devient" le viseur

/**/ if (event.motion.x < 640 - viseur-> w/2 )//attribut les coordonnées x du viseur tant qu'il est dans la fenetre
/**/ posViseur.x=event.motion.x - viseur->h/2;


/**/ if (event.motion.y < 480 - viseur-> h/2 )//attribut les coordonnées y du viseur tant qu'il est dans la fenetre
/**/ posViseur.y=event.motion.y - viseur->w/2;

/**/ /* le fusil suit le viseur*/
/**/ posfusil.x = posViseur.x+4;
/**/ posfusil.y = 480- fusil->h;


/**/ break;


/**/ case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT)
{
/**/ if ( l < 1001 && pause == 0)
{
/**/ posimpact[l].x = event.button.x - impact->w /2;
/**/ posimpact[l].y = event.button.y - impact->h /2;

/**/ FSOUND_PlaySound(FSOUND_FREE, tir);/* Jouer le son d'un coup de feu */
}

i++;

/**/ break;
}
}//fin if ! en pause
}/* < /// SWITCH > */

if (pause == 0)
{

for(m=0;m<1000;m++)
{
SDL_BlitSurface(impact, NULL, ecranImpact, &posimpact[m]);
}

SDL_FillRect(ecran, NULL,SDL_MapRGB(ecran->format, 0,255,255)); // efface l'ecran precedent pour une animation futur


SDL_BlitSurface(fusil, NULL, ecran, &posfusil);

if (posEnnemis.x < 0)
SDL_BlitSurface(ennemis, &ennemisT , ecran, &posEnnemis);

if (posEnnemis.x > 0)
SDL_BlitSurface(ennemis, NULL , ecran, &posEnnemis);

SDL_BlitSurface(ecranImpact, NULL , ecran, &posEcranImpact);

SDL_BlitSurface(viseur, NULL, ecran, &posViseur);

SDL_Flip(ecran);

}


}/* fin de WHILE => evenement */

Autres pages sur : probleme fmod

Lassé par la pub ? Créez un compte
Expert Programmation

Est-ce que la fonction rend la main dessuite (asynchrone) ? ou est-ce qu'il faut que le son soit terminé pour que la fonction retourne (synchrone) ?
Si c'est asynchrone, il faut s'assurer que le son ne soit pas joué plusieurs fois.

en essayant d'utiliser ta fonction je me suis rendu compte d'un truc
case SDL_MOUSEBUTTONDOWN:
c'est peut être pas un probleme de son en fin de compte mais d'evenement si je reste appuyé sur le clic gauche le son est joué a chaque tours dans la boucle wihle mais si j'appuie trés vite le son est joué moins de fois j'ai essayé avec
case SDL_MOUSEBUTTONUP:
le resultat est un peu mieux mais des fois le son est joué plusieur fois et si je reste appuyé sur le clic gauche il n'y a pas de son, je le relache et là le son ne s'arrête plus...
Expert Programmation

déclare 2 variables booléennes:

  1. int isPlaying = 0;
  2. int channelHandle = 0;


la fonction FSOUND_PlaySound() retourne le channel handler, mémorise-le lors de l'appel, indique qu'un son est joué.
Comme ça, pour la boucle suivante, tu testes si un son est joué, et s'il est joué sur le canal indiqué. Lorsque le son est terminé, il faut penser à remettre à 0.

  1. /* Tester si un son a été déclenché */
  2. if (isPlaying)
  3. {
  4.  
  5. /* Tester si le son s'est arrêté */
  6. if (!FSOUND_IsPlaying(channelHandle))
  7. {
  8. /* Arrêt du son */
  9. isPlaying = 0;
  10. }
  11. }
  12.  
  13. /* Tester si aucun son n'est joué */
  14. if (!isPlaying)
  15. {
  16. /* Démarrage du son et répération du channel utilisé */
  17. channelHandle = FSOUND_PlaySound(FSOUND_FREE, tir);
  18.  
  19. /* Son démarré */
  20. isPlaying = 1;
  21. }

J'ai décomposé les if pour mieux expliquer. On peut faire mieux.
Expert Programmation

Oui, alors comme tous les jeu, il faut mettre un temps d'attente avant de refaire une action. Avec SDL_GetTicks(), tu fais un timer que tu initialises après le play sound.
Lorsque ça dépasse un certain temps (donné en ms), tu considères que l'on peut à nouveau tirer.
A la limite, tu peux faire un FSOUND_StopSound() pour arrêter l'ancien son avant de reprendre un nouveau.

Sinon, pour le son, tu utilise fmod, c'est bien, mais c'est aussi géré par SDL:
http://lazyfoo.net/SDL_tutorials/lesson11/index.php
Tu as peut-être moins de fonctionnalité.

oui mais d'aprés le site où j'apprend la sdl ne gere pas trés bien le son donc on est parti vers FMOD ^^

ça sa va empecher le blit de l'impact non ? je ne peux pas faire en sorte que le son se joue même si un blit est trop rapproché d'un autre ? Sa fait quelque chose si on met un timer dans une boucle ? un timer est appelé quoi qu'il arrive même a l'exterrieur d'une boucle mais je n'ai jamais vu de timer dans une boucle while, sa va l'appeler plusieurs fois non ?
Expert Programmation

En fait le principe c'est de ne jamais bloquer l'intérieur d'un boucle évènementielle pour traiter tout autre évènement. Donc, s'il faut faire une attente, il faut se contenter de laisser passer sans rien faire jusqu'à ce que le temps soit écoulé.
Pour ça, quand ton tir se déclenche tu mets une variable:
  1. tirTempsInitial = SDL_GetTicks();

Et dans chaque passage, si tu veux savoir si tu es sorti du temps d'attente, il te suffit de faire le test:
  1. tirTempsCourant = SDL_GetTicks();
  2. if( tirTempsCourant - tirTempsInitial > TIR_DUREE )

où tu auras définit la durée en constante en millisecondes:
  1. #define TIR_DUREE 100


ça permet de verrouiller le tir toutes les 100ms.
après si le son n'est pas tiré, tu peux arrêter le son précédent comme j'avais indiqué, mais tu peux aussi accumuler les sons (je pense que ça utilise un nouveau numéro de canal).

Si tu utilise un SDL_Delay(), ta boucle évènementielle va se bloquer, donc aucun évènement de souris ou clavier, ni rafraichissement d'affichage ne sera effectué. Si tu n'en fais qu'un d'une centaine de ms, ça ne se verra pas, mais lorsque le jeu se complexifiera petit à petit, tu verras des problème (injouable), car il faut rester dans du temps réel.
Lassé par la pub ? Créez un compte
Tom's guide dans le monde