2016-05-11 11 views
1

Ich versuche, ein Spiel in Java zu machen und dies ist mein erstes Mal mit Multithreading (na ja, von Musik gleichzeitig über die Clip-Klasse.) Ich habe eine Canvas-Klasse, die JPanel erweitert, aber innerhalb die Canvas-Klasse ich habe auch einen KeyListener Eingang zu nehmen, hier gezeigt:Concurrent Methoden über Multithreading

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) 
    { 
    } 
} 

Mein Ziel ist es zu haben, so dass man beide Spieler bewegen können gleichzeitig auf der Leinwand (die Rechtecke sind). Gegenwärtig kann man sie nur einzeln bewegen, aber niemals beide gleichzeitig. Dies ist mein erstes Mal mit Multithreading, also entschuldige ich mich im Voraus, wenn ich einen Anfängerfehler mache.

+0

Ich habe nicht genau verstanden, was Sie tun möchten. Sie können nicht beide Spieler gleichzeitig mit diesem Code bewegen, da Sie nicht zwei Tasten gleichzeitig drücken können. Bei jedem Drücken einer Taste wird die Methode keyPressed() einmal aufgerufen. – Daniel

+0

Meinst du zwei Leute, die die gleiche Tastatur benutzen, wobei jeder einen Spieler steuert? – Daniel

+0

@Daniel Ja, tat ich. So wird zum Beispiel auf derselben Tastatur eine Person die Pfeiltasten verwenden, um den Rectangle player1 zu steuern, und die andere Person wird WASD verwenden, um das Rectangle zu steuern. Player2 – ADC2000

Antwort

1

Hier ist der Code.

Sie brauchen nur einen Thread, um die "Spielschleife" zu machen.

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

Danke @Daniel. Ich experimentiere jetzt mit KeyBindings herum, aber das passt genau zu meinen Zielen. Vielen Dank. – 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){} 
} 
} 

, die dann von dieser Klasse ausgeführt wird, ist

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(); 
} 
}