Applet d'animation Java avec MediaTracker, threads et timer


J'ai 3 questions sur mon projet d'animation.

  1. La structure du programme est-elle correcte (voir ci-dessous)
  2. Ma première image (d'un tableau) ne se comporte pas correctement. Parfois, il apparaît puis disparaît, puis le reste des images s'affichent correctement.
  3. Comment puis-je contrôler quand le clip audio commence à jouer. On dirait aussi parfois qu'une aiguille déchire un disque...?

CONCERNANT LA STRUCTURE DU PROGRAMME: Sont les suivants dans le bon ordre:

DANS INIT:

  1. Définir la taille de l'applet.
  2. Exécuter une tâche de minuterie avec un temps de sommeil
  3. Obtenez le fichier son.
  4. Récupère les images du tableau.
  5. Initialisez l'objet MediaTracker et dites-lui d'attendre toutes les images.
  6. Lire le fichier son.

AU DÉBUT(Graphique g) 1. Dessinez l'applet et chargez la première image du tableau

AU DÉBUT: 1. Vérifier les fils pour les valeurs null, sinon null, commencez

EN COURS D'EXÉCUTION: 1. Utilisez une variable "iPictureNumber" pour parcourir les images dans un ordre séquentiel en utilisant également repaint et Thread.méthodes de sommeil

DANS LA MISE À JOUR: 1. Dessiner l'appliquette.


Ce code est une version mise à jour d'un autre programme que j'ai qui n'a pas utilisé de threads, donc je ne sais pas si c'est la bonne structure. Mon objectif est d'utiliser les meilleures pratiques avec ce type de programme simple. Je peux fournir les images et le son dans un fichier zip si nécessaire. Veuillez conseiller, merci d'avance. VOICI LE CODE:

// Projet d'animation Java avec tableau d'images et 1 fichier son utilisant des threads

 import java.net.*;
 import java.io.*;
 import java.lang.*;
 import java.awt.*;
 import java.awt.event.*;
 import java.awt.Frame;
 import java.awt.Graphics;
 import java.awt.Image;
 import java.awt.MediaTracker;
 import java.applet.Applet;
 import java.applet.AudioClip;
 import java.util.*;

 public class c_TrainAnimation extends Applet implements Runnable 
  {
     Image trainAndBush[];
     int totalImages = 17, 
     currentImage = 0,             // Set current image array subscript to 0
     sleepTime = 900;
     Image imageCurrent;  // Set to the matching image in "trainAndBush" Array
     MediaTracker myImageTracker;
     Timer myTimer; 
     Thread threadTrainAnimation = new Thread(this);
     Thread threadSoundFile = new Thread(this); 
     AudioClip mySound; 

     public void init()
     {
    setSize(400,400);   

        myTimer = new Timer(true);
    myTimer.schedule( new TimerTask() 
          { 

              public void run() 
               { repaint();}

            } // end TimerTask

               ,0,sleepTime);

       mySound = getAudioClip(getDocumentBase(), "onpoint.au");
       trainAndBush = new Image[ totalImages ];

       // Load the array of images into the Applet when it begins executing
        for( int i = 0; i  < trainAndBush.length; i++ )
       {    
             trainAndBush[i] = getImage(getDocumentBase(),
              "Hill" + (i + 1) + ".jpg" );      

        myImageTracker = new MediaTracker( this ); 

        // Give the images an ID number to pass to MediaTracker
        myImageTracker.addImage(trainAndBush[i], i);

        // Tell MediaTracker to wait until all images are loaded
          try
    {
        myImageTracker.waitForAll();
    }
    catch(Exception e) {}

         mySound.play();

         }   // end for loop
     }       // end init

     // check threads for null values and then start threads
     public void start()
      {
     if (threadTrainAnimation != null )
        threadTrainAnimation.start();
     if (threadSoundFile != null )
    threadSoundFile.start();
      }

     // Draw the applet with the first image of the array
     public void start(Graphics g)
      {
     g.drawImage(trainAndBush[0],50,50,300,300, this );
     currentImage = 0;                       
      }

      // Set "imageCurrent"to appropriate "trainAndBush image" in the array and_
         loop through  
     public void run()
       {
     int iPictureNumber[] = {0, 1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,15,16};
       while( true )
    {   
          for( int i = 0; i < iPictureNumber.length; i++ )
           {
         imageCurrent = trainAndBush[iPictureNumber[i]];
         repaint();
       try
        {
         Thread.sleep( sleepTime ); 
        }
        catch( InterruptedException e) {}

         }  // end for loop
       }   // end while statement
     }  // end run 

     public void update(Graphics g)
      {
    g.drawImage( imageCurrent, 50, 50, 300, 300, this );
      }

    } // end of Applet
Author: MadProgrammer, 2012-08-14

1 answers

Je n'utiliserais pas Applet, utilisez JApplet, cela résoudra des dizaines de problèmes dès le départ ;)

J'utiliserais probablement des Runnables séparés pour les threadTrainAnimation et threadSoundFile, mais je n'ai pas eu beaucoup d'expérience avec le son dans le passé. Le problème que je vois cependant est que vous avez deux threads qui accèdent simultanément à la partie de code en faisant la même chose. C'est juste faire un gâchis de choses.

Vous devez comprendre comment synchroniser le son et l'animation.

L'utilisation du java.util.Timer est incorrect pour ce que vous essayez de réaliser, c'est aussi exagéré étant donné que vous avez threadTrainAnimation en cours d'exécution, car ils font généralement la même chose. Dans ce cas, je m'en débarrasserais probablement. À l'avenir, il est préférable d'utiliser javax.swing.Timer car il fournit un meilleur support pour le Event Dispatching Thread

Personnellement, je ne chargerais pas mes ressources dans la méthode init comme vous êtes. Cela va ralentir le chargement de l'applet et contrarier les utilisateurs. Vous feriez mieux de mettre en place une belle "chargement" de l'image et utiliser un Thread pour effectuer le chargement. Une fois cela fait, en utilisant quelque chose comme SwingUtilities.invokeLater pour démarrer l'animation.

Ne remplacez pas la méthode update, vous devriez remplacer la méthode paint à la place.

Il est également possible que les images soient modifiées plus rapidement puis qu'elles puissent être peintes, vous voudrez peut - être y réfléchir également-c'est-à-dire que la méthode run peut s'exécuter plusieurs fois avant que paint ne soit appelé

Comme suggestion, j'avais lu par

Si vous êtes sérieux au sujet de l'animation, je vérifierais aussi

Qui sont des frameworks d'animation pour Java

 1
Author: MadProgrammer, 2012-08-13 23:58:17