2012-10-28 110 views
0

我在嘗試讓我的代碼在屏幕上移動播放器(發送)時遇到了很多麻煩。我可以讓行星在屏幕上畫畫,然後玩家發佈,但我無法弄清楚如何實現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"); 
     } 
    } 





    } 

回答

2

KeyListener不是最合適的方法來實現您的結果。

這將是更好的使用key bindings API。

除了簡化了代碼,它也將允許您提供在密鑰應該引發了更好的對焦控制。

0

這裏我設計你類似的,在那裏你可以使用方向鍵,正扔在移動的船炸彈(這是我的項目幾年前:))的應用程序,設計運行的重要手段,希望這將幫助:

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