带有MediaTracker,线程和计时器的Java动画applet

时间:2012-08-13 22:06:56

标签: java multithreading animation timer applet

我对我的动画项目有3个问题。

  1. 程序的结构是否正确(见下文)
  2. 我的第一张图片(来自数组)表现不正常。有时它弹出然后消失,然后其余图像正确显示。
  3. 如何控制音频片段开始播放的时间。它有时候听起来就像针刺在记录上......?
  4. 关于计划的结构: 以下是正确的顺序:

    IN INIT:

    1. 设置小程序大小。
    2. 运行具有睡眠时间的计时器任务
    3. 获取声音文件。
    4. 从阵列中获取图像。
    5. 初始化MediaTracker对象并告诉它“等待所有”图像。
    6. 播放声音文件。
    7. IN START(图形g) 1.绘制小程序并加载数组的第一个图像

      开始时: 1.检查线程是否为空值,如果不为空,则启动它们

      跑步: 1.使用变量“iPictureNumber”按顺序迭代图像,也使用repaint和Thread.sleep方法

      更新: 1.再次绘制小程序。


      此代码是我没有使用线程的另一个程序的更新版本,因此我不确定这是否是正确的结构。 我的目标是使用这种简单程序的最佳实践。如果需要,我可以在zip文件中提供图像和声音。请提前告知,谢谢。 这是代码:

      //带有图像数组的Java动画项目和使用线程的1个声音文件

       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
      

1 个答案:

答案 0 :(得分:1)

我不会使用Applet,使用JApplet,它会解决许多问题;)

我可能会对RunnablesthreadTrainAnimation使用单独的threadSoundFile,但过去我对声音没有多少经验。我看到的问题是你有两个线程同时访问代码部分做同样的事情。这只是乱七八糟的东西。

您需要弄清楚如何同步声音和动画。

java.util.Timer的使用对于你想要达到的目标是不正确的,考虑到你threadTrainAnimation正在运行,因为它们通常做同样的事情,所以它也是过度的。在这种情况下,我可能只是摆脱它。将来,您最好使用javax.swing.Timer,因为它可以更好地支持Event Dispatching Thread

我个人不会按照您的方式在init方法中加载我的资源。这将减慢applet的加载速度并使用户感到不安。你最好提出一个漂亮的“加载”图像并使用Thread来执行加载。完成后,使用SwingUtilities.invokeLater之类的东西来启动动画。

请勿覆盖update方法,而应覆盖paint方法。

图像也可能被更快地更改然后可以被绘制,您可能也想对此进行一些考虑 - 也就是run方法可能会在{{1}之前执行多次被称为

作为建议,我会通读

如果你对动画很认真,我也会看看

这是Java的动画框架