2016-05-11 95 views
1

我想在Java中製作遊戲,這是我第一次處理多線程(好吧,通過Clip類同時播放音樂的旁白。)我有一個Canvas類,它擴展了JPanel,但內Canvas類我也有一個KeyListener的取輸入,如下所示:通過多線程併發方法

private class myKeyListener implements KeyListener 
{ 
    public void keyPressed(KeyEvent keyEvent) 
    { 
     if(keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE){System.exit (0);} 

     Thread thread3 = new Thread() 
      { 
       public void run() { 
        if(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT){moveX(5, player1);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_LEFT){moveX(-5, player1);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_UP){moveY(-5, player1);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_DOWN){moveY (5, player1);} 
       } 
      }; 

     Thread thread4 = new Thread() 
      { 
       public void run() { 
        if(keyEvent.getKeyCode() == KeyEvent.VK_D){moveX(5, player2);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_A){moveX(-5, player2);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_W){moveY(-5, player2);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_S){ moveY(5, player2);} 
       } 
      }; 

     Thread thread5 = new Thread() 
      { 
       public void run() { 
        repaint(); 
       } 
      }; 

     thread3.start(); 
     thread4.start(); 
     thread5.start(); 

     try{ 
      thread3.join(); 
      thread4.join(); 
      thread5.join(); 
     } 
     catch (Exception e){System.out.println(e);} 

     repaint(); 
    } 

    public void keyReleased(KeyEvent keyEvent) 
    { 

    } 

    public void keyTyped(KeyEvent keyEvent) 
    { 
    } 
} 

我的目標是有它,使人們可以在同一時間在畫布上移動這兩個球員(這是矩形)。目前,一次只能移動一個,但不能同時移動兩個。這是我第一次處理多線程問題,所以如果我犯了一個新手的錯誤,我會提前道歉。

+0

我不明白你想要做什麼。您無法同時使用此代碼移動兩個玩家,因爲您無法同時按兩個鍵。每次按一個鍵時,方法keyPressed()都會被調用一次。 – Daniel

+0

你的意思是兩個人使用同一個鍵盤,每個人控制一個玩家? – Daniel

+0

@丹尼爾是的,我做到了。例如,在相同的鍵盤上,一個人將使用箭頭鍵來控制矩形玩家1,另一個人將使用WASD來控制矩形玩家2 – ADC2000

回答

1

這裏執行是代碼。

你只需要一個線程來完成「遊戲循環」。

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.JPanel; 
import java.util.ArrayList; 

public class Canvas2 extends JPanel { 
    // attributes 
    private Rectangle player1; 
    private Rectangle player2; 
    private ArrayList<KeyEvent> log; 

    private boolean player1left = false; 
    private boolean player1right = false; 
    private boolean player1up = false; 
    private boolean player1down = false; 
    private boolean player2left = false; 
    private boolean player2right = false; 
    private boolean player2up = false; 
    private boolean player2down = false; 

    // constructor 
    public Canvas2() { 
     // initialize object 
     player1 = new Rectangle(50, 50, 50, 50); 
     player2 = new Rectangle(50, 50, 50, 50); 

     log = new ArrayList<KeyEvent>(); 

     // set canavs background colour 
     setBackground(Color.white); 

     // add the key listener in the constructor of your canavas/panel 
     addKeyListener(new myKeyListener()); 

     // ensure focus is on this canavas/panel for key operations. 
     setFocusable(true); 

     Thread gameLoop = new Thread() { 
      public void run() { 
       while (true) { 
        updatePlayers(); 
        repaint(); 
        pause(10); 
       } 

      } 
     }; 

     gameLoop.start(); 

    } 

    private void updatePlayers() { 
     if (player1left) { 
      moveX(-5, player1); 
     } 
     if (player1right) { 
      moveX(5, player1); 
     } 
     if (player1up) { 
      moveY(-5, player1); 
     } 
     if (player1down) { 
      moveY(5, player1); 
     } 
     if (player2left) { 
      moveX(-5, player2); 
     } 
     if (player2right) { 
      moveX(5, player2); 
     } 
     if (player2up) { 
      moveY(-5, player2); 
     } 
     if (player2down) { 
      moveY(5, player2); 
     } 
    } 

    // painting 
    public void paintComponent(Graphics graphics) { 
     super.paintComponent(graphics); 
     Graphics2D graphics2d = (Graphics2D) graphics; 

     graphics.setColor(Color.blue); 
     graphics2d.fill(player1); 
     graphics2d.fill(player2); 
    } 

    // function which essentially re-creates rectangle with varying x 
    // orientations. (x-movement) 
    public void moveX(int mutationDistance, Rectangle sampleObject) { 
     sampleObject.setBounds(sampleObject.x + mutationDistance, 
       sampleObject.y, sampleObject.width, sampleObject.height); 
    } 

    // function which essentially re-creates rectangle with varying y 
    // orientations. (y-movement) 
    public void moveY(int mutationDistance, Rectangle sampleObject) { 
     sampleObject.setBounds(sampleObject.x, sampleObject.y 
       + mutationDistance, sampleObject.width, sampleObject.height); 
    } 

    // listener 
    private class myKeyListener implements KeyListener { 
     // implement all the possible actions on keys 
     public void keyPressed(final KeyEvent keyEvent) { 
      if (keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE) { 
       System.exit(0); 
      } 

      if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) { 
       player1right = true; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_LEFT) { 
       player1left = true; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_UP) { 
       player1up = true; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN) { 
       player1down = true; 
      } 

      if (keyEvent.getKeyCode() == KeyEvent.VK_D) { 
       player2right = true; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_A) { 
       player2left = true; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_W) { 
       player2up = true; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_S) { 
       player2down = true; 
      } 


     } 

     public void keyReleased(KeyEvent keyEvent) { 
      if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) { 
       player1right = false; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_LEFT) { 
       player1left = false; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_UP) { 
       player1up = false; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN) { 
       player1down = false; 
      } 

      if (keyEvent.getKeyCode() == KeyEvent.VK_D) { 
       player2right = false; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_A) { 
       player2left = false; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_W) { 
       player2up = false; 
      } 
      if (keyEvent.getKeyCode() == KeyEvent.VK_S) { 
       player2down = false; 
      } 
     } 

     public void keyTyped(KeyEvent keyEvent) { 
     } 
    } 

    public static void pause(int secs) { 
     try { 
      Thread.sleep(secs); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

謝謝@Daniel,我已將它作爲下面的答案發布。我現在正在嘗試使用KeyBindings,但這完全符合我的目的。謝謝。 – ADC2000

0
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.JPanel; 
import java.util.ArrayList; 

/** 
* This code was originally by the user "UniBrain" from the website: 
* http://forum.codecall.net/topic/74377-moving-graphics-across-up-and-down-a-jpanel/?p=652384 
* 
* but has been modified by me for my own purposes 
*/ 

public class Canvas2 extends JPanel 
{ 
//attributes 
private Rectangle player1; 
private Rectangle player2; 
private ArrayList<KeyEvent> log; 

//constructor 
public Canvas2() 
{ 
    //initialize object 
    player1 = new Rectangle (50, 50, 50, 50); 
    player2 = new Rectangle (50, 50, 50, 50); 

    log = new ArrayList<KeyEvent>(); 

    //set canavs background colour 
    setBackground (Color.white); 

    //add the key listener in the constructor of your canavas/panel 
    addKeyListener(new myKeyListener()); 

    //ensure focus is on this canavas/panel for key operations. 
    setFocusable(true); 
} 

//painting 
public void paintComponent(Graphics graphics) 
{ 
    super.paintComponent(graphics); 
    Graphics2D graphics2d =(Graphics2D)graphics; 

    graphics.setColor(Color.blue); 
    graphics2d.fill(player1); 
    graphics2d.fill(player2); 
} 

//function which essentially re-creates rectangle with varying x orientations. (x-movement) 
public void moveX(int mutationDistance, Rectangle sampleObject) 
{ 
    sampleObject.setBounds(sampleObject.x + mutationDistance, sampleObject.y, sampleObject.width, sampleObject.height); 
} 

//function which essentially re-creates rectangle with varying y orientations. (y-movement) 
public void moveY(int mutationDistance, Rectangle sampleObject) 
{ 
    sampleObject.setBounds(sampleObject.x, sampleObject.y + mutationDistance, sampleObject.width, sampleObject.height); 
} 

public void move(){ 
    /* 
    * This method of keeping track of key events and using a loop is taken from the user Michael Meyers at 
    * http://stackoverflow.com/questions/752999/how-do-i-handle-multiple-key-presses-in-java 
    */ 
    Thread thread1 = new Thread() 
     { 
      public void run() { 
       for(KeyEvent keyEvent: log){ 
        if(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT){moveX(5, player1);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_LEFT){moveX (-5, player1);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_UP){moveY (-5, player1);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_DOWN){moveY (5, player1);} 
       } 
      } 
     }; 
    Thread thread2 = new Thread() 
     { 
      public void run() { 
       for(KeyEvent keyEvent: log){ 
        if(keyEvent.getKeyCode() == KeyEvent.VK_D){moveX(5, player2);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_A){moveX(-5, player2);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_W){moveY(-5, player2);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_S){moveY(5, player2);} 
       } 
      } 
     }; 

    //Starts the threads 
    thread1.start(); 
    thread2.start(); 

    //Waits for them to finish 
    try{ 
     thread1.join(); 
     thread2.join(); 
     log = new ArrayList<KeyEvent>(); 
    } 
    catch (Exception e){System.out.println(e);} 
} 
//listener 
private class myKeyListener implements KeyListener 
{ 
    //implement all the possible actions on keys 
    public void keyPressed(KeyEvent keyEvent) 
    { 
     if(keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE){System.exit (0);} 

     Thread thread3 = new Thread() 
      { 
       public void run() { 
        if(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT){moveX(5, player1);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_LEFT){moveX(-5, player1);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_UP){moveY(-5, player1);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_DOWN){moveY (5, player1);} 
       } 
      }; 

     Thread thread4 = new Thread() 
      { 
       public void run() { 
        if(keyEvent.getKeyCode() == KeyEvent.VK_D){moveX(5, player2);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_A){moveX(-5, player2);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_W){moveY(-5, player2);} 
        if(keyEvent.getKeyCode() == KeyEvent.VK_S){ moveY(5, player2);} 
       } 
      }; 

     Thread thread5 = new Thread() 
      { 
       public void run() { 
        repaint(); 
       } 
      }; 

     thread3.start(); 
     thread4.start(); 
     thread5.start(); 

     try{ 
      thread3.join(); 
      thread4.join(); 
      thread5.join(); 
     } 
     catch (Exception e){System.out.println(e);} 

     repaint(); 
    } 

    public void keyReleased(KeyEvent keyEvent) 
    { 
    } 

    public void keyTyped(KeyEvent keyEvent) 
    { 
    } 
} 

public static void pause(int secs){ 
    try{Thread.sleep(secs*0);} catch(Exception e){} 
} 
} 

然後由這個類

import javax.swing.JFrame; 
import java.awt.Dimension; 

/** 
* This code was taken from the user "UniBrain" from the website: 
* http://forum.codecall.net/topic/74377-moving-graphics-across-up-and-down-a-jpanel/?p=652384 
*/ 

public class Display 
{ 

public static void main (String [ ] arguments) 
{ 
    JFrame frame = new JFrame("key listener demo"); 
    Canvas2 panel = new Canvas2(); 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.add(panel); 
    frame.setContentPane(panel); 

    frame.setPreferredSize(new Dimension(800, 600)); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
    frame.pack(); 
} 
}