2012-11-17 3 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) {

당신은 또한 이미지가 이동하는 동안 지금 당신은 꽤 흥미로운 결과를 얻을 수 있습니다 당신이 다른 고토 발행 할 수 있도록 스위칭 부울를 추가하는 것도 고려해 볼 수 있습니다 빠른 클릭으로

+0

고마움, 나는 내가 집에 돌아갈 때 그것을 시험해 볼 것이다. 지금 들어, upvote. :) – Doorknob