2012-10-20 5 views
2

으로 제어 앞뒤로 모든 키 W 및 S하지만 늘 플레이어를 제어하고 위쪽 및 아래쪽 화살표 키를 2퐁 내가 일을 내 탁구 게임,이 프로젝트가 나는 것을 볼 바운스가 좀 더 많은 작업</p> <p>를하기로 결정 단순히 공을 시작 물리학을 가지고 있지만 점점 약간의 문제에 실행 한 모든 KeyListener

public void keyPressed(KeyEvent e){ 
      if(e.getKeyCode() == e.VK_UP){ 
       p2Y -= 3; 
       System.out.println("UP"); 
      } 
      if(e.getKeyCode() == e.VK_DOWN){ 
       p2Y += 3; 
       System.out.println("Down"); 
      } 
      if(e.getKeyCode() == e.VK_W){ 
       p1Y -= 3; 
       System.out.println("Up"); 
      } 
      if(e.getKeyCode() == e.VK_S){ 
       p1Y += 3; 
       System.out.println("down"); 
      } 
      repaint(); 
     } 

그것은 늘 심지어 내가 알고 해달라고

시스템 인쇄 메시지를 표시 플레이어를 제어 그나마 그 코드의이 부분 만 문제가되거나 omewhere 다른

는 다른 곳에서 여기 경우이 파일의 나머지 부분에 대한 링크가 http://pastebin.com/TJbLBxL7

전체 코드 :

import javax.swing.*; 


import java.awt.*; 
import java.awt.event.*; 
import java.util.ArrayList; 

public class Pong extends JPanel 
{ 
    Circle circle1; 
    javax.swing.Timer timer; 
    ArrayList<Point> points = new ArrayList<Point>(); 
    int p1X=10, p1Y=320; 
    int p2X=760, p2Y = 320; 
    int y, y1; 

    int p1Score, p2Score; 

    boolean playing = true; 

    public Pong(Color backcolor, int Width, int Height) 
    { 
     setBackground(backcolor); 
     setPreferredSize(new Dimension(Width, Height)); 

     //first circle 

     circle1 = new Circle(Width/2, 360, 15, Color.white); 
     circle1.setVelocity(4); 
     circle1.setDirection(180); 

     timer = new javax.swing.Timer(5, new MoveListener()); 
     addKeyListener(new KeyWatcher()); 
     timer.start(); 
    } 

    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 

     //first circle 
     circle1.draw(g); 
     circle1.fill(g); 

     // Draw Players 
     g.setColor(Color.red); 
     g.fillRect(p1X, p1Y, 10, 75); 
     g.setColor(Color.blue); 
     g.fillRect(p2X, p2Y, 10, 75); 

     //Draw Scores 
     g.setColor(Color.white); 
     g.drawString("Player 1's Score: " + p1Score, 10, 10); 
     g.drawString("Player 2's Score: " + p2Score, getWidth() - 120, 10); 
     repaint(); 

     if(!playing) 
     { 
      g.setColor(Color.red); 
      g.drawString("GAMEOVER!!!", (getWidth()/2) - 15, 10); 
     } 
     else 
     { 
     } 
    } 

    private class MoveListener extends MouseAdapter implements ActionListener 
    { 
     public void actionPerformed(ActionEvent arg0) 
     { 

      int x1 = circle1.getX(); 
      int y1 = circle1.getY(); 
      int width = getWidth(); 
      int height = getHeight(); 
      int radius1 = circle1.getRadius(); 

      //first circle 

      if(x1 - radius1 <= 0) 
      { 
       p2Score++; 
       circle1.setX(getWidth()/2); 
       circle1.setY(getHeight()/2); 
      } 
      if(x1 + radius1 >= width) 
      { 
       p1Score++; 

       circle1.setX(getWidth()/2); 
       circle1.setY(getHeight()/2); 
      } 
      if(y1 - radius1 <= 0 || y1 + radius1 >= height) 
      { 
       circle1.turnY(); 

      } 

      if((x1 - radius1 == p1X) || (x1 + radius1 == p2X)) 
      { 
       circle1.turnX(); 
      } 

      circle1.move(); 
      repaint(); 
     } 

     public void GameOver() 
     { 
      playing = false; 
     } 

    } 
    private class KeyWatcher implements KeyListener 
    { 

     @Override 
     public void keyPressed(KeyEvent e){ 
      if(e.getKeyCode() == e.VK_UP){ 
       p2Y -= 3; 
       System.out.println("UP"); 
      } 
      if(e.getKeyCode() == e.VK_DOWN){ 
       p2Y += 3; 
       System.out.println("Down"); 
      } 
      if(e.getKeyCode() == e.VK_W){ 
       p1Y -= 3; 
       System.out.println("Up"); 
      } 
      if(e.getKeyCode() == e.VK_S){ 
       p1Y += 3; 
       System.out.println("down"); 
      } 
      repaint(); 
     } 

     @Override 
     public void keyReleased(KeyEvent e){ 
      //if(e.getKeyCode() == e.VK_UP){ 
      //  y1 = p2Y; 
      //  repaint(); 
      // } 
      // if(e.getKeyCode() == e.VK_DOWN){ 
      //  y1 = p2Y; 
      //  repaint(); 
      // } 
      //if(e.getKeyCode() == e.VK_W){ 
      //  y = p1Y; 
      //  repaint(); 
      // } 
      // if(e.getKeyCode() == e.VK_S){ 
      //  y = p1Y; 
      //  repaint(); 
      // } 
     } 

     @Override 
     public void keyTyped(KeyEvent arg0) { 
      // TODO Auto-generated method stub 

     } 


    } 
} 

나의 새로운 코드 이 하나의 문제는 아니라 한 번에 한 명의 플레이어가 제어 할 수 있습니다.

또한 2 개의 MyKeyAction을 작성하여 수정하려고 저의 어리석은 시도가 있지만 전혀 변하지 않았습니다.

package Bouncy; 

import javax.swing.*; 


import java.awt.*; 
import java.awt.event.*; 
import java.util.ArrayList; 

public class Pong extends JPanel 
{ 
    Circle circle1; 
    javax.swing.Timer timer; 
    ArrayList<Point> points = new ArrayList<Point>(); 
    int p1X=10, p1Y=320; 
    int p2X=760, p2Y = 320; 
    int y, y1; 

    int p1Score, p2Score; 

    boolean playing = true; 

    public Pong(Color backcolor, int Width, int Height) 
    { 
     setBackground(backcolor); 
     setPreferredSize(new Dimension(Width, Height)); 

     //first circle 

     circle1 = new Circle(Width/2, 360, 15, Color.white); 
     circle1.setVelocity(4); 
     circle1.setDirection(180); 

     timer = new javax.swing.Timer(5, new MoveListener()); 
     setupKeyBinding(); 
     setupKeyBinding2(); 
     timer.start(); 
    } 
    private void setupKeyBinding() { 
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; 
      InputMap inMap = getInputMap(condition); 
      ActionMap actMap = getActionMap(); 

      // this uses an enum of Direction that holds ints for the arrow keys 
      for (DirectionP1 direction : DirectionP1.values()) { 
      int key = direction.getKey(); 
      String name = direction.name(); 

      // add the key bindings for arrow key and shift-arrow key 
      inMap.put(KeyStroke.getKeyStroke(key, 0), name); 
      inMap.put(KeyStroke.getKeyStroke(key, InputEvent.SHIFT_DOWN_MASK), name); 
      actMap.put(name, new MyKeyAction(direction)); 
      } 
     } 
    private void setupKeyBinding2() { 
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; 
      InputMap inMap = getInputMap(condition); 
      ActionMap actMap = getActionMap(); 

      // this uses an enum of Direction that holds ints for the arrow keys 
      for (DirectionP2 direction : DirectionP2.values()) { 
      int key = direction.getKey(); 
      String name = direction.name(); 

      // add the key bindings for arrow key and shift-arrow key 
      inMap.put(KeyStroke.getKeyStroke(key, 0), name); 
      inMap.put(KeyStroke.getKeyStroke(key, InputEvent.SHIFT_DOWN_MASK), name); 
      actMap.put(name, new MyKeyAction2(direction)); 
      } 
     } 
    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 

     //first circle 
     circle1.draw(g); 
     circle1.fill(g); 

     // Draw Players 
     g.setColor(Color.red); 
     g.fillRect(p1X, p1Y, 10, 75); 
     g.setColor(Color.blue); 
     g.fillRect(p2X, p2Y, 10, 75); 

     //Draw Scores 
     g.setColor(Color.white); 
     g.drawString("Player 1's Score: " + p1Score, 10, 10); 
     g.drawString("Player 2's Score: " + p2Score, getWidth() - 120, 10); 
     repaint(); 

     if(!playing) 
     { 
      g.setColor(Color.red); 
      g.drawString("GAMEOVER!!!", (getWidth()/2) - 15, 10); 
     } 
     else 
     { 
     } 
    } 

    private class MoveListener extends MouseAdapter implements ActionListener 
    { 
     public void actionPerformed(ActionEvent arg0) 
     { 

      int x1 = circle1.getX(); 
      int y1 = circle1.getY(); 
      int width = getWidth(); 
      int height = getHeight(); 
      int radius1 = circle1.getRadius(); 

      //first circle 

      if(x1 - radius1 <= 0) 
      { 
       p2Score++; 
       circle1.setX(getWidth()/2); 
       circle1.setY(getHeight()/2); 
      } 
      if(x1 + radius1 >= width) 
      { 
       p1Score++; 

       circle1.setX(getWidth()/2); 
       circle1.setY(getHeight()/2); 
      } 
      if(y1 - radius1 <= 0 || y1 + radius1 >= height) 
      { 
       circle1.turnY(); 

      } 

      if((x1 - radius1 <= p1X) || (x1 + radius1 >= p2X)) 
      { 
       circle1.turnX(); 
      } 

      circle1.move(); 
      repaint(); 
     } 

     public void GameOver() 
     { 
      playing = false; 
     } 



    } 

    enum DirectionP1 { 
      W(KeyEvent.VK_W), S(KeyEvent.VK_S); 

      private int key; 

      private DirectionP1(int key) { 
       this.key = key; 
      } 

      public int getKey() { 
       return key; 
      } 
     } 
    enum DirectionP2 { 
      UP(KeyEvent.VK_UP), DOWN(KeyEvent.VK_DOWN); 

      private int key; 

      private DirectionP2(int key) { 
       this.key = key; 
      } 

      public int getKey() { 
       return key; 
      } 
     } 

    class MyKeyAction extends AbstractAction { 
      private DirectionP1 direction; 

      public MyKeyAction(DirectionP1 direction) { 

       this.direction = direction; 
      } 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       switch (direction) { 
        case W: 
         p1Y -= 6; 
        break; 
        case S: 
         p1Y += 6; 
        break; 

        default: 
        break; 
        } 
      } 
     } 
    class MyKeyAction2 extends AbstractAction { 
      private DirectionP2 direction2; 

      public MyKeyAction2(DirectionP2 direction2) { 

       this.direction2 = direction2; 
      } 

      @Override 
      public void actionPerformed(ActionEvent e) { 

       switch (direction2) { 
        case UP: 
         p2Y -= 6; 
        break; 
        case DOWN: 
         p2Y += 6; 
        break; 

        default: 
        break; 
        } 
      } 
     } 
} 
+2

:

는 예를 들어,이 애니메이션 (즉, 당신까지)하지만이 기술은 동시 키 입력에 대한 응답을 수 있음을 보여줍니다 표시되지 않습니다? –

+1

당신은 말하지 않습니다 - 당신의 println 진술을 보시겠습니까? 그렇지 않다면 초점 문제가있을 가능성이 높습니다. 그러나 더 나은 해결책은 KeyListeners를 릴레이하는 것이 아니라 Swing Timer와 Key Bindings를 사용하는 것입니다. 이에 대한 예는 [이 링크] (http://stackoverflow.com/a/6887354/522444)를 참조하십시오. –

+0

if 문 앞에 'println()'이 있습니까? VK_UP 등은 정적 변수이며 클래스 이름을 사용하여 액세스합니다 :'KeyEvent.VK_UP'. +1 to HFOE KeyBinding은가는 길입니다. –

답변

5

포커스 문제가 있습니다. 당신은 인 JPanel에 모든 KeyListener를 추가하고 :하지만 JPanel에 초점을 맞춘 적이있다 그래서 모든 KeyListener이 작동하지 않습니다 :

public class Pong extends JPanel 
{ 
    //... 


    public Pong(Color backcolor, int Width, int Height) 
    { 
     // ... 

     timer = new javax.swing.Timer(5, new MoveListener()); 
     addKeyListener(new KeyWatcher()); 

을하지만 JPanel의 포커스를 얻을 수 없다, 그리고 구성 요소에 귀를 기울되는 경우 KeyListeners에만 작동 초점이 있습니다.

더 나은 해결 방법은 KeyListeners에서 릴레이하는 것이 아니라 Swing Timer와 Key Bindings를 사용하는 것입니다. 이에 대한 예는 this link을 참조하십시오.

: 또는 더 나은 링크 - Java KeyListener Not Registering Arrow Keys.

편집 2

아마도 더 나은 솔루션은 키 바인딩을 사용하지만 키 누름 또는 키 릴리스에 클래스의 필드를 설정하는 데 사용할 다음 해당 필드를 폴링 게임 루프로 스윙 타이머를 사용하는 것입니다. 당신은 질문이 ..Do

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.util.EnumMap; 

import javax.swing.*; 

public class NewArrowTest extends JPanel { 
    private static final String PRESSED = "pressed"; 
    private static final String RELEASED = "released"; 
    private static final int TIMER_DELAY = 20; 
    private EnumMap<Key, Boolean> keyMap = new EnumMap<NewArrowTest.Key, Boolean>(Key.class); 

    public NewArrowTest() { 
     keyMap.put(Key.W, false); 
     keyMap.put(Key.S, false); 
     keyMap.put(Key.UP, false); 
     keyMap.put(Key.DOWN, false); 

     // set up key binding 
     ActionMap actionMap = getActionMap(); 
     int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; 
     InputMap inputMap = getInputMap(condition); 

     for (Key key : Key.values()) { 
     KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke(key.getKeyCode(), 0, false); 
     KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke(key.getKeyCode(), 0, true); 

     inputMap.put(pressedKeyStroke, key.getText() + PRESSED); 
     inputMap.put(releasedKeyStroke, key.getText() + RELEASED); 
     actionMap.put(key.getText() + PRESSED, new MyArrowBinding(key, false)); 
     actionMap.put(key.getText() + RELEASED, new MyArrowBinding(key, true)); 
     } 

     // start polling timer or game loop 
     new Timer(TIMER_DELAY, new TimerListener()).start(); 
    } 

    private static void createAndShowGui() { 
     NewArrowTest mainPanel = new NewArrowTest(); 

     JFrame frame = new JFrame("NewArrowTest"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 

    private class TimerListener implements ActionListener { 
     public void actionPerformed(java.awt.event.ActionEvent e) { 
     for (Key key : keyMap.keySet()) { 
      System.out.printf("%6s %b%n", key, keyMap.get(key)); 
      // here we'd move things based on which key is true 
     } 
     System.out.println(); 

     }; 
    } 

    private class MyArrowBinding extends AbstractAction { 
     private Key key; 
     private boolean released; 

     public MyArrowBinding(Key key, boolean released) { 
     this.key = key; 
     this.released = released; 
     } 

     @Override 
     public void actionPerformed(ActionEvent aEvt) { 
     keyMap.put(key, !released); 
     } 
    } 

    enum Direction { 
     UP("Up"), DOWN("Down"), NEUTRAL("Neutral"); 
     private String text; 

     private Direction(String text) { 
     this.text = text; 
     } 
     public String getText() { 
     return text; 
     } 
    } 

    enum Key { 
     W("W", Direction.UP, KeyEvent.VK_W), S("S", Direction.DOWN, KeyEvent.VK_S), 
     UP("Up", Direction.UP, KeyEvent.VK_UP), DOWN("Down", Direction.DOWN, KeyEvent.VK_DOWN); 

     private String text; 
     private Direction direction; 
     private int keyCode; 

     private Key(String text, Direction direction, int keyCode) { 
     this.text = text; 
     this.direction = direction; 
     this.keyCode = keyCode; 
     } 

     public String getText() { 
     return text; 
     } 

     public Direction getDirection() { 
     return direction; 
     } 

     public int getKeyCode() { 
     return keyCode; 
     } 

    } 
} 
+0

내가 원했던 거의 정확하게 작업 한 것을 정말 고맙게 생각합니다. 이것은 내 새 코드 http : // pastebin입니다.com/Z0ArcUWz 내가 지금까지 겪었던 유일한 문제는 두 선수가 동시에 움직일 수없고 퐁 게임에서 문제가 될 수 있다는 것입니다. – user1181424

+0

@ user118 : 문제를 디버깅하기 위해 무엇을 했습니까? 그리고 링크가 아닌 질문에 코드를 게시하십시오. –

+0

내 질문을 업데이트하는 것이 좋습니다 – user1181424