2013-04-30 4 views
0

Итак, у меня есть приложение, которое успешно перемещает шар (эллипс) влево, вправо, вверх или вниз в зависимости от того, какая кнопка на клавиатуре нажата. Однако у меня возникают проблемы с тем, чтобы мяч двигался под углом. Я пытаюсь сделать это, сказав, что если пользователь держит 2 клавиши направления, мяч пойдет по диагонали. Например, если они нажимают левую клавишу и клавишу вверх, я хочу, чтобы мяч двигался в направлении NorthWest. Если кто-нибудь из вас увидит причину проблемы, я бы очень благодарен за помощь!Использование клавиатуры для перемещения круга под углами в java

Двигатель

class KeyClickListener implements KeyListener 
     { 
     public void keyPressed(KeyEvent e) 
     { 
      if (e.getKeyCode() == KeyEvent.VK_DOWN) 
       { 
        component.moveCircle(1); 
       } 
      else if (e.getKeyCode() == KeyEvent.VK_UP) 
       { 
        component.moveCircle(2); 
       } 
      else if (e.getKeyCode() == KeyEvent.VK_RIGHT) 
       { 
        component.moveCircle(3); 
       } 
      else if (e.getKeyCode() == KeyEvent.VK_LEFT) 
       { 
        component.moveCircle(5); 
       } 
      //this is my attempt at telling whether or not the user was holding two keys 
      else if (e.getKeyCode() == KeyEvent.VK_LEFT && e.getKeyCode() == KeyEvent.VK_UP) 
       { 
        component.moveCircle(5); 
       } 
     } 
     public void keyReleased(KeyEvent e){} 
     public void keyTyped(KeyEvent e){} 
    } 

CircleComponent

public void moveCircle(int w) 
{ 
    dir = w; 
    if (dir == 1) 
     { 
      y+=20; 
      repaint(); 
      if (y>=560) 
       { 
        dir=2; 
       } 
     } 
. 
. 
. 

else if (dir == 5) 
     { 
      x-=10; 
      y-=10; 
      repaint(); 
      if(x<=0) 
       { 
        dir=3; 
       } 
     } 
} 

ответ

3

Поскольку ключевые события будут сообщать только последний ключ, который вызвал событие, ваш последний if заявление никогда не будет работать, так как keyCode будет только соответствовать последнему ключу, вызвавшему событие.

Вместо этого вы должны поддерживать «состояние» каждой клавиши и обрабатывать это состояние вместо этого.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestKeyListener01 { 

    public static void main(String[] args) { 
     new TestKeyListener01(); 
    } 

    public TestKeyListener01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private boolean arrowUp = false; 
     private boolean arrowDown = false; 
     private boolean arrowLeft = false; 
     private boolean arrowRight = false; 

     public TestPane() { 
      setFocusable(true); 
      addKeyListener(new KeyAdapter() { 

       @Override 
       public void keyReleased(KeyEvent e) { 
        switch (e.getKeyCode()) { 
         case KeyEvent.VK_DOWN: 
          arrowDown = false; 
          break; 
         case KeyEvent.VK_UP: 
          arrowUp = false; 
          break; 
         case KeyEvent.VK_LEFT: 
          arrowLeft = false; 
          break; 
         case KeyEvent.VK_RIGHT: 
          arrowRight = false; 
          break; 
        } 
        repaint(); 
       } 

       @Override 
       public void keyPressed(KeyEvent e) { 
        switch (e.getKeyCode()) { 
         case KeyEvent.VK_DOWN: 
          arrowDown = true; 
          break; 
         case KeyEvent.VK_UP: 
          arrowUp = true; 
          break; 
         case KeyEvent.VK_LEFT: 
          arrowLeft = true; 
          break; 
         case KeyEvent.VK_RIGHT: 
          arrowRight = true; 
          break; 
        } 
        repaint(); 
       } 
      }); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      FontMetrics fm = g2d.getFontMetrics(); 
      String text = "Up"; 
      int x = (getWidth() - fm.stringWidth(text))/2; 
      int y = ((getHeight()/2) - fm.getHeight()); 
      draw(g2d, text, x, y, arrowUp); 

      text = "Down"; 
      x = (getWidth() - fm.stringWidth(text))/2; 
      y = ((getHeight()/2) + fm.getHeight()) + fm.getAscent(); 
      draw(g2d, text, x, y, arrowDown); 

      text = "Left"; 
      x = (getWidth()/2) - fm.stringWidth(text) - 4; 
      y = ((getHeight() - fm.getHeight())/2) + fm.getAscent(); 
      draw(g2d, text, x, y, arrowLeft); 

      text = "Right"; 
      x = (getWidth()/2) + 4; 
      y = ((getHeight() - fm.getHeight())/2) + fm.getAscent(); 
      draw(g2d, text, x, y, arrowRight); 

      g2d.dispose(); 
     } 

     protected void draw(Graphics2D g2d, String text, int x, int y, boolean pressed) { 
      g2d.setColor(pressed ? Color.BLACK : Color.GRAY); 
      g2d.drawString(text, x, y); 
     } 
    } 
} 

Я также рекомендовал бы вместо KeyListener, вы должны использовать вместо Key Bindings. Они решают раздражающие проблемы фокуса, которые чумы KeyListener

+0

+1 для ключей; ['LinePanel'] (http://stackoverflow.com/a/5797965/230513) является примером. – trashgod

0

Измените свой KeyClickListener и наблюдайте за магией! затем проверьте это http://zetcode.com/tutorials/javagamestutorial/movingsprites/

class KeyClickListener implements KeyListener, Runnable 
    { 
     private boolean moveLeft, moveRight, moveUp, moveDown; 
     private Thread runThread; 
     public KeyClickListener() { 
      moveLeft = moveRight = moveUp = moveDown = false; 
      runThread = new Thread(this); 
      runThread.start(); 
     } 
     public void keyPressed(KeyEvent e) {assessKeycodes(e, true);} 
     public void keyReleased(KeyEvent e){assessKeycodes(e, false);} 
     public void keyTyped(KeyEvent e){} 

     private void assessKeycodes(KeyEvent e, boolean setTo) { 
      switch(e.getKeyCode()) { 
       case KeyEvent.VK_DOWN: 
        moveDown = setTo; 
        break; 
       case KeyEvent.VK_UP: 
        moveDown = setTo; 
        break; 
       case KeyEvent.VK_LEFT: 
        moveDown = setTo; 
        break; 
       case KeyEvent.VK_RIGHT: 
        moveDown = setTo; 
        break; 
      } 
     } 

     public void run() { 
      while(true) { 
       if (moveDown) 
         component.moveCircle(1); 
       if (moveUp) 
         component.moveCircle(2); 
       if (moveRight) 
         component.moveCircle(3); 
       if (moveLeft) 
         component.moveCircle(5); 
      } 
     } 
    } 

 Смежные вопросы

  • Нет связанных вопросов^_^