簡體   English   中英

Java repaint()方法並不總是有效

[英]Java repaint() method doesn't always work

Java中的repaint()方法存在問題。 我創建了一個新線程,該線程不斷重新繪制屏幕。 當我釋放空格鍵時,我希望播放器通過設置其位置來平穩下落,然后等待50毫秒並循環播放20次。 相反,它會等待整個循環時間, 然后重新繪制。 我想知道為什么它不能不斷地重繪玩家坐標中的變化。 謝謝。

(編輯)謝謝大家的幫助。 這是我第一次使用堆棧溢出,我只有13歲,仍然在學習Java,因此我可能會再次回到教程。

我的“ a”班(主要):

public class a {
    public static void main(String[] args) {
        JFrame frame = new JFrame("StickFigure Game");
        frame.setSize(740, 580);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        b board = new b();
        frame.add(board);
        frame.addKeyListener(board);
    }
}

我的“ b”課(JPanel /繪畫):

public class b extends JPanel implements KeyListener {
    c player = new c();

    public class MyRunnable implements Runnable {

        public void run() {
            while (true)
                repaint();
        }
    }

    MyRunnable run = new MyRunnable();

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(player.getImage(), player.getX(), player.getY(), 80, 140,
                null);
    }

    public b() {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
    }

    public static void slow(int n) {
        long t0, t1;
        t0 = System.currentTimeMillis();
        do {
            t1 = System.currentTimeMillis();
        } while (t1 - t0 < n);
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_D) {
            player.setPos(player.getX() + 6, player.getY());
        }
        if (e.getKeyCode() == KeyEvent.VK_A) {
            player.setPos(player.getX() - 6, player.getY());
        }
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            player.setPos(player.getX(), player.getY() - 60);
        }
    }

    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {

            for (int i = 0; i < 20; i++) {
                slow(50);
                player.setPos(player.getX(), player.getY() + 2);
            }
        }
    }

    public void keyTyped(KeyEvent e) {
    }
}

我的“ c”課(玩家):

public class c {
    private ImageIcon i = new ImageIcon("guy.png");
    private Image img = i.getImage();
    private int x = 0;
    private int y = 100;

    public void wait(int what) {
        try {
            Thread.sleep(what);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public c() {
    }

    public Image getImage() {
        return img;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void setPos(int mx, int my) {
        x = mx;
        y = my;
    }
}

我沒有在這里瀏覽所有代碼,但是這里有一些指針:

  • Swing有自己的並發機制 ,可讓您處理UI更新。 您可以使用Swing計時器,而不是原始Thread 相關的是Thread.sleep的使用-不要這樣做,它只會阻止EDT並阻止UI更新。
  • Swing繪畫鏈機制要求您重寫paintComponent而不是paint
  • 在Swing中始終使用鍵綁定而不是KeyListeners KeyListeners需要組件焦點才能與KeyEvents交互。 Key Bindings沒有此限制。

“ java中的repaint()方法存在問題。” 您是否認為問題可能出在您的代碼上? 您正在阻止事件線程,並且沒有時間讓系統進行中間重繪。 特別是,此方法:

public static void slow (int n){
    long t0,t1;
    t0=System.currentTimeMillis();
    do{
        t1=System.currentTimeMillis();
    }
    while (t1-t0<n);
}

和這個循環:

for(int i = 0;i<20;i++){
    slow(50);
    player.setPos(player.getX(), player.getY()+2);
}

不要放棄對系統的控制,以便重新繪制實際上可以發生。 使用Swing計時器重寫它們。 請參閱本教程 ,以獲取有關如何使用它們的介紹。

另外,您的線程在一個緊密的循環中不斷調用repaint()

public void run(){
  while(true) repaint();
}

是一個可怕的主意。 您無需以全CPU速度調用repaint() 每30毫秒左右一次適合動畫。 同樣,考慮使用Swing實用程序執行此操作,而不是編寫自己的循環線程。

repaint只是盡快repaint的“要求”。 因此,當您調用它時,它會導致盡快調用paint方法。

這里

所以基本上你只是泛濫的排定呼叫paintupdatewhile(true) repaint();

甲骨文對AWT和Swing繪畫的立場

一種可行的方法,或者我應該說怎么做,是使您的c類實現KeyListener ,以便在按下鍵時(且僅在按下鍵時)更新其位置。

因此,將您的KeyListener方法移動到類c ,在您的類b構造函數中,您可以添加調用this.addKeyListener(player)或使方法void addPlayer(c player)進行添加。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM