共2个文件, 一个TwentyFour.java(class), 一个IDefine.java(interface), 画fps的字不停的闪烁,是不是frame也在不停的刷新,谁能解释一下,怎么解决? 不胜感激!
第一个文件:import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;import javax.swing.ImageIcon;
public class TwentyFour extends Canvas implements Runnable
{

/**
 * 
 */
private static final long serialVersionUID = 1L; //---------------------------------------------
///paint
//---------------------------------------------
public void paint(Graphics g)
{
s_bGameInPaint = true;
updateGame();
paintGame(g);
s_bGameInPaint = false;
System.out.println("frameNum " + s_frameNum);
System.out.println("time " + s_frameDelayTime);
}


public void paintGame(Graphics g)
{
        //------------------------------------
        //draw fps
     g.setColor(Color.black);
g.fillRect(0,
getScreenHeight() - g.getFont().getSize() - 100,
getScreenWidth(),
g.getFont().getSize() );
g.setColor(Color.white);
s_strBuffer.delete(0, s_strBuffer.length() );
s_strBuffer.append("Fps: ");
s_strBuffer.append(s_fps);
g.drawString(s_strBuffer.toString(),
0, 
getScreenHeight() - 100);
}
 
///--------------------------------
public static StringBuffer s_strBuffer = new StringBuffer();
///--------------------------------

    //---------------------------------------------
///update
//---------------------------------------------
public static long s_frameDelayTime;
public static long s_frameTime;
public static long s_frameStartTime;
public static long s_currentTime;
public static int s_fps;
public static int s_frameNum;
public static boolean s_bGameInPaint;

public static Graphics s_screenGraphics;
public static Graphics s_g;

public void updateGame( )
{
s_frameNum++;
} public void run()
{
// TODO Auto-generated method stub
        while( !s_bExitGame )
        {
         if( s_bGameInPaint )
     {
         try
         {
         Thread.sleep( 3);
         }
         catch(Exception e)
         {
         e.printStackTrace();
         }
         s_frameStartTime = System.currentTimeMillis();
     continue;
     }
     //
         s_currentTime = System.currentTimeMillis();
         s_frameDelayTime = s_currentTime - s_frameStartTime;
         s_frameStartTime = s_currentTime;
         if(s_frameDelayTime < 0)
         {
         s_frameDelayTime = 0;
         }
         else if(s_frameDelayTime > 1000)
         {
         s_frameDelayTime = 1000;
         }
         s_fps = 1000 / (int)(s_frameDelayTime > 0 ? s_frameDelayTime : 1);
        
         repaint();
         s_frameTime = System.currentTimeMillis() - s_frameStartTime;
         //limit fps
         if(s_frameTime < 1000 / IDefine.FPS_MAX )
         {
         try
         {
         Thread.sleep( 1000 / IDefine.FPS_MAX - s_frameTime);
         }
         catch(Exception e)
         {
         e.printStackTrace();
         }
         }
        }
}

public static int getScreenWidth()
{
return IDefine.SCREEN_W;
}

public static int getScreenHeight()
{
return IDefine.SCREEN_H;
}
    //---------------------------------------------
///main method
//---------------------------------------------
public static Image s_iconImg;


public static void main(String[] args )
{
try
{
s_bExitGame = false;
s_app = new TwentyFour();
s_screenGraphics = s_app.getGraphics();
s_g = s_screenGraphics;
System.out.println("Game Start!");
s_frameStartTime = System.currentTimeMillis();
new Thread(s_app).start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
    
    //---------------------------------------------
///init
//---------------------------------------------
public static  TwentyFour s_app;
public static  Frame s_mainFrame;
public static boolean s_bExitGame;
    
//init game
public TwentyFour()
{
//set frame
s_mainFrame = new Frame(IDefine.FRAME_TITLE);
s_mainFrame.setSize(IDefine.FRAME_W, IDefine.FRAME_H);
s_mainFrame.setBackground(new Color(220, 220, 240));
s_mainFrame.setVisible(true);
s_mainFrame.addWindowListener( new WindowAdapter()
{
  public void windowClosing(WindowEvent e)
  {
  System.out.println("Game Exit!");
  System.exit(0);
  }
}
);
s_iconImg = ( new ImageIcon(IDefine.FRAME_ICON_PATH) ).getImage();
s_mainFrame.setIconImage(s_iconImg);
Dimension pcScrDimen =  Toolkit.getDefaultToolkit().getScreenSize();
s_mainFrame.setLocation(
( pcScrDimen.width - s_mainFrame.getWidth() ) >> 1,
( pcScrDimen.height - s_mainFrame.getHeight() ) >> 1 );
//set canvas
setSize(IDefine.SCREEN_W, IDefine.SCREEN_H );
s_mainFrame.add(this);
setLocation(0, 0);
s_mainFrame.pack();

}
    

}-------------------------------------------------
第二个文件:public interface IDefine
{
public final static int FPS_MAX = 30;


//screen
public final static int SCREEN_W = 320;

public final static int SCREEN_H = 240;
//frame
public final static String FRAME_TITLE = "24点小游戏"; public final static int FRAME_W = 400; public final static int FRAME_H = 400;

public final static String FRAME_ICON_PATH = "data\\TFPoint.png" ;
//state
public final static int STATE_LOGO = 0;

}

解决方案 »

  1.   

    找到了,有两个原因:
    1.没有用backbuffer。
    2.没有重写update(Graphics g)这个函数。如果只有backbuffer而没重写这个函数,那么整个图片都会闪烁。
    多谢指点。public void update(Graphics g)    更新此 canvas。    调用此方法以响应对 repaint 的调用。首先通过使用背景色填充 canvas 来清理它,然后通过调用此 canvas 的 paint 方法重绘它。注:重写此方法的应用程序应该调用 super.update(g),或者将上面描述的功能合并到其自身的代码中。    覆盖:
            类 Component 中的 update    参数:
            g - 指定的 Graphics 上下文
        另请参见:
            paint(Graphics), Component.update(Graphics)