2015-10-16 205 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相对陌生,但对编程不熟悉。使用Applet我绘制了一个正方形,并通过递增x,y坐标来移动它,然后递归地调用paint方法。我使用了错误的对象(JTextArea)还是使用了我的方法?请快速回答,谢谢。为什么这个keyListener不起作用?

+0

“KeyListener”不起作用的“主要”原因是它从未实际注册过屏幕上显示的任何内容,因此永远无法获得键盘焦点。你不应该使用带有文本组件的'KeyListener',它完全不合适。 – MadProgrammer

+0

我首先看看[在AWT和Swing中绘画](http://www.oracle.com/technetwork/java/painting-140037.html)和[Performing Custom Painting](http:// docs .oracle.com/javase/tutorial/uiswing/painting /)了解绘画的工作原理。然后,我将删除applet/AWT API并使用[Swing](http://docs.oracle.com/javase/tutorial/uiswing/)或JavaFX,您将获得更好的一般支持。我还会看看[如何使用Swing Timers](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小号

然后调用...

//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来请求更新,但是您应该知道,绘画将在重绘管理器决定需要更新的内容时发生,因此可能不会立即发生。