2013-02-09 115 views
0

我已经开始用Java编写一个小而简单的引擎(用于游戏)。当我重新绘制屏幕时,它有时会闪烁。我查了这个问题的答案,并且回答建议使用swing定时器(这正是我正在做的)。下面是代码中的相关片段(我在一些添加注释):(Java)屏幕闪烁

public class Game extends JPanel implements ActionListener { 
private static final long serialVersionUID = 1L; 

private static Window window; 
private static ObjectUpdater objects; 
private static Timer timer; 

private static boolean init = false; 


public Game(){ 
    timer = new Timer(30,this); 
    timer.start(); 
} 

public static void main (String[] self){ 
    new Game(); 
} 

private static void initialize(){ 
    //Tests 
    //Setting up the window 
    window = new Window(); 

    //Setting up the updater 
    objects = new ObjectUpdater(); 

    new Picture(Path.images+Path.img_black,10); 
    // These are just some objects for the game... 

    Entity r = new Entity(new Picture(Path.images+Path.img_lapras,0)); 
    r.setVelocity(0.5,0); 
    Entity r2 = new Entity(new Picture(Path.images+Path.img_lapras,1)); 
    Vector i = new Vector(0,0.5); 
    r2.setVelocity(i.values()[0],i.values()[1]); 
} 
// This is where repaint(); is called. 
public void actionPerformed(ActionEvent e) { 
    setDoubleBuffered(true); 
    if (init == false){ 
     initialize(); 
     init = true; 

    } 

    objects.update(); // This updates all the game object's information 
    window.update(); // This updates the window itself, it's literally: repaint(); 

} 
} 

这里是window对象的代码,因为这是东西也发生。

public class Window extends JFrame{ 
private static final long serialVersionUID = 1L; 

public static int refresh_rate = 25; 
public static Picture[] image_list = new Picture[0]; // All the images I want to render 
private static String win_title = "Window"; // The name of the window 
private static int[] win_xy = {640,360}; // The size of the window 

public Window(){ 
    //initializes window 
    setTitle(win_title); 
    //setUndecorated(true); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setSize(win_xy[0],win_xy[1]); 
    setLocationRelativeTo(null); 
    setVisible(true); 
    setResizable(false); 

} 

public static int[] getWinSize(){ 
    return win_xy; 
} 

// Here I'm just "painting" everything in the image_list array... 
public void paint(Graphics g) { 
    super.paint(g); 
    Graphics2D g2d = (Graphics2D) g; 
    for (Picture i:image_list){ 
     g2d.drawImage(i.getPic(), i.getXY()[0], i.getXY()[1], null); 
    } 
    Toolkit.getDefaultToolkit().sync(); 
    g.dispose(); 
} 


public static void addPicture(Picture element){// This adds images to the image_list 
    Picture[] result = Arrays.copyOf(image_list, image_list.length +1); 
    result[image_list.length] = element; 
    image_list = result; 
    Arrays.sort(image_list); 

} 

public void update() { 
    repaint(); 

} 

} 

就是这样......谢谢!

+3

在'Window'类的'paint'方法中调用'super.paint(g)'是闪烁的原因,此外,您应该重写'paintComponent'而不是'paint'基于应用。 – 2013-02-09 14:32:49

+0

有什么理由我应该使用'paintComponent'而不是'paint'?我的意思是更具体? – Linkxgl 2013-02-09 14:59:45

+0

检查*** [this](http://stackoverflow.com/questions/9389187/difference-between-paint-paintcomponent-and-paintcomponents-in-swing)***页面。 – 2013-02-09 15:05:25

回答

1

顶级包含(如JFrame)不是双缓冲。这是我们不推荐从顶级容器延伸的原因之一。

相反,创建你自己(从JPanel例如)自定义组件,替代它的paintComponent方法(不要忘记调用super.paintComponent

退房

对于一些例子

+0

谢谢!我会投你一票,但我的名声还不够高...... – Linkxgl 2013-02-15 00:54:14

+0

如果你发现答案有用,你可以把它标记为正确的(右边的小勾),否则,当你有更多的时候记住我声誉;) – MadProgrammer 2013-02-15 01:02:13