当前位置: 首页 > 面试题库 >

使用KeyListener的Pong控件

栾英资
2023-03-14
问题内容

我在打乒乓球游戏时遇到了麻烦,这个项目只是从制作具有物理性的球开始,但后来我决定做更多的工作

我有那个球来回弹跳,除了键W和S之外,其他所有键都不控制玩家1,上下箭头键不控制玩家2

public void keyPressed(KeyEvent e){  
            if(e.getKeyCode() == e.VK_UP){  
                p2Y -= 3; 
                System.out.println("UP");
            }   
            if(e.getKeyCode() == e.VK_DOWN){  
                p2Y += 3;  
                System.out.println("Down");
            }  
            if(e.getKeyCode() == e.VK_W){  
                p1Y -= 3; 
                System.out.println("Up");
            }   
            if(e.getKeyCode() == e.VK_S){  
                p1Y += 3;  
                System.out.println("down");
            }
            repaint();
        }

它甚至不会显示系统打印消息

我不知道这只是问题的代码的这一部分还是其他地方

如果在其他位置,请访问此文件其余部分的链接
http://pastebin.com/TJbLBxL7

整个代码:

import javax.swing.*;


import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class Pong extends JPanel
{
    Circle circle1;
    javax.swing.Timer timer;
    ArrayList<Point> points = new ArrayList<Point>();
    int p1X=10, p1Y=320;
    int p2X=760, p2Y = 320;
    int y, y1;

    int p1Score, p2Score;

    boolean playing = true;

    public Pong(Color backcolor, int Width, int Height)
    {
        setBackground(backcolor);
        setPreferredSize(new Dimension(Width, Height));

        //first circle

        circle1 = new Circle(Width / 2, 360, 15, Color.white);
        circle1.setVelocity(4);
        circle1.setDirection(180);

        timer =  new javax.swing.Timer(5, new MoveListener());
        addKeyListener(new KeyWatcher());
        timer.start();
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        //first circle
        circle1.draw(g);
        circle1.fill(g);

        // Draw Players
        g.setColor(Color.red);
        g.fillRect(p1X, p1Y, 10, 75);
        g.setColor(Color.blue);
        g.fillRect(p2X, p2Y, 10, 75);

        //Draw Scores
        g.setColor(Color.white);
        g.drawString("Player 1's Score: " + p1Score, 10, 10);
        g.drawString("Player 2's Score: " + p2Score, getWidth() - 120, 10);
        repaint();

        if(!playing)
        {
            g.setColor(Color.red);
            g.drawString("GAMEOVER!!!", (getWidth() / 2) - 15, 10);
        }
        else
        {
        }
    }

    private class MoveListener extends MouseAdapter implements ActionListener
    {
        public void actionPerformed(ActionEvent arg0)
        {

            int x1 = circle1.getX();
            int y1 = circle1.getY();
            int width = getWidth();
            int height = getHeight();
            int radius1 = circle1.getRadius();

            //first circle

            if(x1 - radius1 <= 0)
            {
                p2Score++;
                circle1.setX(getWidth()/2);
                circle1.setY(getHeight()/2);
            }
            if(x1 + radius1 >= width)
            {
                p1Score++;

                circle1.setX(getWidth()/2);
                circle1.setY(getHeight()/2);
            }
            if(y1 - radius1 <= 0 || y1 + radius1 >= height )
            {
                circle1.turnY();

            }

            if((x1 - radius1 == p1X) || (x1 + radius1 == p2X))
            {
                circle1.turnX();
            }

            circle1.move();
            repaint();
        }

        public void GameOver()
        {
            playing = false;
        }

    }
    private class KeyWatcher implements KeyListener
    {

        @Override
        public void keyPressed(KeyEvent e){  
            if(e.getKeyCode() == e.VK_UP){  
                p2Y -= 3; 
                System.out.println("UP");
            }   
            if(e.getKeyCode() == e.VK_DOWN){  
                p2Y += 3;  
                System.out.println("Down");
            }  
            if(e.getKeyCode() == e.VK_W){  
                p1Y -= 3; 
                System.out.println("Up");
            }   
            if(e.getKeyCode() == e.VK_S){  
                p1Y += 3;  
                System.out.println("down");
            }
            repaint();
        }

        @Override
        public void keyReleased(KeyEvent e){  
             //if(e.getKeyCode() == e.VK_UP){  
            //        y1 = p2Y;  
             //       repaint();
             //   }   
             //   if(e.getKeyCode() == e.VK_DOWN){  
             //       y1 = p2Y;  
            //        repaint();
            //    } 
             //if(e.getKeyCode() == e.VK_W){  
             //       y = p1Y;  
            //        repaint();
            //    }   
            //    if(e.getKeyCode() == e.VK_S){  
            //        y = p1Y;  
            //        repaint();
             //   } 
        }

        @Override
        public void keyTyped(KeyEvent arg0) {
            // TODO Auto-generated method stub

        }


    }
}

我的新代码这个问题是每次只能控制一个玩家

它也有我愚蠢的尝试,通过制作2 MyKeyAction来解决它,但是它并没有改变它

package Bouncy;

import javax.swing.*;


import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class Pong extends JPanel
{
    Circle circle1;
    javax.swing.Timer timer;
    ArrayList<Point> points = new ArrayList<Point>();
    int p1X=10, p1Y=320;
    int p2X=760, p2Y = 320;
    int y, y1;

    int p1Score, p2Score;

    boolean playing = true;

    public Pong(Color backcolor, int Width, int Height)
    {
        setBackground(backcolor);
        setPreferredSize(new Dimension(Width, Height));

        //first circle

        circle1 = new Circle(Width / 2, 360, 15, Color.white);
        circle1.setVelocity(4);
        circle1.setDirection(180);

        timer =  new javax.swing.Timer(5, new MoveListener());
        setupKeyBinding();
        setupKeyBinding2();
        timer.start();
    }
    private void setupKeyBinding() {
          int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
          InputMap inMap = getInputMap(condition);
          ActionMap actMap = getActionMap();

          // this uses an enum of Direction that holds ints for the arrow keys
          for (DirectionP1 direction : DirectionP1.values()) {
             int key = direction.getKey();
             String name = direction.name();

             // add the key bindings for arrow key and shift-arrow key
             inMap.put(KeyStroke.getKeyStroke(key, 0), name);
             inMap.put(KeyStroke.getKeyStroke(key, InputEvent.SHIFT_DOWN_MASK), name);
             actMap.put(name, new MyKeyAction(direction));
          }
       }
    private void setupKeyBinding2() {
          int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
          InputMap inMap = getInputMap(condition);
          ActionMap actMap = getActionMap();

          // this uses an enum of Direction that holds ints for the arrow keys
          for (DirectionP2 direction : DirectionP2.values()) {
             int key = direction.getKey();
             String name = direction.name();

             // add the key bindings for arrow key and shift-arrow key
             inMap.put(KeyStroke.getKeyStroke(key, 0), name);
             inMap.put(KeyStroke.getKeyStroke(key, InputEvent.SHIFT_DOWN_MASK), name);
             actMap.put(name, new MyKeyAction2(direction));
          }
       }
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        //first circle
        circle1.draw(g);
        circle1.fill(g);

        // Draw Players
        g.setColor(Color.red);
        g.fillRect(p1X, p1Y, 10, 75);
        g.setColor(Color.blue);
        g.fillRect(p2X, p2Y, 10, 75);

        //Draw Scores
        g.setColor(Color.white);
        g.drawString("Player 1's Score: " + p1Score, 10, 10);
        g.drawString("Player 2's Score: " + p2Score, getWidth() - 120, 10);
        repaint();

        if(!playing)
        {
            g.setColor(Color.red);
            g.drawString("GAMEOVER!!!", (getWidth() / 2) - 15, 10);
        }
        else
        {
        }
    }

    private class MoveListener extends MouseAdapter implements ActionListener
    {
        public void actionPerformed(ActionEvent arg0)
        {

            int x1 = circle1.getX();
            int y1 = circle1.getY();
            int width = getWidth();
            int height = getHeight();
            int radius1 = circle1.getRadius();

            //first circle

            if(x1 - radius1 <= 0)
            {
                p2Score++;
                circle1.setX(getWidth()/2);
                circle1.setY(getHeight()/2);
            }
            if(x1 + radius1 >= width)
            {
                p1Score++;

                circle1.setX(getWidth()/2);
                circle1.setY(getHeight()/2);
            }
            if(y1 - radius1 <= 0 || y1 + radius1 >= height )
            {
                circle1.turnY();

            }

            if((x1 - radius1 <= p1X) || (x1 + radius1 >= p2X))
            {
                circle1.turnX();
            }

            circle1.move();
            repaint();
        }

        public void GameOver()
        {
            playing = false;
        }



    }

    enum DirectionP1 {
           W(KeyEvent.VK_W), S(KeyEvent.VK_S);

           private int key;

           private DirectionP1(int key) {
              this.key = key;
           }

           public int getKey() {
              return key;
           }
        }
    enum DirectionP2 {
           UP(KeyEvent.VK_UP), DOWN(KeyEvent.VK_DOWN);

           private int key;

           private DirectionP2(int key) {
              this.key = key;
           }

           public int getKey() {
              return key;
           }
        }

    class MyKeyAction extends AbstractAction {
           private DirectionP1 direction;

           public MyKeyAction(DirectionP1 direction) {

              this.direction = direction;
           }

           @Override
           public void actionPerformed(ActionEvent e) {
               switch (direction) {
                  case W:
                        p1Y -= 6; 
                     break;
                  case S:
                        p1Y += 6; 
                     break;

                  default:
                     break;
                  }
           }
        }
    class MyKeyAction2 extends AbstractAction {
           private DirectionP2 direction2;

           public MyKeyAction2(DirectionP2 direction2) {

              this.direction2 = direction2;
           }

           @Override
           public void actionPerformed(ActionEvent e) {

               switch (direction2) {
                  case UP:
                        p2Y -= 6; 
                     break;
                  case DOWN:
                        p2Y += 6; 
                     break;

                  default:
                     break;
                  }
           }
        }
}

问题答案:

您有一个重点问题。您正在向JPanel添加KeyListener:但是JPanel永远不会具有焦点,因此KeyListener将无法工作:

public class Pong extends JPanel
{
    //...


    public Pong(Color backcolor, int Width, int Height)
    {
        // ...

        timer =  new javax.swing.Timer(5, new MoveListener());
        addKeyListener(new KeyWatcher());

但是JPanel永远不会获得焦点,并且KeyListeners仅在被侦听的组件具有焦点时才起作用。

更好的解决方案不是中继KeyListener,而是使用Swing Timer和Key
Bindings。请参阅[此链接](http://codingdict.com/questions/2408以获取此示例。

编辑 :或者甚至更好的链接-JavaKeyListener不注册箭头键。

编辑2
也许更好的解决方案是使用按键绑定,但是使用它们在按键或释放按键时设置类的字段,然后使用Swing Timer作为游戏循环来轮询这些字段。

例如,这不会显示动画(由您决定),但是表明此技术将允许对同时按下的键做出响应:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.EnumMap;

import javax.swing.*;

public class NewArrowTest extends JPanel {
   private static final String PRESSED = "pressed";
   private static final String RELEASED = "released";
   private static final int TIMER_DELAY = 20;
   private EnumMap<Key, Boolean> keyMap = new EnumMap<NewArrowTest.Key, Boolean>(Key.class);

   public NewArrowTest() {
      keyMap.put(Key.W, false);
      keyMap.put(Key.S, false);
      keyMap.put(Key.UP, false);
      keyMap.put(Key.DOWN, false);

      // set up key binding
      ActionMap actionMap = getActionMap();
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);

      for (Key key : Key.values()) {
         KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke(key.getKeyCode(), 0, false);
         KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke(key.getKeyCode(), 0, true);

         inputMap.put(pressedKeyStroke, key.getText() + PRESSED);
         inputMap.put(releasedKeyStroke, key.getText() + RELEASED);
         actionMap.put(key.getText() + PRESSED, new MyArrowBinding(key, false));
         actionMap.put(key.getText() + RELEASED, new MyArrowBinding(key, true));
      }

      // start polling timer or game loop
      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   private static void createAndShowGui() {
      NewArrowTest mainPanel = new NewArrowTest();

      JFrame frame = new JFrame("NewArrowTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }

   private class TimerListener implements ActionListener {
      public void actionPerformed(java.awt.event.ActionEvent e) {
         for (Key key : keyMap.keySet()) {
            System.out.printf("%6s %b%n", key, keyMap.get(key));
            // here we'd move things based on which key is true
         }
         System.out.println();

      };
   }

   private class MyArrowBinding extends AbstractAction {
      private Key key;
      private boolean released;

      public MyArrowBinding(Key key, boolean released) {
         this.key = key;
         this.released = released;
      }

      @Override
      public void actionPerformed(ActionEvent aEvt) {
         keyMap.put(key, !released);
      }
   }

   enum Direction {
      UP("Up"), DOWN("Down"), NEUTRAL("Neutral");
      private String text;

      private Direction(String text) {
         this.text = text;
      }
      public String getText() {
         return text;
      }
   }

   enum Key {
      W("W", Direction.UP, KeyEvent.VK_W), S("S", Direction.DOWN, KeyEvent.VK_S), 
      UP("Up", Direction.UP, KeyEvent.VK_UP), DOWN("Down", Direction.DOWN, KeyEvent.VK_DOWN);

      private String text;
      private Direction direction;
      private int keyCode;

      private Key(String text, Direction direction, int keyCode) {
         this.text = text;
         this.direction = direction;
         this.keyCode = keyCode;
      }

      public String getText() {
         return text;
      }

      public Direction getDirection() {
         return direction;
      }

      public int getKeyCode() {
         return keyCode;
      }

   }
}


 类似资料:
  • 问题内容: 我目前正在尝试在程序中实现一个键侦听器,以便当我按下箭头键时它会执行一个操作,程序中的对象向左或向右移动。 这是我程序中的移动方法 我想知道程序应该如何读入(KeyEvent)e。我真的不能输入箭头键。 请帮忙! 编辑:我还需要知道我需要添加到代码中的内容,以便我的程序在继续使用另一种方法之前要等待大约700毫秒的时间才能进行键输入 问题答案: http://docs.oracle.c

  • 问题内容: 我正在计划在Windows下运行的Java程序的计划制定工作,该程序可以在背景的不同键runnig上映射不同的“宏”。问题是- 如何使Java在应用程序未聚焦时监听按键。 我发现很多观点认为这是不可能的。但是我也发现Stefano在SO上写的这本书。这种解决方案对我来说还不够好,至少没有一个重要的信息。如果没有按下该键,该函数将返回一个值。按键后,它会返回不同的值…如果函数在按键事件后

  • Pong! 是一个完全用 JavaScript 实现的 pong 游戏,基于 Socket.io 和 Canvas 技术实现。 特性: 服务器 socket.io 集成 支持两个在线玩家 响应式和自适应 UI 支持移动设备 支持手势操作 tokenized lobby entry page

  • 一个在设置了Keylistener或Keyadapter类并重写了keyPressed之后,另两个在程序中如何获得键盘响应呢?例如,假设我已经设置了Keyadapter类: 我将如何从那里开始,使它能够实际检测到它,并在我按w时显示字符串?没有任何方法,我可以在main方法中调用,使它开始检查,是吗?如果没有,JVM如何知道开始检查main中是否没有方法告诉它? 谢谢你抽出时间。

  • ms (数值型) 自ping到pong经历的毫秒数 socket.on('pong', (timeout) => { // ... });

  • ms (数值型) 自ping至pong经过的毫秒数 当接受到服务器端的pong时触发。