2014-01-25 2 views
0

주말에 Pong의 클론을 만들려고했습니다. 처음 키 듣기가 효과가 있었지만 이후에는 듣지 못했습니다.KeyListener가 창에서 작업을 중단했습니다

import java.awt.BorderLayout; 
import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.image.BufferStrategy; 
import java.util.Random; 

import javax.swing.JFrame; 

public final class PingPong extends Canvas implements KeyListener { 
    private static final long serialVersionUID = 381061428448529952L; 

    public static final long FPS_LIMIT = 500; 

    public static final int BALL_SIZE = 10; 
    public static final int BALL_SPEED = 3; 

    public static final int BAT_LENGTH = 64; 
    public static final int BAT_WIDTH = 16; 
    public static final int BAT_POSITION_SHIFT_X = 16; 
    public static final int BAT_SPEED = 2; 

    private long fps_; 

    public void run() { 
     long last = System.currentTimeMillis(); 
     long now; 
     long delta = 0; 

     this.resetGame_(); 
     while(true) { 
      now = System.currentTimeMillis(); 
      delta = now - last; 

      if(delta >= 1000/FPS_LIMIT) { 
       this.process_(); 
       this.draw_(); 

       this.fps_ = 1000/delta; 

       last = now; 
      } 
     } 
    } 

    enum EDirection { LEFT, RIGHT } 

    int ballPosX; 
    int ballPosY; 
    EDirection ballDirection; 
    float ballRoll = 0; 

    int firstBatPosY; 
    int leftScore = 0; 

    int secondBatPosY; 
    int rightScore = 0; 

    private void process_() { 
     if(ballDirection == null) { 
      Random rnd = new Random(); 
      ballDirection = rnd.nextBoolean() == true ? EDirection.LEFT : EDirection.RIGHT; 
     } 

     /* 
     * Bats 
     */ 
     if(this.keyW) 
      firstBatPosY -= BAT_SPEED; 
     else if(this.keyS) 
      firstBatPosY += BAT_SPEED; 

     if(this.keyUp) 
      secondBatPosY -= BAT_SPEED; 
     else if(this.keyDown) 
      secondBatPosY += BAT_SPEED; 

     if(firstBatPosY < 0) 
      firstBatPosY = 0; 

     if(secondBatPosY < 0) 
      secondBatPosY = 0; 


     /* 
     * Ball 
     */ 
     switch(ballDirection) { 
     case LEFT: 
      ballPosX -= BALL_SPEED; 
      break; 
     case RIGHT: 
      ballPosX += BALL_SPEED; 
      break; 
     } 
     ballPosY += ballRoll; 

     if(ballPosX <= 0) { 
      ballDirection = EDirection.RIGHT; 
     } else { 
      switch(ballDirection) { 
      case LEFT: 
       if(ballPosX <= BAT_POSITION_SHIFT_X + BAT_WIDTH) { 
        if((ballPosY >= firstBatPosY && ballPosY <= firstBatPosY + BAT_LENGTH) 
         || (ballPosY + BALL_SIZE >= firstBatPosY && ballPosY + BALL_SIZE <= firstBatPosY + BAT_LENGTH)) { 
         ballDirection = EDirection.RIGHT; 
         break; 
        } else { 
         if(ballPosX <= 0) { 
          rightScore++; 
          this.resetGame_(); 
         } 
        } 
       } 
       break; 
      case RIGHT: 
       if(ballPosX >= super.getWidth() - BAT_POSITION_SHIFT_X - BAT_WIDTH) { 
        if((ballPosY >= secondBatPosY && ballPosY <= secondBatPosY + BAT_LENGTH) 
         || (ballPosY + BALL_SIZE >= secondBatPosY && ballPosY + BALL_SIZE <= secondBatPosY + BAT_LENGTH)) { 
         ballDirection = EDirection.LEFT; 
         break; 
        } else { 
         if(ballPosX >= super.getWidth()) { 
          leftScore++; 
          this.resetGame_(); 
         } 
        } 
       } 
       break; 
      } 
     } 
    } 

    private void draw_() { 
     BufferStrategy bs = super.getBufferStrategy(); 

     if(bs == null) { 
      super.createBufferStrategy(2); 
      super.requestFocus(); 
      return; 
     } 

     Graphics gfx = bs.getDrawGraphics(); 

     gfx.setColor(Color.BLACK); 
     gfx.fillRect(0, 0, super.getWidth(), super.getHeight()); 

     gfx.setColor(Color.GRAY); 
     gfx.fillRect(super.getWidth()/2 - 5, 10, 10, super.getHeight() - 20); 

     gfx.setColor(Color.WHITE); 
     gfx.fillRect(ballPosX, ballPosY, BALL_SIZE, BALL_SIZE); 
     gfx.fillRect(BAT_POSITION_SHIFT_X, firstBatPosY, BAT_WIDTH, BAT_LENGTH); 
     gfx.fillRect(super.getWidth() - BAT_POSITION_SHIFT_X - BAT_WIDTH, secondBatPosY, BAT_WIDTH, BAT_LENGTH); 

     gfx.setColor(Color.WHITE); 
     gfx.drawString(String.valueOf(this.fps_), 10, 20); 
     gfx.drawString(String.valueOf(leftScore), super.getWidth()/2/2, 64); 
     gfx.drawString(String.valueOf(rightScore), super.getWidth() - (super.getWidth()/2/2), 64); 

     gfx.dispose(); 
     bs.show(); 
    } 

    private void resetGame_() { 
     ballPosX = super.getWidth()/2 - BALL_SIZE/2; 
     ballPosY = super.getHeight()/2 - BALL_SIZE/2; 
     ballDirection = null; 
     ballRoll = 0; 

     firstBatPosY = super.getHeight()/2 - BAT_LENGTH/2; 

     secondBatPosY = super.getHeight()/2 - BAT_LENGTH/2; 
    } 

    boolean keyW, keyS, keyUp, keyDown; 

    @Override 
    public void keyPressed(KeyEvent _key) { 
     switch(_key.getKeyCode()) { 
     case KeyEvent.VK_W: keyW = true; break; 
     case KeyEvent.VK_S: keyS = true; break; 
     case KeyEvent.VK_UP: keyUp = true; break; 
     case KeyEvent.VK_DOWN: keyDown = true; break; 
     } 
    } 

    @Override 
    public void keyReleased(KeyEvent _key) { 
     switch(_key.getKeyCode()) { 
     case KeyEvent.VK_W: keyW = false; break; 
     case KeyEvent.VK_S: keyS = false; break; 
     case KeyEvent.VK_UP: keyUp = false; break; 
     case KeyEvent.VK_DOWN: keyDown = false; break; 
     } 
    } 

    @Override 
    public void keyTyped(KeyEvent _key) { 

    } 

    public static void main(String[] args) { 
     PingPong game = new PingPong(); 

     JFrame frame = new JFrame("DrMGC's Ping-Pong"); 
     frame.setSize(1024, 512); 
     frame.setLayout(new BorderLayout()); 
     frame.setFocusable(true); 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.addKeyListener(game); 
     frame.add(game, BorderLayout.CENTER); 

     frame.setVisible(true); 
     game.run(); 
    } 

} 

keyPressed() 메소드가 프레임 키를 통한 호출이 아닌 경우에도 리스닝은 작동하지 않습니다. 즉, 키의 코드에 문제가 없습니다.

+0

그럼 당신이 실제로'keyXxx' 방법에서 아무것도 _do_하지 않습니다에. 변수에 값을 할당하는 것만으로 아무런 영향을 미치지 않습니다. –

+0

이 'Swing'또는 'AWT'입니까? 이 두 가지 API를 함께 사용해야하는 이유는 무엇입니까? 'Swing' 또는'AWT'를 사용 합니다만,'AWT'에 속하는'Canvas' 대신에'JPanel/JComponent'를 그려야합니다. 또한, KeyListener (주로 포커스 관련 문제로 어려움을 겪고있는)를 통해 [KeyBindings] (http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html)를 사용하십시오. :-)이 작은 [ 예] (http://stackoverflow.com/a/18045209/1057230), [Motion using Keyboard] (http://tips4java.wordpress.com/2013/06/09/ 모션 - 키보드 사용하기), @camickr –

답변

0

은 합의 : 대신

frame.addKeyListner(game); 

쓰기

game.addKeyListner(game); 

또는 메소드 실행()

super.addKeyListener(this); 
관련 문제