2016-05-11 51 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(); 
} 
}