2014-01-25 2 views
0

В выходные я попытался создать клон Понга. Слушание в первый раз было работоспособным, но после этого не было.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

Ну вы на самом деле не _do_ ничего в 'keyXxx' методами. _Only_ присвоение значения переменной абсолютно не влияет. –

+0

Является ли это 'Swing' или' AWT'? В чем же необходимость сочетать оба эти API вместе? Используйте «Swing» или «AWT», но не смешивайте их как с рисунком «JPanel/JComponent», а с «Canvas» (который принадлежит «AWT'). Кроме того, попробуйте использовать [KeyBindings] (http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html) над 'KeyListeners (которые в основном страдают от проблем, связанных с фокусом)' :-) Этот небольшой [ пример] (http://stackoverflow.com/a/18045209/1057230), может дать эту идею, больше в [Motion using Keyboard] (http://tips4java.wordpress.com/2013/06/09/motion- с помощью клавиатуры /), by @camickr –

ответ

0

Согласовано: Вместо

frame.addKeyListner(game); 

Написать

game.addKeyListner(game); 

или в методе Run()

super.addKeyListener(this); 
Смежные вопросы