2012-12-07 56 views
1

这是我制作的乒乓球游戏,但唯一不起作用的是桨板移动。我不知道如何使键盘与程序一起工作。下面是游戏的主要代码:为什么keyListener不工作?

//Project: A program where you play the game pong 

//This module defines the properties of the user interface 

import java.awt.*; 
import javax.swing.*; 
import java.awt.event.*; 


public class pongframe extends JFrame 
{ 
    private JLabel playerlefttitle; 
    private JLabel playerrighttitle; 
    private JLabel speedtitle; 
    private JTextField speedfield; 
    private JTextField playerleftscorefield; 
    private JTextField playerrightscorefield; 
    private JButton newgame; 
    private JButton gobutton; 
    private JButton pausebutton; 
    private JButton quitgame; 
    private Timer systemclock; 
    private Timer paddleclock; 
    private String speedstring; 
    private int speed; 
    private int leng = 10; 
    private int delayinterval; 
    private float millisecondpersecond = 1000.0f; 
    private boolean win = false; 
    private int playerleftscore=0; 
    private int playerrightscore=0; 
    private boolean rightup = false; 
    private boolean rightdown = false; 
    private boolean leftup = false; 
    private boolean leftdown = false; 
    private boolean barhit = true; 
    private double direction=0; 
    private pongoperations graphicalpanel; 
    private Clockhandlerclass clockhandler; 
    private PaddleClockHandlerClass paddleclockhandler; 
    private PaddleHandlerClass paddlehandler; 

    public pongframe() 
    { 
     super("Pong"); 
     JPanel panel1 = new JPanel(new GridBagLayout()); 
     GridBagConstraints c = new GridBagConstraints(); 

     graphicalpanel = new pongoperations(); 
     graphicalpanel.setBackground(Color.GREEN); 
     add(graphicalpanel, BorderLayout.CENTER); 

     add(panel1, BorderLayout.SOUTH); 
     c.insets = new Insets(0,0,10,10); 
     newgame = new JButton("New"); 
     c.gridx = 0; 
     c.gridy = 1; 
     panel1.add(newgame, c); 
     speedtitle = new JLabel("Speed"); 
     c.gridx = 1; 
     c.gridy = 0; 
     panel1.add(speedtitle, c); 
     speedfield = new JTextField(3); 
     c.gridx = 1; 
     c.gridy = 1; 
     panel1.add(speedfield, c); 
     quitgame = new JButton("Quit"); 
     c.gridx = 2; 
     c.gridy = 1; 
     panel1.add(quitgame, c); 
     playerlefttitle = new JLabel("Player Left"); 
     c.gridx = 0; 
     c.gridy = 3; 
     panel1.add(playerlefttitle, c); 
     playerrighttitle = new JLabel("Player Right"); 
     c.gridx = 3; 
     c.gridy = 3; 
     panel1.add(playerrighttitle, c); 
     playerleftscorefield = new JTextField(2); 
     playerleftscorefield.setEditable(false); 
     c.gridx = 0; 
     c.gridy = 4; 
     panel1.add(playerleftscorefield, c); 
     gobutton = new JButton("Go"); 
     c.gridx = 1; 
     c.gridy = 4; 
     panel1.add(gobutton, c); 
     pausebutton = new JButton("Pause"); 
     c.gridx = 2; 
     c.gridy = 4; 
     panel1.add(pausebutton, c); 
     playerrightscorefield = new JTextField(2); 
     playerrightscorefield.setEditable(false); 
     c.gridx = 3; 
     c.gridy = 4; 
     panel1.add(playerrightscorefield, c); 
     buttonhandler myhandler = new buttonhandler(); 
     newgame.addActionListener(myhandler); 
     gobutton.addActionListener(myhandler); 
     pausebutton.addActionListener(myhandler); 
     quitgame.addActionListener(myhandler); 
     clockhandler = new Clockhandlerclass(); 
     paddleclockhandler = new PaddleClockHandlerClass(); 
     paddlehandler = new PaddleHandlerClass(); 
    } 
    private class buttonhandler implements ActionListener 
    { 
     public void actionPerformed(ActionEvent event) 
     { 
      graphicalpanel.reset(); 
      if(event.getSource() == newgame) 
      { 
       speedfield.setText(""); 
       playerleftscore = 0; 
       playerrightscore = 0; 
       playerleftscorefield.setText("0"); 
       playerrightscorefield.setText("0"); 
       graphicalpanel.reset(); 
       graphicalpanel.repaint(); 
       gobutton.setEnabled(true); 
       speedfield.setEditable(true); 
       newgame.setEnabled(false); 
      } 
      else if(event.getSource() == gobutton) 
      { 
       speedstring = speedfield.getText(); 
       leng = speedstring.length(); 
       if(leng == 0) 
        speed = 0; 
       else 
       { 
        speed = Integer.parseInt(speedstring); 
        gobutton.setEnabled(false); 
        speedfield.setEditable(false); 
       } 
       newgame.setEnabled(false); 
       delayinterval = (int)Math.floor(millisecondpersecond/speed + 0.5f); 
       systemclock = new Timer(delayinterval, clockhandler); 
       systemclock.start(); 
       paddleclock = new Timer(delayinterval, paddleclockhandler); 
       paddleclock.start(); 
      } 
      else if(event.getSource() == pausebutton) 
      { 
       gobutton.setEnabled(true); 
       newgame.setEnabled(true); 
       systemclock.stop(); 
      } 
      else if(event.getSource() == quitgame) 
      { 
       System.exit(0); 
      } 
      else 
       System.out.println("Unkown error"); 
     } 
    } 
    private class Clockhandlerclass implements ActionListener 
    { 
     public void actionPerformed(ActionEvent event) 
     { 
      if(event.getSource() == systemclock) 
      { 
       graphicalpanel.grabFocus(); 
       graphicalpanel.moveball(speed,delayinterval, direction, barhit); 
       direction = graphicalpanel.changedirection(direction); 

       if(win == false) 
       { 
        barhit = graphicalpanel.barhits(barhit); 
        graphicalpanel.repaint(); 
        win = graphicalpanel.winner(); 
        playerleftscore = graphicalpanel.playerleftwin(playerleftscore); 
        playerrightscore = graphicalpanel.playerrightwin(playerrightscore); 
        playerleftscorefield.setText(Integer.toString(playerleftscore)); 
        playerrightscorefield.setText(Integer.toString(playerrightscore)); 
       } 
       else if(win == true) 
       { 
        graphicalpanel.reset(); 
        win = false; 
        systemclock.restart(); 
        if(playerleftscore == 10) 
        { 
         newgame.setEnabled(true); 
         systemclock.stop(); 
        } 
        else if(playerrightscore == 10) 
        { 
         newgame.setEnabled(true); 
         systemclock.stop(); 
        } 
        graphicalpanel.repaint(); 
       } 
      } 
      else 
       System.out.printf("%s\n", "There is a bug in the clock."); 
     } 
    } 
    private class PaddleClockHandlerClass implements ActionListener 
    { 
     public void actionPerformed(ActionEvent event) 
     { 
      if(event.getSource() == paddleclock) 
      { 
       graphicalpanel.moveplayer1(rightup, rightdown); 
       graphicalpanel.moveplayer2(leftup, leftdown); 
       graphicalpanel.repaint(); 
      } 
     } 
    } 
    private class PaddleHandlerClass implements KeyListener 
    { 
     public void keyTyped(KeyEvent event) 
     { 
     } 
     public void keyPressed(KeyEvent event) 
     { 
      if(event.getKeyCode() == KeyEvent.VK_UP) 
      { 
       rightup = true; 
       System.out.println("Up"); 
      } 
      else if(event.getKeyCode() == KeyEvent.VK_DOWN) 
       rightdown = true; 
      if(event.getKeyCode() == KeyEvent.VK_W) 
       leftup = true; 
      else if(event.getKeyCode() == KeyEvent.VK_S) 
       leftdown = true; 
     } 
     public void keyReleased(KeyEvent event) 
     { 
      if(event.getKeyCode() == KeyEvent.VK_UP) 
       rightup = false; 
      else if(event.getKeyCode() == KeyEvent.VK_DOWN) 
       rightdown = false; 
      if(event.getKeyCode() == KeyEvent.VK_W) 
       leftup = false; 
      else if(event.getKeyCode() == KeyEvent.VK_S) 
       leftdown = false; 
     } 
    } 
} 

这接下来的代码位是我使用的游戏功能:

//Project: A program where you play the game pong 

//This module contains the graphics and algorithms used by this project. 

import java.awt.Graphics; 
import javax.swing.JPanel; 
import java.awt.Color; 

public class pongoperations extends JPanel 
{ 
    int widthofgraphicalarea; 
    int heightofgraphicalarea; 
    final int ballradius = 8; 
    int ballxcoordinate; 
    double ballycoordinate; 
    int paddle1xcoordinate; 
    int paddle1ycoordinate; 
    int paddle2xcoordinate; 
    int paddle2ycoordinate; 

    public void paintComponent(Graphics graphicarea) 
    {//function to paint the area 
     super.paintComponent(graphicarea); 
     this.setBackground(Color.GREEN); 
     widthofgraphicalarea = getWidth(); 
     heightofgraphicalarea = getHeight(); 
     //create paddle 1 
     graphicarea.setColor(Color.BLUE); 
     graphicarea.fillRect(paddle1xcoordinate, paddle1ycoordinate, 10, 50); 
     //create paddle 2 
     graphicarea.setColor(Color.RED); 
     graphicarea.fillRect(paddle2xcoordinate, paddle2ycoordinate, 10, 50); 
     //Give the ball a white color 
     graphicarea.setColor(Color.WHITE); 
     //The 3rd and 4th parameters below represent the diameter of the ball. 
     graphicarea.fillOval(ballxcoordinate,(int)ballycoordinate,2*ballradius,2*ballradius); 
    }//End of method paintComponent 
    public void moveplayer1(boolean rightup, boolean rightdown) 
    { 
     if(rightup == true) 
     paddle1ycoordinate -= 5; 
     else if(rightdown == true) 
     paddle1ycoordinate += 5; 
     positionPlayer1(paddle1xcoordinate, paddle1ycoordinate); 
    } 
    public void moveplayer2(boolean leftup, boolean leftdown) 
    { 
     if(leftup == true) 
     paddle2ycoordinate -= 5; 
     else if(leftdown == true) 
     paddle2ycoordinate += 5; 
     positionPlayer2(paddle2xcoordinate, paddle2ycoordinate); 
    } 
    public void positionPlayer1(int x, int y) 
    { 
     this.paddle1xcoordinate = x; 
     this.paddle1ycoordinate = y; 
     repaint(); 
    } 
    public void positionPlayer2(int x, int y) 
    { 
     this.paddle2xcoordinate = x; 
     this.paddle2ycoordinate = y; 
     repaint(); 
    } 
    public void moveball(int speed, int delayinterval, double direction, boolean barhit) 
    { 
     if(barhit == true) 
      ballxcoordinate+=1; 
     else if(barhit == false) 
      ballxcoordinate-=1; 
     if(direction > 0) 
      ballycoordinate = ballycoordinate + (double)Math.sin(Math.toRadians(direction)); 
     else if(direction < 0) 
      ballycoordinate = ballycoordinate + (double)Math.sin(Math.toRadians(direction)); 
    } 
    public boolean barhits(boolean barhit) 
    { 
     if(ballxcoordinate == paddle1xcoordinate+10 && (ballycoordinate >= paddle1ycoordinate && ballycoordinate <= paddle1ycoordinate+50)) 
      barhit = true; 
     else if(ballxcoordinate+2*ballradius == paddle2xcoordinate && (ballycoordinate+2*ballradius >= paddle2ycoordinate && ballycoordinate+2*ballradius <= paddle2ycoordinate+50)) 
      barhit = false; 
     return barhit; 
    } 
    public boolean winner() 
    { 
     if(ballxcoordinate+2*ballradius >= widthofgraphicalarea) 
      return true; 
     else if(ballxcoordinate+2*ballradius <= 16) 
      return true; 

     return false; 
    } 
    public int playerleftwin(int playerleftscore) 
    { 
     if(ballxcoordinate+2*ballradius >= widthofgraphicalarea) 
      playerleftscore+=1; 

     return playerleftscore; 
    } 
    public int playerrightwin(int playerrightscore) 
    { 
     if(ballxcoordinate+2*ballradius <= 16) 
      playerrightscore+=1; 

     return playerrightscore; 
    } 
    public double changedirection(double direction) 
    {//function to change the direction of the ball to bounce of walls 
     if((int)ballycoordinate+2*ballradius >= heightofgraphicalarea || (int)ballycoordinate+2*ballradius < 16) 
      direction = -direction; 
     return direction; 
    } 
    public void reset() 
    {//reset the ball at middle of left side 
     ballxcoordinate = widthofgraphicalarea/2 - ballradius; 
     ballycoordinate = heightofgraphicalarea/2 - ballradius; 
     paddle1xcoordinate = 10; 
     paddle1ycoordinate = heightofgraphicalarea/2-25; 
     paddle2xcoordinate = widthofgraphicalarea-20; 
     paddle2ycoordinate = heightofgraphicalarea/2-25; 
    } 
} 

请人帮忙。提前致谢。

如果您可以提供帮助,另一个问题是一旦完成,我该如何切换到小程序窗体?

+0

有你试过'paddlehandler.addKeyListener(this);'? – jonhopkins

+0

错误消息说:pongframe.java:111:错误:找不到符号 paddlehandler.addkeyListener(this); ^ 符号:方法addkeyListener(pongframe) 位置:pongframe.PaddleHandlerClass类型的变量paddlehandler – GolfinGamer

+0

好你想让我把它放在哪里? – GolfinGamer

回答

1
  • 请勿使用KeyListener Swing组件使用KeyBindings

  • 不要延长JFrame类不必要

  • Swing组件应Event Dispatch Thread

  • 要设置应用程序的大小来创建(不setSize(..)通话JFrame)添加组件按钮等时(使用appropiate布局管理你在做什么),并在paintComponent覆盖JPanelgetPreferredSize(),并在JFrameJFrame之前返回一个适合所有图纸的适当大小,然后将其设置为可见

  • 不要忘记调用setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JFrame所以当X按下事件指派线程初始线程会退出,或应用程序将留在后台运行。

但后paddlehandler = new PaddleHandlerClass();附加解决您的问题:

graphicalpanel.addKeyListener(paddlehandler); 

的问题是,你永远不添加KeyListener到任何组件事件监听

正确的解决办法是KeyBindings这将改变你的PaddleHandlerClass这样的:

private class PaddleHandlerClass { 

    public PaddleHandlerClass(JComponent jc) { 

     jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "up"); 
     jc.getActionMap().put("up", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       rightup = true; 
       System.out.println("Up"); 
      } 
     }); 
     jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released UP"), "rel up"); 
     jc.getActionMap().put("rel up", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       rightup = false; 
      } 
     }); 
    } 

} 

不是简单地创建paddleHandler和传递的JPanel情况下,我们希望得到哪些键:

paddlehandler = new PaddleHandlerClass(graphicalpanel); 
+0

'graphicalpanel.addKeyListener(paddlehandler);'作品。谢谢。 – GolfinGamer

+0

@GolfinGamer请参阅更新 –

+2

@GolfinGamer KeyListener的焦点丢失问题,他们只有当他们注册的组件有焦点时才会作出响应。正如大卫的建议,你最好使用键绑定,因为它们能够响应更广泛的焦点标准(例如,当窗口具有焦点时) – MadProgrammer