2015-10-16 2 views
-1
public class game extends Applet implements KeyListener { 
int movex = 10; 
int movey = 10; 
int x = 50, y = 50; 
JTextArea typingArea; 
Random rand = new Random(); 
public void paint(Graphics page){ 
     typingArea = new JTextArea(); 
     typingArea.addKeyListener(this); 

     //Drawing borders w/ Random colors 
     page.setColor(new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat())); 
     page.drawRect(0,0,200,200); 

     //delay 
     try { 
      Thread.sleep(1); 
     } catch (InterruptedException e) { 
     } 

     //Draws square   
     page.drawRect(x, y, 10, 10); 
     x+=movex; 
     y+=movey; 

     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
     } 
     Dimension d = getSize(); 
     page.setColor(Color.WHITE); 
     page.fillRect(0, 0, d.width, d.height); 
     paint(page); 
    } 

public void keyPressed(KeyEvent e) { 
    int keyCode = e.getKeyCode(); 
    System.out.println("Key is pressed"); 
    switch(keyCode) { 
     case KeyEvent.VK_UP: 
      movex = 0; 
      movey = 10; 
      break; 
     case KeyEvent.VK_DOWN: 
      movex = 0; 
      movey = -10; 
      break; 
     case KeyEvent.VK_LEFT: 
      movex = -10; 
      movey = 0; 
      break; 
     case KeyEvent.VK_RIGHT : 
      movex = 10; 
      movey = 0; 
      break; 
    } 
} 
@Override 
public void keyReleased(KeyEvent arg0) { 

} 
@Override 
public void keyTyped(KeyEvent e) { 

}} 

В настоящее время я делаю короткую змею как практику программирования, поскольку я относительно новичок в Java, но не в программировании. Используя апплет, я рисую квадрат и перемещаю его, увеличивая координаты x, y, а затем вызывая метод рисования рекурсивно. Я использовал неправильный объект (JTextArea) или есть проблема с моими методами. Пожалуйста, ответьте быстро, спасибо.Почему этот keyListener не работает?

+0

«Основная причина, по которой вы« KeyListener »не работает, никогда не регистрируется ничем, отображаемым на экране, поэтому никогда не может иметь фокус клавиатуры. Вы никогда не должны использовать «KeyListener» с текстовыми компонентами, это просто совершенно неуместно. – MadProgrammer

+0

Начну с взгляда на [Живопись в AWT и Swing] (http://www.oracle.com/technetwork/java/painting-140037.html) и [Выполнение пользовательской живописи] (http: // docs .oracle.com/javase/tutorial/uiswing/painting /), чтобы понять, как работает живопись. Затем я отбросил API апплета/AWT и использовал либо [Swing] (http://docs.oracle.com/javase/tutorial/uiswing/), либо JavaFX, вам станет лучше, общая поддержка. Я также посмотрю на [Как использовать таймеры Swing] (http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) для некоторых представлений о том, как создать цикл игры – MadProgrammer

+0

И вы можете просто взглянуть на этот [пример] (http://stackoverflow.com/questions/31508913/snakegame-how-to-make-the-tail-follow-the-head/31509204#31509204) для некоторых идей , Если вы собираетесь использовать Swing, я бы рекомендовал взглянуть на [Как использовать привязки клавиш] (http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html) и забыть о 'KeyListener' – MadProgrammer

ответ

0

Давайте посмотрим, сможем ли мы сломать это вниз немного ...

В вас paint методе вы создаете новый экземпляр JTextArea и добавить себя в качестве KeyListener.

public void paint(Graphics page) { 
    typingArea = new JTextArea(); 
    typingArea.addKeyListener(this); 

Три проблемы здесь ...

  1. Вы действительно не должны создавать новые компоненты в методе paint. Метод paint будет вызываться, когда когда-либо компонент должен быть перекрашен (и может быть вызван часто в быстрой последовательности), а paint должен только рисовать текущее состояние компонента, никогда не изменять его
  2. Вы действительно не должны использовать KeyListener с текстовым компонентом
  3. вы никогда не добавить JTextArea к отображаемой компоненте, то есть он не может получить фокус клавиатуры и, следовательно, никогда не вызывает KeyEvent s

Тогда вы называете ...

//delay 
    try { 
     Thread.sleep(1); 
    } catch (InterruptedException e) { 
    } 
    //... 
    try { 
     Thread.sleep(100); 
    } catch (InterruptedException e) { 
    } 

в вашем методе paint. Это очень плохая идея, картина должна происходить как можно быстрее, так как пока метод paint не существует, то содержимое Graphics контекста может не быть окрашены в экран

И, наконец, вы называете ...

paint(page); 
} 

Это плохая идея, так как вы никогда не выйдете из метода paint после его вызова (см. Предыдущий комментарий), и вы получите StackOverflowException.

AWT вызовет ваш метод paint, когда он захочет перекрасить компонент. Вы можете запросить обновление, вызвав repaint, но вы должны знать, что картина будет возникать, когда менеджер repaint решит, что что-то нужно обновить, поэтому это может не произойти немедленно.

  • Я хотел бы взглянуть на Painting in AWT and Swing и Performing Custom Painting, чтобы понять, как работает живопись.
  • Я бы затем отбросил API апплета/AWT и использовал либо Swing, либо JavaFX, вы получите лучшую поддержку.
  • Если вы хотите использовать качание, я бы взглянуть на How to use Swing Timers для некоторых идей о том, как вы могли бы генерировать цикл игр
  • Если вы собираетесь использовать качание, я рекомендовал бы иметь взгляд на How to Use Key Bindings и забыть о KeyListener
  • И вы можете просто взглянуть на это example для некоторых идей.
Смежные вопросы