2015-07-03 4 views
0

Я хочу, чтобы мой прямоугольник остановился, когда пользователь нажимает левую и правую клавиши. Я исследовал несколько ключевых манипуляций, но не смог ничего найти.Breakout Game Multiple Key Handling

package View; 

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

public class GamePanel extends JPanel { 

private final int WIDTH = 600, HEIGHT = 500; 

// PROPERTIES 

private Timer timer; 
int x = 0; 
int y = 475; 
int velX = 0; // only left or right 

// CONSTRUCTOR 

public GamePanel() { 

    setSize(WIDTH, HEIGHT); 
    setBackground(new Color(240, 255, 255)); 

    timer = new Timer(5, new MyTimerListener());   
    addKeyListener(new MyKeyListener()); 

    setFocusable(true); // for key listening 
    setFocusTraversalKeysEnabled(false); 

    timer.start(); 
} 

// METHODS 

@Override 
public void paintComponent(Graphics g) { 

    super.paintComponent(g); 
    g.setColor(new Color(201, 51, 51)); 
    g.fillRoundRect(x, y, 80, 20, 15, 15);  
} 

public class MyTimerListener implements ActionListener { 

    @Override 
    public void actionPerformed(ActionEvent e) { 

     if (x < 0) 
     { 
      velX = 0; 
      x = 0;   
     } 

     if (x > 520) 
     { 
      velX = 0; 
      x = 520; 
     } 

     x = x + velX; 

     repaint(); 
    }  
} 

public class MyKeyListener implements KeyListener { 

    @Override 
    public void keyPressed(KeyEvent e) { 

     int code = e.getKeyCode(); 

     if (code == KeyEvent.VK_LEFT) 
      velX = -1; 

     if (code == KeyEvent.VK_RIGHT) 
      velX = 1;  
    } 
    @Override 
    public void keyReleased(KeyEvent e) { 

     velX = 0;   
    } 
    @Override 
    public void keyTyped(KeyEvent e) {}    
} 
} 

благодарю за heeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeelp

a busy cat ! [Два Muppets]

+1

Домашний очаг, я ненавижу, «Я исследовал несколько манипуляций с ключевыми словами, но не смог ничего найти». «Ненавидьте, ненавидьте ненавижу. Наверняка вы читали о привязках клавиш, нет? Стреляйте, я написал несколько примеров кода на этом сайте, которые затрагивают эту самую проблему - повторите поиск. –

+2

[Например] (http://stackoverflow.com/a/6887354/522444) и [еще один пример] (http://stackoverflow.com/a/12545773/522444). –

+0

, поэтому я имею в виду, что мне не нужен прослушиватель клавиш. Я пытаюсь понять, что сейчас –

ответ

3

Так снова, используйте привязки ключей и не KeyListener. Вы хотели бы использовать отдельные привязки для нажатия и отпускания клавиш для клавиш со стрелками вправо и влево и хотите, чтобы ваши действия по привязке клавиш изменили состояние вашей программы, что повлияет на то, как Swing Timer перемещает весло. В этом примере здесь (заимствован из другого моего примера), я создал перечисление, Direction, чтобы инкапсулировать правое и левое направления, и создал Map<Direction, Boolean>, который будет ассоциировать логическое значение как с правым, так и с левым направлением. Стрелка вправо со стрелкой изменит карту, чтобы связать направление ПРАВО с буфером true, и релиз ключа сделает наоборот. Таймер опросит карту, чтобы увидеть, куда перемещать весло. Например:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.util.EnumMap; 
import java.util.Map; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class GamePanel2 extends JPanel { 
    private static final int PREF_W = 600; 
    private static final int PREF_H = 500; 
    private static final int PADDLE_Y = 475; 
    private static final int PADDLE_W = 80; 
    private static final int PADDLE_H = 20; 
    private static final int PADDLE_ARC = 15; 
    private static final int TIME_DELAY = 15; 
    public static final int VEL_X = 2; 
    private static final Color PADDLE_COLOR = new Color(201, 51, 51); 
    private int paddleX; 
    private Timer time = new Timer(TIME_DELAY, new TimerListener()); 

    // key presses and releases will change the boolean values held in this Map 
    // When an arrow key is pressed, the direction-corresponding boolean is set true 
    // and likewise when the arrow key is released the direction corresponding boolean is false 
    private Map<Direction, Boolean> dirMap = new EnumMap<>(Direction.class); 


    public GamePanel2() { 
     setKeyBindings(); 
     time.start(); 
    } 

    private void setKeyBindings() { 
     int condition = WHEN_IN_FOCUSED_WINDOW; 
     InputMap inputMap = getInputMap(condition); 
     ActionMap actionMap = getActionMap(); 

     // iterate through all the Direction enums 
     for (Direction direction : Direction.values()) { 
     // set all values to false 
     dirMap.put(direction, false); 

     // create two key strokes, one for pressed and one for released 
     int keyValue = direction.getKeyValue(); 
     KeyStroke pressedKey = KeyStroke.getKeyStroke(keyValue, 0, false); 
     KeyStroke releasedKey = KeyStroke.getKeyStroke(keyValue, 0, true); 

     // create two Actions, one for pressed, one for released 
     Action pressedAction = new KeyAction(direction, true); 
     Action releasedAction = new KeyAction(direction, false); 

     // add keystroke to inputMap and use keystroke's toString as binding link 
     inputMap.put(pressedKey, pressedKey.toString()); 
     inputMap.put(releasedKey, releasedKey.toString()); 

     // link binding links to our actions 
     actionMap.put(pressedKey.toString(), pressedAction); 
     actionMap.put(releasedKey.toString(), releasedAction); 
     } 

    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
     return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     g.setColor(PADDLE_COLOR); 
     g.fillRoundRect(paddleX, PADDLE_Y, PADDLE_W, PADDLE_H, PADDLE_ARC, PADDLE_ARC); 
    } 

    private class TimerListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
     // if JPanel no longer displayed, stop the Timer 
     if (!GamePanel2.this.isDisplayable()) { 
      ((Timer) e.getSource()).stop(); 
     } 
     // here's the key: iterate through the Direction enum 
     for (Direction direction : Direction.values()) { 
      // get corresponding boolean from dirMap 
      // and if true, change location of x and y 
      if (dirMap.get(direction)) { 
       int possibleX = paddleX + VEL_X * direction.getDeltaX(); 
       if (direction == direction.RIGHT && possibleX + PADDLE_W <= getWidth()) { 
        paddleX = possibleX; 
       } 
       if (direction == Direction.LEFT && possibleX >= 0) { 
        paddleX = possibleX; 
       } 
      } 
     } 
     repaint(); 
     } 
    } 

    private class KeyAction extends AbstractAction { 
     private Direction direction; 
     private boolean pressed; 

     public KeyAction(Direction direction, boolean pressed) { 
     this.direction = direction; 
     this.pressed = pressed;    
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
     dirMap.put(direction, pressed); // key press simply changes the map, that's it. 
     } 
    } 

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

     JFrame frame = new JFrame("GamePanel2"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_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(); 
     } 
     }); 
    } 
} 

enum Direction { 
    LEFT("Left", KeyEvent.VK_LEFT, -1), 
    RIGHT("Right", KeyEvent.VK_RIGHT, 1); 

    private String text; 
    private int keyValue; // KeyEvent.VK_? 
    private int deltaX; 

    Direction(String text, int keyValue, int deltaX) { 
     this.text = text; 
     this.keyValue = keyValue; 
     this.deltaX = deltaX; 
    } 

    public String getText() { 
     return text; 
    } 

    public int getKeyValue() { 
     return keyValue; 
    } 

    @Override 
    public String toString() { 
     return text; 
    } 

    public int getDeltaX() { 
     return deltaX; 
    } 
} 
+0

WOOOW. SOO SMooth. –

+0

Я обещаю, я узнаю каждую строку этого кода. Завтра я отдам весь день –

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