2015-01-05 71 views
0

我是新來的java,我有一個問題。我可以讓我的形狀在全部四個方向上移動,但是我無法停止線程,因此形狀只能朝一個方向移動。此外,我要畫形狀後面的一條線(TRON認爲光周期的),但我不能確定怎麼做...如何停止鍵處理程序中的線程

package test; 

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import javax.swing.JFrame; 
import java.awt.event.KeyListener; 
import java.awt.event.KeyEvent; 
import javax.swing.JPanel; 

@SuppressWarnings("serial") 
public class Test extends JPanel implements KeyListener { 

    int x = Test.WIDTH/2; 
    int y = Test.HEIGHT/2; 

    public void paint(Graphics g) { 
     super.paint(g); 
     Graphics2D g2d; 
     g2d = (Graphics2D) g; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
     RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.fillRect(x, y, 10, 10); 
    } 

    private void moveleft() { 
     new Thread (new Runnable() 
     { 
      public void run() 
      { 
       while(true) 
       { 

        x = x - 1; 
        repaint(); 
        //System.out.println("Right");//For debugging purposes 
        try { 
         Thread.currentThread().sleep(6); 
        } catch (Exception e){} 
        if(!true) 
         break; 
       } 
      } 
     }).start(); 
    } 

    private void moveright() { 
     new Thread (new Runnable() 
     { 
      public void run() 
      { 
       while(true) 
       { 
        x = x + 1; 
        repaint(); 
        //System.out.println("Right");//For debugging purposes 
        try { 
         Thread.currentThread().sleep(6); 
        } catch (Exception e){} 
        if(!true) 
         break; 
       } 
      } 
     }).start(); 
    } 

    private void moveup() { 
     new Thread (new Runnable() 
     { 
      public void run() 
      { 
       while(true) 
       { 
        y = y - 1; 
        repaint(); 
        //System.out.println("Right");//For debugging purposes 
        try { 
         Thread.currentThread().sleep(6); 
        } catch (Exception e){} 
        if(!true) 
         break; 
       } 
      } 
     }).start(); 
    } 

    private void movedown() { 
     new Thread (new Runnable() 
     { 
      public void run() 
      { 
       while(true) 
       { 
        y = y + 1; 
        repaint(); 
        //System.out.println("Right");//For debugging purposes 
        try { 
         Thread.currentThread().sleep(6); 
        } catch (Exception e){} 
        if(!true) 
         break; 
       } 
      } 
     }).start(); 
    } 

    public void keyPressed(KeyEvent e) { 
     //System.out.println("keyPressed"); 
     if (e.getKeyCode() == KeyEvent.VK_RIGHT) { 
      //D.start(); 

      moveright(); 
     } else if (e.getKeyCode() == KeyEvent.VK_LEFT) { 
      moveleft(); 
     } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { 
      movedown(); 
     } else if (e.getKeyCode() == KeyEvent.VK_UP) { 
      moveup(); 
     } 
    } 

    public void keyReleased(KeyEvent e) { 
    } 

    public void keyTyped(KeyEvent e) { 
     System.out.println("keyTyped"); 
    } 

    public Test() { 

     //this=new maindraw(); 
     addKeyListener(this); 
     setFocusable(true); 
     setFocusTraversalKeysEnabled(false); 

    } 

    public static void main(String[] args) throws InterruptedException { 
     JFrame frame = new JFrame("BMTRON"); 
     Test game = new Test(); 
     frame.add(game); 
     frame.setSize(500, 500); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 
+2

不要使用布爾文字,'while(true)'。爲什麼不使用可以由用戶更改的易變布爾變量?此外,只要可行,您應該更喜歡KeyListeners上的Key Bindings。 –

回答

3
  1. 風俗畫是通過覆蓋paintComponent(...)沒有做漆(...) 。
  2. 請勿使用KeyListener。鞦韆是專爲KeyBindings

使用如何在keyhandler

您需要偵聽的keyReleased事件中停止線程。

欲瞭解更多信息和想法檢查出Motion Using the Keyboard。沒有確切地表明你想要什麼,但概念是相同的。

+0

感謝您的幫助,但我也想知道。是否可以使用這個命名一個線程?新的線程(新的Runnable()),如果不是,我將如何命名我的程序中的線程,以便我可以阻止它們? –

0

你應該有線程本身內的線程退出代碼。 您可以添加標誌變量來檢查線程是否退出。

private boolean isMovingLeft; // this flag will control the loop to exit. 
private boolean isMovingRight; // this flag will control the loop to exit. 
private boolean isMovingUp;  // this flag will control the loop to exit. 
private boolean isMovingDown; // this flag will control the loop to exit. 

private void movedown() { 
    isMovingLeft = false; // this will make moveleft thread to exit in time. 
    isMovingRight = false; // this will make moveright thread to exit in time. 
    isMovingUp = false;  // this will make moveup thread to exit in time. 
    if(isMovingDown) { 
     // movedown loop thread is already running. 
     return; 
    } 

    isMovingDown = true; 

    new Thread (new Runnable() 
    { 
     public void run() 
     { 
      while(isMovingDown) 
      { 
       y = y + 1; 
       repaint(); 
       try { 
        Thread.currentThread().sleep(6); 
        } catch (Exception e){} 
       if(!true) 
        break; 
      } 
     } 
    }).start(); 
} 
0

您好安德魯·麥克米蘭,

我想你可以簡單地輸入單獨處理從繪畫(從Jaemok李提到的)...

我確信自己總是驅動器插入一個方向,所以你可以啓動動畫線程啓動(或任何你想要的)

public void onStart(){ 
    animationThread.start(); //do this when you start your game 
} 

保持編碼簡化le使用兩個整數作爲你的運動,dx和dy。只要按下一個鍵,你調整值 - 這個任務是由動畫線程中完成的:

int dx = 0; 
int dy = 0; 
boolean isRunning = true; 

Thread animationThread = new Thread(new Runnable(){ 

    @Override 
    public void run(){ 
     while(isRunning){ //as mentioned from 
          //HovercraftFullOfEels: define a abort-criteria 

      //move your player by using dx and dy 
      player.xpos = player .xpos + dx; 
      player.ypos = player .ypos + dy; 

      //update your gui 
      panel.repaint(); 

      //wait for the next 'turn'; TODO: surround with try/catch 
      Thread.sleep(100); 
     } 
    } 
} 

輸入來自面板,使用的鍵綁定。這是爲了向上鍵,並且還需要爲其他鍵完成。您可以縮短該示例並僅使用key_pressed_event。 dy = 0;只有在您想停止播放器時才能使用。

如果你想,也許通過按下停止動畫
JPanel panel = new JPanel(); 

//define a 'key object' (define TWO key objects) 
final String KEY_UP_PRESSED_INPUT = "KEY_UP_PRESSED"; 
final String KEY_UP_RELEASE_INPUT = "KEY_UP_RELEASED"; 

//get the corresponding key strokes 
KeyStroke upPressed = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false); 
KeyStroke upReleased = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true); 

//put them into the map 
panel.getInputMap().put(upPressed, KEY_UP_PRESSED_INPUT); 
panel.getInputMap().put(upReleased, KEY_UP_RELEASE_INPUT); 


//define the action performed 
panel.getActionMap().put(KEY_UP_PRESSED_INPUT, new AbstractAction() { 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     System.out.println("up pressed!"); 
     dy = -1; //upwards 
    } 
}); 

panel.getActionMap().put(KEY_UP_RELEASE_INPUT, new AbstractAction() { 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     System.out.println("up released!"); 
     dy = 0; //no more upwards 
    } 
}); 

VK_ESC您只需設置isRunning = false;

好運!