【问题标题】:Key Listener not working when being pressed按下时键侦听器不起作用
【发布时间】:2012-10-18 07:30:10
【问题描述】:

试图让我的代码在屏幕上移动玩家(飞船)时遇到了很多麻烦。我可以让行星在屏幕和玩家飞船上绘制,但我不知道如何实现 keyListener 以至少打印出一些东西。提前感谢您的所有帮助!

    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import java.awt.Canvas;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.Toolkit;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;


    public class MapPanel extends JPanel {
public static final int WIDTH = 25;
 public static final int HEIGHT = 20;
 int zone = 0;
 private int xValue;
 private int yValue;
 private Color color;
 public Planet[][] planetGrid = new Planet[WIDTH][HEIGHT];
 static Player currPlayer = new Player("h");
 static Universe universe = new Universe(currPlayer);

 /**
 * Create the panel.
 */
 public MapPanel(Universe univ, Player p) {
    this.universe = univ;
    currPlayer = p;
    int i = 0;
    this.setSize(new Dimension(450,450));
    setVisible( true );
    //this.addKeyListener(new KeyController());
     KeyController kc = new KeyController();
     this.addKeyListener(kc);
    repaint();


 }


 /**
  * Draw method to draw the playing field
  * @param g Graphics object
  * @param tileDimension dimension of the tile
  */
 public void draw(Graphics g)
 {
 universe.draw(g);

    //    KeyController key = new KeyController();
 }
 public void paintComponent(Graphics g) {
     super.paintComponent(g);
     draw(g);
 }
 public static void main(String[] args)
 {
     MapPanel mp = new MapPanel(universe, currPlayer);
     JFrame f = new JFrame();
     f.add(mp);
     f.setSize(new Dimension(450,450));
     f.setVisible(true);
     f.setFocusable(true);


 }
 private class KeyController implements KeyListener {
     public KeyController()
     {
         System.out.println("ghgh");
         setFocusable(true);
        // addKeyListener(this);
     }
        @Override
        public void keyPressed(final KeyEvent key) {
            System.out.println("fgfgf");
            if (currPlayer != null) {

                int oldX = currPlayer.getPosition().x;
                int oldY = currPlayer.getPosition().y;

                switch (key.getKeyCode()) {
                    case KeyEvent.VK_RIGHT:
                      currPlayer.setPosition(new Point(oldX+1, oldY)); //move right
                      System.out.println("RIGHT");
                        break;
                    case KeyEvent.VK_LEFT:
                          currPlayer.setPosition(new Point(oldX-1, oldY));         //move left
                        break;
                    case KeyEvent.VK_DOWN:
                          currPlayer.setPosition(new Point(oldX, oldY+1));         //move down
                        break;
                    case KeyEvent.VK_UP:
                          currPlayer.setPosition(new Point(oldX, oldY-1));         //move up
                        break;
                }

            }
            repaint();
        }
        @Override
        public void keyReleased(KeyEvent e) {
            System.out.println("ggg");
        }
        @Override
        public void keyTyped(KeyEvent e) {
            System.out.println("typeeeddd");
        }
    }





    }

【问题讨论】:

    标签: java swing graphics keylistener


    【解决方案1】:

    KeyListener 不是实现您的结果的最合适的方法。

    最好使用key bindings API。

    除了简化代码之外,它还可以让您更好地控制何时触发按键。

    【讨论】:

      【解决方案2】:

      在这里我设计了一个与您类似的应用程序,您可以在其中使用箭头键,然后在移动的船上投掷炸弹(这是我几年前的项目:)),设计一个运行的主要方法,希望这会帮助:

      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.*;
      
      
      /**
      * This panel implements a simple arcade game in which the user tries to blow
      * up a "submarine" (a black oval) by dropping "depth charges" (a red disk) from
      * a "boat" (a blue roundrect).  The user moves the boat with the left- and
      * right-arrow keys and drops the depth charge with the down-arrow key.
      * The sub moves left and right erratically along the bottom of the panel.
      */
      public class SubKillerPanel extends JPanel {
      
      private Timer timer;        // Timer that drives the animation.
      
      private int width, height;  // The size of the panel -- the values are set
                                 //    the first time the paintComponent() method
                                 //    is called.  This class is not designed to
                                 //    handle changes in size; once the width and
                                 //    height have been set, they are not changed.
                                 //    Note that width and height cannot be set
                                 //    in the constructor because the width and
                                 //    height of the panel have not been set at
                                 //    the time that the constructor is called.
      
      private Boat boat;          // The boat, bomb, and sub objects are defined
      private Bomb bomb;          //    by nested classes Boat, Bomb, and Submarine,
      private Submarine sub;      //    which are defined later in this class.
                                 //    Note that the objects are created in the
                                 //    paintComponent() method, after the width
                                 //    and height of the panel are known.
      
      
       /**
      * The constructor sets the background color of the panel, creates the
      * timer, and adds a KeyListener, FocusListener, and MouseListener to the
      * panel.  These listeners, as well as the ActionListener for the timer
      * are defined by anonymous inner classes.  The timer will run only
      * when the panel has the input focus.
      */
      public SubKillerPanel() {
      
        setBackground(Color.GREEN);
      
        ActionListener action = new ActionListener() {
                 // Defines the action taken each time the timer fires.
           public void actionPerformed(ActionEvent evt) {
              if (boat != null) {
                 boat.updateForNewFrame();
                 bomb.updateForNewFrame();
                 sub.updateForNewFrame();
              }
              repaint();
           }
        };
        timer = new Timer( 30, action );  // Fires every 30 milliseconds.
      
        addMouseListener( new MouseAdapter() {
                // The mouse listener simply requests focus when the user
                // clicks the panel.
           public void mousePressed(MouseEvent evt) {
              requestFocus();
           }
        } );
      
        addFocusListener( new FocusListener() {
               // The focus listener starts the timer when the panel gains
               // the input focus and stops the timer when the panel loses
               // the focus.  It also calls repaint() when these events occur.
           public void focusGained(FocusEvent evt) {
              timer.start();
              repaint();
           }
           public void focusLost(FocusEvent evt) {
              timer.stop();
              repaint();
           }
        } );
      
        addKeyListener( new KeyAdapter() {
               // The key listener responds to keyPressed events on the panel. Only
               // the left-, right-, and down-arrow keys have any effect.  The left- and
               // right-arrow keys move the boat while down-arrow releases the bomb.
           public void keyPressed(KeyEvent evt) {
              int code = evt.getKeyCode();  // Which key was pressed?
              if (code == KeyEvent.VK_LEFT) {
                   // Move the boat left.  (If this moves the boat out of the frame, its
                   // position will be adjusted in the boat.updateForNewFrame() method.)
                 boat.centerX -= 15;
              }
              else if (code == KeyEvent.VK_RIGHT) {
                   // Move the boat right.  (If this moves boat out of the frame, its
                   // position will be adjusted in the boat.updateForNewFrame() method.)
                 boat.centerX += 15;
              }
              else if (code == KeyEvent.VK_DOWN) {
                    // Start the bomb falling, if it is not already falling.
                 if ( bomb.isFalling == false )
                    bomb.isFalling = true;
              }
           }
        } );
      
       } // end constructor
      
      
      /**
      * The paintComponent() method draws the current state of the game.  It
      * draws a gray or cyan border around the panel to indicate whether or not
      * the panel has the input focus.  It draws the boat, sub, and bomb by
      * calling their respective draw() methods.
      */
      public void paintComponent(Graphics g) {
      
        super.paintComponent(g);  // Fill panel with background color, green.
      
        if (boat == null) {
              // The first time that paintComponent is called, it assigns
              // values to the instance variables.
           width = getWidth();
           height = getHeight();
           boat = new Boat();
           sub = new Submarine();
           bomb = new Bomb();
        }
      
        if (hasFocus())
           g.setColor(Color.CYAN);
        else {
           g.setColor(Color.RED);
           g.drawString("CLICK TO ACTIVATE", 20, 30);
           g.setColor(Color.GRAY);
        }
        g.drawRect(0,0,width-1,height-1);  // Draw a 3-pixel border.
        g.drawRect(1,1,width-3,height-3);
        g.drawRect(2,2,width-5,height-5);
      
        boat.draw(g);
        sub.draw(g);
        bomb.draw(g);
      
       } // end drawFrame()
      
      
      /**
      * This nested class defines the boat.  Note that its constructor cannot
      * be called until the width of the panel is known!
      */
      private class Boat {
        int centerX, centerY;  // Current position of the center of the boat.
        Boat() { // Constructor centers the boat horizontally, 80 pixels from top.
           centerX = width/2;
           centerY = 80;
        }
        void updateForNewFrame() { // Makes sure boat has not moved off screen.
           if (centerX < 0)
              centerX = 0;
           else if (centerX > width)
              centerX = width;
        }
        void draw(Graphics g) {  // Draws the boat at its current location.
           g.setColor(Color.BLUE);
           g.fillRoundRect(centerX - 40, centerY - 20, 80, 40, 20, 20);
        }
       } // end nested class Boat
      
      
       /**
       * This nested class defines the bomb.
       */
       private class Bomb {
        int centerX, centerY; // Current position of the center of the bomb.
        boolean isFalling;    // If true, the bomb is falling; if false, it
                              // is attached to the boat.
        Bomb() { // Constructor creates a bomb that is initially attached to boat.
           isFalling = false;
        }
        void updateForNewFrame() {  // If bomb is falling, take appropriate action.
           if (isFalling) {
              if (centerY > height) {
                    // Bomb has missed the submarine.  It is returned to its
                    // initial state, with isFalling equal to false.
                 isFalling = false;
              }
              else if (Math.abs(centerX - sub.centerX) <= 36 &&
                                   Math.abs(centerY - sub.centerY) <= 21) {
                    // Bomb has hit the submarine.  The submarine
                    // enters the "isExploding" state.
                 sub.isExploding = true;
                 sub.explosionFrameNumber = 1;
                 isFalling = false;  // Bomb reappears on the boat.
              }
              else {
                   // If the bomb has not fallen off the panel or hit the
                   // sub, then it is moved down 10 pixels.
                 centerY += 10;
              }
           }
        }
        void draw(Graphics g) {  // Draw the bomb.
           if ( ! isFalling ) {  // If not falling, set centerX and CenterY
                                // to show the bomb on the bottom of the boat.
              centerX = boat.centerX;
              centerY = boat.centerY + 23;
           }
           g.setColor(Color.RED);
           g.fillOval(centerX - 8, centerY - 8, 16, 16);
        }
       } // end nested class Bomb
      
      
      /**
      * This nested class defines the sub.  Note that its constructor cannot
      * be called until the width of the panel is known!
      */
      private class Submarine {
        int centerX, centerY; // Current position of the center of the sub.
        boolean isMovingLeft; // Tells whether the sub is moving left or right
        boolean isExploding;  // Set to true when the sub is hit by the bomb.
        int explosionFrameNumber;  // If the sub is exploding, this is the number
                                   //   of frames since the explosion started.
        Submarine() {  // Create the sub at a random location 40 pixels from bottom.
           centerX = (int)(width*Math.random());
           centerY = height - 40;
           isExploding = false;
           isMovingLeft = (Math.random() < 0.5);
        }
        void updateForNewFrame() { // Move sub or increase explosionFrameNumber.
           if (isExploding) {
                 // If the sub is exploding, add 1 to explosionFrameNumber.
                 // When the number reaches 15, the explosion ends and the
                 // sub reappears in a random position.
              explosionFrameNumber++;
              if (explosionFrameNumber == 15) {
                 centerX = (int)(width*Math.random());
                 centerY = height - 40;
                 isExploding = false;
                 isMovingLeft = (Math.random() < 0.5);
              }
           }
           else { // Move the sub.
              if (Math.random() < 0.04) {
                    // In one frame out of every 25, on average, the sub
                    // reverses its direction of motion.
                 isMovingLeft = ! isMovingLeft;
              }
              if (isMovingLeft) {
                    // Move the sub 5 pixels to the left.  If it moves off
                    // the left edge of the panel, move it back to the left
                    // edge and start it moving to the right.
                 centerX -= 5;
                 if (centerX <= 0) {
                    centerX = 0;
                    isMovingLeft = false;
                 }
              }
              else {
                    // Move the sub 5 pixels to the right.  If it moves off
                    // the right edge of the panel, move it back to the right
                    // edge and start it moving to the left.
                 centerX += 5;
                 if (centerX > width) {
                    centerX = width;
                    isMovingLeft = true;
                 }
              }
           }
        }
        void draw(Graphics g) {  // Draw sub and, if it is exploding, the explosion.
           g.setColor(Color.BLACK);
           g.fillOval(centerX - 30, centerY - 15, 60, 30);
           if (isExploding) {
                  // Draw an "explosion" that grows in size as the number of
                  // frames since the start of the explosion increases.
              g.setColor(Color.YELLOW);
              g.fillOval(centerX - 4*explosionFrameNumber,
                    centerY - 2*explosionFrameNumber,
                    8*explosionFrameNumber,
                    4*explosionFrameNumber);
              g.setColor(Color.RED);
              g.fillOval(centerX - 2*explosionFrameNumber,
                    centerY - explosionFrameNumber/2,
                    4*explosionFrameNumber,
                    explosionFrameNumber);
           }
        }
       } // end nested class Submarine
      
      
      } // end class SubKiller
      

      【讨论】:

        猜你喜欢
        • 2018-08-18
        • 1970-01-01
        • 2013-05-16
        • 2017-09-27
        • 2020-08-17
        • 1970-01-01
        • 2017-12-26
        • 1970-01-01
        • 2018-02-21
        相关资源
        最近更新 更多