2012-11-17 42 views
2

這段代碼大部分都是完美的。在線算法中「飛過去」?

import java.awt.*; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

import javax.swing.*; 


public class Main { 

    public static void main(String[] args) { 
     new Main(); 
    } 

    private Main() { 
     JFrame f = new JFrame("Test"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new Game()); 
     f.setResizable(false); 
     f.pack(); 
     f.setVisible(true); 
    } 

    private class Game extends JPanel implements MouseListener { 
     private static final long serialVersionUID = -7048656881407382561L; 
     int x = 300, y = 300; 
     Image thing; 
     ImageIcon ico = new ImageIcon("smiley.png"); 
     private Game() { 
      setPreferredSize(new Dimension(600, 600)); 
      thing = ico.getImage(); 
      addMouseListener(this); 
     } 
     private void goTo(int stX, int stY, int endX, int endY) { 
      int dx = Math.abs(endX - stX); 
      int dy = Math.abs(endY - stY); 
      int sx = endX > stX ? 1 : -1; 
      int sy = endY > stY ? 1 : -1; 
      int err = dx - dy; 
      while (true) { 
       x = stX; 
       y = stY; 
       repaint(); 
       validate(); 
       if (stX == endX && stY == endY) break; 
       if ((err*2) > -dy) { 
        err -= dy; 
        stX += sx; 
       } 
       if ((err*2) < dx) { 
        err += dx; 
        stY += sy; 
       } 
       try { 
        Thread.sleep(10); 
       } catch (InterruptedException e) {} 
      } 
     } 
     private void goTo(final int endX, final int endY) { 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        goTo(x, y, endX, endY); 
       } 
      }).start(); 
     } 
     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      ((Graphics2D)g).drawImage(thing, x, y, null); 
     } 
     @Override 
     public void mousePressed(MouseEvent e) { 
      goTo(e.getX(), e.getY()); 
     } 
     public void mouseReleased(MouseEvent e) {} //These 
     public void mouseEntered(MouseEvent e) {} //are 
     public void mouseExited(MouseEvent e) {} //useless 
     public void mouseClicked(MouseEvent e) {} //methods 
    } 

} 

只有一個問題:有時,看似隨意,圖像只是繼續前進,而不是停止點擊鼠標的位置。通常它是有效的,但有時它會混亂並繼續前進。

下面是與它有關的圖像。 smiley face

我注意到,如果你點擊他的眼睛之間,它總是會飛走。

+1

我認爲這是併發問題。你不使用invokeLater,x,y變量也沒有標記爲volatile,並且它們出現在不同的線程中。 – gregory561

回答

1

我改變了你的while語句,它似乎對我來說工作得很好。

private void goTo(int stX, int stY, int endX, int endY) { 
     int dx = Math.abs(endX - stX); 
     int dy = Math.abs(endY - stY); 
     int sx = endX > stX ? 1 : -1; 
     int sy = endY > stY ? 1 : -1; 
     int err = dx - dy; 
     while (stX != endX && stY != endY) { 
      x = stX; 
      y = stY; 
      repaint(); 
      validate(); 
      if ((err*2) > -dy) { 
       err -= dy; 
       stX += sx; 
      } 
      if ((err*2) < dx) { 
       err += dx; 
       stY += sy; 
      } 
      try { 
       Thread.sleep(10); 
      } catch (InterruptedException e) {} 
     } 
    } 

注意在這條線的變化:while (stX != endX && stY != endY) {

您也可以考慮增加一個開關布爾值,這樣就可以不發出另一個GOTO當圖像被感動,因爲現在你可以得到一些非常有趣的結果快速點擊。

+0

謝謝,當我回家時我會嘗試。現在,upvote。 :) – Doorknob