带有 MediaTracker、线程和计时器的 Java 动画小程序

标签 java multithreading animation timer applet

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

  1. 程序的结构是否正确(见下文)
  2. 我的第一张图像(来自数组)表现不正常。有时它会弹出然后消失,然后其余图像会正确显示。
  3. 如何控制音频剪辑何时开始播放。有时听起来就像一根针在撕裂唱片......?

关于该计划的结构: 以下内容的顺序是否正确:

在初始化中:

  1. 设置小程序大小。
  2. 运行具有 sleep 时间的计时器任务
  3. 获取声音文件。
  4. 从数组中获取图像。
  5. 初始化 MediaTracker 对象并告诉它“等待所有”图像。
  6. 播放声音文件。

开始(图形g) 1.绘制小程序并加载数组的第一张图片

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

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

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

<小时/>

这段代码是我拥有的另一个没有使用线程的程序的更新版本,所以我不确定这是否是正确的结构。 我的目标是对这种类型的简单程序使用最佳实践。如果需要,我可以提供 zip 文件中的图像和声音。请指教,先谢谢了。 这是代码:

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

 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

最佳答案

我不会使用Applet,使用JApplet,它会立即解决几十个问题;)

我可能会为 threadTrainAnimationthreadSoundFile 使用单独的 Runnables,但我过去在声音方面没有太多经验。我看到的问题是你有两个线程同时访问代码部分做同样的事情。这只会把事情搞得一团糟。

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

使用java.util.Timer对于您想要实现的目标来说是不正确的,考虑到您正在运行threadTrainAnimation,它也是矫枉过正的,因为它们通常都在做同样的事情。在这种情况下,我可能会摆脱它。将来,您最好使用javax.swing.Timer,因为它为事件调度线程提供更好的支持

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

不要重写 update 方法,您应该重写 paint 方法。

图像的更改速度也有可能比绘制速度更快,您可能也需要考虑一下这一点 - 即 run 方法可能会在 paint 被调用

作为建议,我会通读

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

Java 的动画框架有哪些

关于带有 MediaTracker、线程和计时器的 Java 动画小程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11943032/

相关文章:

java - 你能在Spring中为@PreAuthorize设置一个动态值吗?

java - 使用数据库、GCM 和后台线程实现 Java Web 服务器

android - 使用 FLAG_ACTIVITY_CLEAR_TOP 的 Activity 之间的动画转换

css - IE11平移比例模糊图像

java - 使用 hibernate 存储/从 MySql 检索 JSON 数据时出现 UTF-8 问题

java - 调试 NullPointerException

python - 如果多个线程不访问相同的变量,我可以在多个线程上使用相同的锁吗?

multithreading - POSIX 的扩展允许 select() 或等效函数终止进程

ios - iOS 5.1 中的 CGGraphics Image Context 动画旋转

java - 正则表达式,排除以特定字符开头的数字