Animation d'une balle avec du son  
Animation d'une balle avec du son

  -- Le site --
· News
· Moi
· Liens
·
 Forum
· Me Contacter

  -- Mes projets sur TI --
· Blib
· Librairie PolySnd
· PolySnd Player
· PolySnd MIDI Converter
· PolySnd Converti
· Arkanoid
· Nebulus

 

  -- Rubriques --
· PolySnd v1.0
· PolySnd v1.2
· PolySnd v1.3
· PolySnd v2.0
· Guide de programmation

 

   

Guide de programmation pour PolySnd 2.0 en ASM et en C.

 

Animation d'une balle avec du son (partie n°1):

  Dans ce programme nous allons vraiment commencer à exploiter les performances de PolySnd v2.0, nous allons réaliser un programme réalisant le déplacement d'une balle avec un angle de 45°, chaque rebond sur l'écran correspondera à un son.

  Créez un nouveau projet en C avec la librairie PolySnd v2.0 que vous nommerez 'example3' avec le code de base pour initialiser PolySnd v2.0.

  Nous allons tout d'abord réaliser le programme sans s'occuper du son, nous devons tout d'abord définir le sprite et les déplacements de la balle, après avoir fait ceci, nous réaliseront les effets sonores et nous appliquerons à chaque collisions un son différent.

 

Réalisation du sprite (image) de la balle:

unsigned char ball_sprite [] = {0b00111100,
                                                0b01111110,
                                                0b11111111,
                                                0b11111111,
                                                0b11111111,
                                                0b11111111,
                                                0b01111110,
                                                0b00111100};
                                   

Inserez ce code en dessous de:

DEFINE_INT_HANDLER (myint2)
{
   pokeIO (0x60001B,0);
}

Notre sprite fait du 8x8 pixels, nous allons nous attquer au code de gestion de la balle.

 

Réalisation du code de déplacement de la balle:

  La position de notre balle sera définis par 2 variables xpos et ypos qui indiquerons ça positions en X et Y, à chaque passage de boucle, nous incrémenterons ses variables avec un facteur indiquant la direction de la balle, soit xdir pour son déplacement suivant X et ydir suivant Y. Pour afficher et effacer correctement la balle, nous l'afficherons avec un OU logique à la fin de la boucle et nous l'effacerons avec OU exclusif (XOR) au début de la boucle, bien sûr nous prenderons soin d'afficher la balle avec une bonne vitesse et avec une boucle d'attente.

Voici le code du programme:

// C Source File
// Created 11/10/2003; 17:13:50

#include <tigcclib.h>
#include "polysnd2.h"

INT_HANDLER OldInt1 = NULL;
INT_HANDLER OldInt2 = NULL;

DEFINE_INT_HANDLER (myint2)
{
   pokeIO (0x60001B,0);
}

unsigned char ball_sprite [] = {0b00111100,
                                                0b01111110,
                                                0b11111111,
                                                0b11111111,
                                                0b11111111, 
                                                0b11111111, 
                                                0b01111110,
                                                0b00111100};

//Programme principal
void _main(void)
{
   int i;

   short xpos = (LCD_WIDTH-1)/2;
   short ypos = (LCD_HEIGHT-1)/2;
   char xdir = 1, ydir = 1;

   OldInt1 = GetIntVec (AUTO_INT_1);
   OldInt2 = GetIntVec (AUTO_INT_2);
   SetIntVec (AUTO_INT_1, DUMMY_HANDLER);
   SetIntVec (AUTO_INT_2, myint2);

   pSnd_EnableSound ();
   pSnd_InstallSound ();

   ClrScr ();
   Sprite8 (xpos, ypos,8 ,ball_sprite, LCD_MEM, SPRT_OR);

   while (_keytest (RR_ESC)==FALSE)
   {
      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_XOR);

      xpos+=xdir; ypos+=ydir;

      if (xpos+8 > (LCD_WIDTH-1)) xdir = -1;
      if (xpos < 0) xdir =1;
      if (ypos+8 > (LCD_HEIGHT-1)) ydir = -1;
      if (ypos < 0) ydir = 1;

      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_OR);

      for (i=0; i<10000; i++);
   }

   pSnd_UninstallSound ();
   pSnd_DisableSound ();

   SetIntVec (AUTO_INT_1, OldInt1);
   SetIntVec (AUTO_INT_2, OldInt2);
}

  Nous allons nous occuper maintenant des divers parties de ce code pour mieux comprendre ce programme et ainsi pouvoir y introduire des séquences sonores sans trop de difficultés.

   int i;

   short xpos = (LCD_WIDTH-1)/2;
   short ypos = (LCD_HEIGHT-1)/2;
   char xdir = 1, ydir = 1;

Ici nous définissons les variables qu'utilisera le programme:

i est va permettre juste d'être utilisé dans la boucle de temporisation.

xpos et ypos sont les variables qui vont permettre de situer la balle sur l'écran de telle sorte que ça coordonné soit (xpos,ypos), ici nous les inialisons de tel sorte qu'au lancement du programme la balle ce situe au centre de l'écran et ce sur n'importe quel modèle de calculatrice.

xdir et ydir permettent de définir le sens de déplacement de la balle, dans notre programme, ses variables ne pourrons prendre que 2 valeurs (-1 ou 1), si xdir=1, la balle ce déplacera vers la droite et si xdir=-1, vers la gauche, s'est le même principe pour ydir. Si ydir=-1, la balle ce déplacera vers le haut et si ydir=1, vers le bas.

Voilà nos variables, maintenant nous devons les exploiter:

   ClrScr ();
   Sprite8 (xpos, ypos,8 ,ball_sprite, LCD_MEM, SPRT_OR);

   while (_keytest (RR_ESC)==FALSE)
   {
      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_XOR);

      xpos+=xdir; ypos+=ydir;

      if (xpos+8 > (LCD_WIDTH-1)) xdir = -1;
      if (xpos < 0) xdir =1;
      if (ypos+8 > (LCD_HEIGHT-1)) ydir = -1;
      if (ypos < 0) ydir = 1;

      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_OR);

      for (i=0; i<10000; i++);
   }

  Nous effacons tout d'abord l'écran avec ClrScr (à savoir que c'est une fonction de TIGCC) et nous affichons la balle avec sprite8 en mode OU logique.

  La boucle while execute une série d'instruction entre {} tant que la condition est vrai, ici tant que nous n'avons pas appuyez sur la touche ESC. Après nous nous occupons d'effacer la balle sur l'écran en l'affichant avec sprite8 mais en mode OU exclusif (XOR), nous ajoutant xdir à xpos et ydir à ypos de telle sorte d'effectuer le mouvement de la balle. Une fois cette étape d'effectué, il faut vérifier que la balle ne sorte pas de l'écran, pous cela on applique des collisions entre les points ce situant à l'extremité de la balle donc si nous voulons tester correctement si il y a collisions avec le bas de l'écran et la balle nous devons ajouter 8 à xpos dans notre condition car la balle fait 8 pixels de hauteur et procéder de la même façon pour les autres collisions, mais au lieu de changer xpos ou ypos dans notre résultat , nous changerons les vecteurs de directions xdir ou ydir. Et ensuite pour finir nous affichons la balle avec sprite8 en mode OU logique et nous effectuons une boucle de temporisation avec for pour que la balle ne soit pas trop rapide et que son temps d'affichage soit visible.

Nous allons donc maintenant créer les 4 séquences audio de collisions avec l'écran, pour cela vous devez créer un nouveau fichier du type header (portant l'extension h) que vous nommerez 'sounds_ball.h' et l'inclure dans le projet en tapant au début du code '#include "sounds_ball.h"'. Ouvrez le fichier 'sounds_ball.h' et copiez le code suivant:

//C Source File
//Created 11/10/2003; 17:13:50
//Collision avec la gauche
unsigned short collide_left[]={2500,15,
                                               1415,21,
                                               1000,30,
                                               2000,10,
                                               0xFFFF};

//Collision avec la droite
unsigned short collide_right[]={5500,15,
                                                 2415,21,
                                                 3000,30,
                                                 4000,10,
                                                 0xFFFF};

//Collision vers le haut
unsigned short collide_up[]={1250,10,
                                              2300,30,
                                              3800,10,
                                              4500,10,
                                              0xFFFF};

//Collision vers le bas
unsigned short collide_down[]={5845,5,
                                                   600,10,
                                                   5423,30,
                                                   8645,20,
                                                   0xFFFF};

  Voici enfin notre fichier 'sounds_ball.h' remplit de données sonores, ici nous avons réaliser 4 listes de données pour PlayFX, les données de PlayFX s'ordonnent de façon précise:

fréquence, durée, fréquence, durée .... fréquence, durée, 0xFFFF

  La fréquence peut aller de 0 (considéré comme une pause) à 32768 Hz, ses valeurs ne sont pas précise et les durées vont de 1 à 255 et sont en cycles tempo, soit 32 correspondant à une noire. Ce mode est très difficile à utiliser mais produit des résultats assez impressionnant. (note: c'est le seul mode qui n'a pas de logiciel de conversion). Une liste de données pour PlayFX doit toujhours ce terminer par 0xFFFF et ce pour indiquer ça fin à PolySnd v2.0.

Voici maintenant le code du programme principal, nous avons juste modifié les conditions lors de collisions:

// C Source File
// Created 11/10/2003; 17:13:50

#include <tigcclib.h>
#include "polysnd2.h"

INT_HANDLER OldInt1 = NULL;
INT_HANDLER OldInt2 = NULL;

DEFINE_INT_HANDLER (myint2)
{
   pokeIO (0x60001B,0);
}

unsigned char ball_sprite [] = {0b00111100,
                                                0b01111110,
                                                0b11111111,
                                                0b11111111,
                                                0b11111111, 
                                                0b11111111, 
                                                0b01111110,
                                                0b00111100};

//Programme principal
void _main(void)
{
   int i;

   short xpos = (LCD_WIDTH-1)/2;
   short ypos = (LCD_HEIGHT-1)/2;
   char xdir = 1, ydir = 1;

   OldInt1 = GetIntVec (AUTO_INT_1);
   OldInt2 = GetIntVec (AUTO_INT_2);
   SetIntVec (AUTO_INT_1, DUMMY_HANDLER);
   SetIntVec (AUTO_INT_2, myint2);

   pSnd_EnableSound ();
   pSnd_InstallSound ();

   pSnd_PlayMode (MONO);
   pSnd_SetTempo (1000);

   ClrScr ();
   Sprite8 (xpos, ypos,8 ,ball_sprite, LCD_MEM, SPRT_OR);

   while (_keytest (RR_ESC)==FALSE)
   {
      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_XOR);

      xpos+=xdir; ypos+=ydir;

      if (xpos+8>(LCD_WIDTH-1))
     {
          xdir=-1;
          pSnd_PlayFX_voice1 (collide_right);
          pSnd_SetState (VOICE1);
     }

     if (xpos<0)
     {
          xdir=1;
          pSnd_PlayFX_voice1 (collide_left);          
          pSnd_SetState (VOICE1);
     }

     if (ypos+8>(LCD_HEIGHT-1))
     {
          ydir=-1;     
          pSnd_PlayFX_voice1 (collide_down);
          pSnd_SetState (VOICE1);
     }

     if (ypos<0)
     {
          ydir=1;
          pSnd_PlayFX_voice1 (collide_up);
          pSnd_SetState (VOICE1);
     }

      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_OR);

      for (i=0; i<10000; i++);
   }

   pSnd_UninstallSound ();
   pSnd_DisableSound ();

   SetIntVec (AUTO_INT_1, OldInt1);
   SetIntVec (AUTO_INT_2, OldInt2);
}

  Nous réglons PolySnd v2.0 en mode mono grâce à pSnd_PlayMode puis nous paramètrons le tempo à 1000 bpm avec SetTempo, ici pSnd_SetTempo_voice1 aurait suffit.

  Dans chaque conditions de collisions nous jouant un son ce trouvant dans le fichier 'sounds_ball.h' avec pSnd_PlayFX_voice1 et nous donnons l'ordre à PolySnd v2.0 de jouer le mode de la voie1 avec pSnd_SetState (VOICE1), ici comme nous sommes en mono, VOICE1 suffit. PolySnd v2.0 n'attend pas qu'un mode soit finit de jouer pour executer le suivant, celui qui était en cours et ignoré au profit du nouveau mode et des nouvelles données (bien sûr il est toujours possible de programmer une gestion de modes...).

Télécharger example3.zip partie 1.

 

Animation d'une balle avec du son (partie n°2):

  Nous allons réaliser le même programme que précédément mais cette fois si en donnant la priorité au son et donc bloquant le cours du programme lorsqu'un son est joué. Vous allez constater que la balle subira des ralentissements. Mais cette méthode est utile dans le cas ou vous devez executer des actions en fonction du son.

  Nous allons donc executer une boucle qui devra attendre la fin du mode en cours, pour cela insérez cette ligne de code en dessous pSnd_SetState_voice1 (VOICE1);.

 while (pSnd_GetState ()==VOICE1);

  La boucle while s'executera tant que le mode en cours n'est pas finit, donc tant que pSnd_GetState est égale à VOICE1.

Télécharger example3.zip partie 2.

Rubrique suivante.