⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jv0403.htm

📁 很不错到
💻 HTM
📖 第 1 页 / 共 4 页
字号:
  int s_length = s.length();<br>  
  int x_character = 0;<br>  
  Font wordFont=new Font(&quot;TimesRoman&quot; , Font.BOLD , 50);<br>  
  public void start() {<br>  
  if(runThread==null){<br>  
  runThread = new Thread(this);<br>  
  runThread.start();<br>  
  }<br>  
  }<br>  
  public void stop() {<br>  
  if(runThread!=null){<br>  
  runThread.stop();<br>  
  runThread=null;<br>  
  }<br>  
  }<br>  
  public void run() {<br>  
  while(true) {<br>  
  if (x_character++&gt;s_length)<br>  
  x_character = 0;<br>  
  repaint ();<br>  
  try {<br>  
  Thread.sleep(300);<br>  
  } catch (InterruptedException e) {}<br>  
  }<br>  
  }<br>  
  public void paint (Graphics g) {<br>  
  g.setFont (wordFont);<br>  
  g.setColor (Color.red);<br>  
  g.drawString (s.substring(0,x_character), 8, 50);<br>  
  }<br>  
  }</P>
<p>   <IMG height=130 
src="tu4-16.gif" width=416></P>
<p>  </P>
<p>  图4-15 简单动画例子的执行结果</P>
<p>   <a name="433"></a>4.3.3 初识闪烁问题</P>
<p>   虽然,我们刚才的applet已经能动起来,可是挑剔的用户马上就会发现屏幕上的动画会一闪一闪的,如果你的机器速度较慢的话,这一现象就更明显。确实,有效的解决闪烁问题一直是动画制作的关键技术,因为没有人会愿意观看刺眼的一闪一闪的画面。<br>  
  既然想要解决这一问题,那就先要找到产生闪烁现象的原因在哪里。还记不记得动画过程是如何工作的:applet调用repaint( )方法通知系统进行重画,repaint( 
  )方法实际调用了update( )方法先清洗整个applet区域,然后再调用paint( )方法绘制屏幕。<br>  
  很明显,问题就出在update( )方法里,它每次清除屏幕,使画面每次都从有内容,到全空白,再画上内容,无疑造成了闪烁。下面就是update( )方法的缺省代码:<br>  
  public void update(Graphics g){<br>  
  g.setColor(getBackground()); //将背景色置为当前绘图颜色<br>  
  g.fillRect(0,0,width,height); //用背景色填充整个applet区域<br>  
  g.setColor(getForeground()); //将当前绘图颜色设回前景色<br>  
  paint(g); //进行重画<br>  
  }<br>  
  其中width和height是指整个applet的高度和宽度。很显然,我们必须覆盖这一方法,去改变它每次都呆板的用背景色去填充一下整个applet区域。那我们是否真的每次都需清除屏幕吗?回想一下,我们的applet每一次重画的内容都比前一次多一个字符。所以,如果前一个画面不清除,后一个画面叠加上去并不会破坏整个画面的内容,只有在全部字符都显示完全,才需要真正的清洗一下屏幕。因此,只在真正需要清除屏幕的时候才去做清除的动作,这应该说是消除闪烁的一个原则。下面,就是我们覆盖缺省的update( 
  )方法后的新代码:<br>  
  public void update(Graphics g){<br>  
  if (x_character= =0){<br>  
  g.setColor(getBackground());<br>  
  g.fillRect(0,0,appletWidth,appletHeight);<br>  
  g.setColor(getForeground());<br>  
  }<br>  
  paint(g);<br>  
  }<br>  
  另外有一点要改进的就是,为了能增加applet的灵活性和实用性,我们要尽量从HTML文件给applet传递各种配置参数,如要显示的字符串、字体、颜色、尺寸等信息,这样就不必每次小的改动都需要重新编译applet源代码。<br>  
  下面就是本实例经改进后的程序代码:<br>  
  import java.awt.Color;<br>  
  import java.awt.Font;<br>  
  import java.awt.FontMetrics;<br>  
  import java.awt.Graphics;<br>  
  public class RollingMessage extends java.applet.Applet implements Runnable {<br>  
  Thread runThread;<br>  
  String s; // 要显示的字符串<br>  
  int s_length; // 字符串的长度<br>  
  int x_character=0, // 当前显示到第几个字符串<br>  
  y_coord, // 字符串的Y坐标位置<br>  
  textcolor, // 字符串的颜色值(16进制整数rrggbb)<br>  
  backcolor, // applet背景颜色值(16进制整数rrggbb)<br>  
  delay; //每帧画面的时延(毫秒)<br>  
  int appletWidth, appletHeight;<br>  
  String font_name; // 字体的名称<br>  
  int font_size; // 字体的尺寸<br>  
  Font wordFont;<br>  
  FontMetrics wordMetrics;<br>  
  public void init() {<br>  
  String temp;<br>  
  appletWidth = size().width;<br>  
  appletHeight = size().height;<br>  
  temp=getParameter(&quot;font&quot;);<br>  
  font_name= (temp= =null) ? &quot;TimesRoman&quot; : temp;<br>  
  temp = getParameter(&quot;fontsize&quot;);<br>  
  font_size= (temp= =null) ? 12 : Integer.parseInt( temp ); //转换为10进制整数<br>  
  wordFont = new Font(font_name, Font.PLAIN, font_size);<br>  
  if (wordFont = = null)<br>  
  wordFont = getFont();<br>  
  wordMetrics = getFontMetrics (wordFont);<br>  
  temp = getParameter(&quot;text&quot;);<br>  
  s= (temp= =null) ? &quot;Message goes here... &quot; : temp;<br>  
  s_length=s.length();<br>  
  temp = getParameter(&quot;textcolor&quot;);<br>  
  textcolor= (temp= =null) ? 0 : Integer.parseInt( temp ,16 ); //转换为16进制整数<br>  
  temp = getParameter(&quot;backcolor&quot;);<br>  
  backcolor= (temp= =null) ? 0xffffff : Integer.parseInt( temp ,16 );<br>  
  temp = getParameter(&quot;delay&quot;);<br>  
  delay= (temp= =null) ? 100 : Integer.parseInt( temp );<br>  
  y_coord = appletHeight/2 + (wordMetrics.getHeight()-wordMetrics.getDescent())/2;<br>  
  }<br>  
  public void start() {<br>  
  if(runThread==null){<br>  
  runThread = new Thread(this);<br>  
  runThread.start();<br>  
  }<br>  
  }<br>  
  public void stop() {<br>  
  if(runThread!=null){<br>  
  runThread.stop();<br>  
  runThread=null;<br>  
  }<br>  
  }<br>  
  public void run() {<br>  
  while(true) {<br>  
  if (x_character++&gt;s_length)<br>  
  x_character = 0;<br>  
  repaint ();<br>  
  try {<br>  
  Thread.sleep( delay );<br>  
  } catch (InterruptedException e) {}<br>  
  }<br>  
  }<br>  
  public void paint (Graphics g) {<br>  
  g.setFont (wordFont);<br>  
  g.setColor (Color.red);<br>  
  g.drawString (s.substring(0,x_character), 8, y_coord);<br>  
  }<br>  
  public void update(Graphics g){<br>  
  if (x_character = = 0){<br>  
  g.setColor(getBackground());<br>  
  g.fillRect(0,0,appletWidth,appletHeight);<br>  
  g.setColor(getForeground());<br>  
  }<br>  
  paint(g);<br>  
  }<br>  
  }<br>  
  下面是测试这一applet的HTML语言的例子:<br>  
  &lt;applet code=RollingMessage.class width=400 height=60&gt;<br>  
  &lt;param name=font value=&quot;TimesRoman&quot;&gt;<br>  
  &lt;param name=fontsize value=30&gt;<br>  
  &lt;param name=text value=&quot;Welcome to here !&quot;&gt;<br>  
  &lt;param name=textcolor value=&quot;ff0000&quot;&gt;<br>  
  &lt;param name=backcolor value=&quot;ffffff&quot;&gt;<br>  
  &lt;param name=delay value=300&gt;<br>  
  &lt;img src=&quot;java/rollingmessage.gif&quot; WIDTH=251 HEIGHT=24 BORDER=0&gt;<br>  
  &lt;h5&gt;You need Java to use the RollingMessage applet!<br>  
  &lt;/applet&gt;</P>
<p>   <a name="434"></a>4.3.4 放映图像</P>
<p>   有些人可能会觉得真正的动画应该是每一帧都有自己的图像,而不是仅仅跳出几个字符。那好吧,我们下面就来制作一个放映图像的动画例子,那就是一个会走的数码钟,其显示效果如图4-16所示。图像的动画例子,那就是一个会走的数码钟,其显示效果如图4-16所示。</P>
<p>  <IMG 
height=99 src="tu4-17.gif" width=130></P>
<p>  图4-16 会走的数码钟在放映图像前我们自然应该先准备好各个图像文件,本例的applet所需要的图像清单是:'0'到'9'共十幅数码管图像(文件名为lcd0.gif、lcd1.gif、...、lcd9.gif),一个冒号图像(colon.gif文件),一个钟的边框(frame.gif文件)。这些清单如图4-17所示。<IMG 
height=106 src="tu4-18.gif" width=326></P>
<p>  图4-17 数码钟所用的各图像文件<br>  
  然后我们把这些图像都放在本applet目录下的dcimages目录下,由于我们把数码管图像的文件名取得相似,因而可以创建一个Image数组digit_image作为实例变量,并在init()方法中通过一个循环,将这十幅图像装载进来,如:<br>  
  Image[] digit_image = new Image[10];<br>  
  public void init()<br>  
  {<br>  
  for (int i = 0; i &lt; 10; i++)<br>  
  {<br>  
  digit_image[i] = getImage(getCodeBase(), &quot;dcimages/lcd&quot; + i + &quot;.gif&quot;);<br>  
  . . .<br>  
  }<br>  
  同样,用getImage( )方法装载其它两幅图像。下一步的工作就是要确定数码钟里每幅图显示的起始位置,这里主要是指X方向的坐标值(因为Y方向的坐标值是一样的)。<br>  
  我们把这些信息存放在一个整型数组(image_start_x)中,其中每个值的含义依次表示下列位置:小时数的十位数码、小时数的个位数码、第一个冒号、分钟数的十位数码、分钟数的个位数码、第二个冒号、秒钟数的十位数码、秒钟数的个十位数码。然后同样采用多线程机制,在run( 
  )方法中控制定时,一秒钟重画一次。而在paint()方法中则先获取当前的时间,然后用drawImage( )方法在相应的位置画出边框、相应的六个数码管图像及两个冒号。<br>  
  接下来的问题就是如何得到当前的时间呢?这就要用到java.util程序包里的Data类(别忘了import它哟)。这个类的构造方法中有一种不带任何参数的调用格式,它就会创建一个表示当前日期和时间的对象,得到这一对象后就可以调用Data类中提供的getHours()方法、getMinutes( 
  )方法与getSeconds( )方法来获取当前时刻的小时数、分钟数和秒数。<br>  
  例如:<br>  
  Date now = new Date( );<br>  
  int hour = now.getHours( );<br>  
  int minute = now.getMinutes( );<br>  
  int second = now.getSeconds( );<br>  
  另外,我们为了将该applet的宽度和高度就设置为数码钟边框所围的区域,就调用了Applet类中的resize( )方法,该方法传递两个整型参数,分别将该applet重新设置为所指定的高度和宽度。调用这一方法将覆盖HTML文件中&quot;applet&quot;标记的width属性和height属性的值,这样就可以防止用户对这两个属性值的错误设置。<br>  
  最后,我们要注意的问题自然又是关于闪烁。由于我们每次都在一系列固定的位置上放置大小相同的图片,因而根本不需每次用背景色清除画面。所以update( )方法只要简单地调用paint( 
  )方法就可以了:<br>  
  public void update(Graphics g)<br>  
  {<br>  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -