2011-10-21 186 views
1

當我運行該程序時,一切正常,這一切工作和東西,但圖形不斷閃爍。我是新手做這樣的事情,我不知道如何解決這個問題。圖形閃爍

import java.awt.Frame; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionListener; 


public class MovementTest extends Frame implements Runnable, MouseMotionListener, KeyListener { 

    private static Thread thread; 
    private int mouseX, mouseY; 
    private boolean movingRight; 
    private boolean movingLeft; 
    private boolean movingUp; 
    private boolean movingDown; 

    private Rectangle player = new Rectangle(50, 50, 100, 100); 
    private Rectangle wallOne = new Rectangle(400, 50, 100, 100); 

    public MovementTest() { 
     setSize(800, 600); 
     setVisible(true); 
     addKeyListener(this); 
     addMouseMotionListener(this); 
    } 

    public static void main(String[] args) { 
     thread = new Thread(new MovementTest()); 
     thread.start(); 
    } 

    @Override 
    public void run() { 
     try { 
      while(true) { 
       if(player.intersects(wallOne)) { 
        thread.stop(); 
        break; 
       } 
       if(movingRight) { 
        player.x++; 
       } else if(movingLeft) { 
        player.x--; 
       } 
       if(movingUp) { 
        player.y--; 
       } else if(movingDown) { 
        player.y++; 
       } 
       paint(getGraphics()); 
       Thread.sleep(5); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     int key = e.getKeyCode(); 
     if (key == KeyEvent.VK_D) 
      movingRight = true; 
     if (key == KeyEvent.VK_A) 
      movingLeft = true; 
     if (key == KeyEvent.VK_W) 
      movingUp = true; 
     if (key == KeyEvent.VK_S) 
      movingDown = true; 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     int key = e.getKeyCode(); 
     if (key == KeyEvent.VK_D) 
      movingRight = false; 
     if (key == KeyEvent.VK_A) 
      movingLeft = false; 
     if (key == KeyEvent.VK_W) 
      movingUp = false; 
     if (key == KeyEvent.VK_S) 
      movingDown = false; 
    } 

    @Override 
    public void keyTyped(KeyEvent arg0) { 
     // TODO Auto-generated method stub 

    } 

    public void paint(Graphics g) { 
     g.drawString("x: " + mouseX + " y: " + mouseY, 5, 35); 
     g.drawRect(player.x, player.y, 100, 100); 
     g.drawRect(wallOne.x, wallOne.y, 100, 100); 
     repaint(); 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
     mouseX = e.getX(); 
     mouseY = e.getY(); 
    } 
} 
+3

我沒有得到最後一句話。 –

+0

最後一句由Stack Overflow生成。我不確定他在帖子中是如何結束的,它應該只是一個信息。 – corsiKa

+2

你有沒有使用Swing的原因?你不應該直接調用'paint()'(改爲調用'repaint()')。編碼你自己的更新循環是要求讓自己瘋狂;查看'Events' /'Listeners'。嘗試[教程](http://download.oracle.com/javase/tutorial/uiswing/index.html)可能會對您有所幫助。 –

回答

1

重新繪製您的繪畫方法。你真的不希望它在那裏。那是什麼導致你的問題。

之後,添加這個 - 它有助於保持組織的長期運行。

public void update() { 
    repaint(); 
} 

然後,在你移動東西的地方添加重繪方法。您還需要爲您的繪畫方法添加清除。這實際上會讓你的矩形移動。 更新:我注意到你已經有東西來重繪你的東西。優秀。這真的很快(200 fps !!),所以你一定要考慮雙緩衝。

然後稍後我們可以談談雙緩衝:)但你可以谷歌的那個或什麼。

+0

謝謝,我會看看:D – user1007883

+0

@user在編譯你的例子之後,看起來你不能移動你的矩形:-)我在你的paint方法中添加了下面一行:'g.clearRect(0,800,600,600 );' - 這給你一個清晰的屏幕,每次工作。它導致一個新的閃爍,你需要雙緩衝來擺脫,但是你至少能夠看到你的XY座標,而不是隨着時間的推移它們變成一個巨大的黑盒子:) – corsiKa

+0

我收回它。如果你使用正確的鍵hahaha,你確實會移動。我正在使用箭頭鍵,而不是WADS。 :-)但清晰仍然效果最好。 – corsiKa

4

你絕對想看看雙緩衝。現在你正在做的是直接將所有東西畫到屏幕上,用戶看到了這一點。雙緩衝的作用是首先在屏幕外的緩衝區(圖像)上繪製所有內容,一旦計算完所有內容並且圖像準備就緒後,就可以將屏幕緩衝區繪製到可見緩衝區上(因此用戶只能看到最後一幀而不是中間幀)。

這與OpenGL或Direct3D應用程序最常用的類似概念。他們有兩個緩衝區。一切都被拖到屏幕外的緩衝區中,一旦完成,緩衝區就會被交換,而現在屏幕外的緩衝區將被清除,然後再次繪製新的圖像。

而且glowcoder也指出,你有一個非常高的fps。嘗試將其與顯示器的刷新頻率同步,以避免浪費資源,而不是經常需要。

+0

感謝您的幫助:D – user1007883