使用KeyListener移动矩形

时间:2018-04-25 01:14:42

标签: java swing user-interface graphics keylistener

我正在尝试使用KeyListener移动一个矩形。我见过其他人使用相同的代码但由于某种原因我不能让它移动。现在矩形确实出现了。如果有什么东西我不知道,我不确定我是否忘记了什么。 这是我的代码:

board_tiles = [0, 1, 2, 3, 4, 5, 6, 7, 8]
tiles_available = [0, 1, 2, 3, 4, 5, 6, 7, 8]

# create a function that draw the board
def draw_board():
    #call clear_screen()

    print(f'{board_tiles[0]} | {board_tiles[1]} | {board_tiles[2]}')
    print('------------------')
    print(f'{board_tiles[3]} | {board_tiles[4]} | {board_tiles[5]}')
    print('------------------')
    print(f'{board_tiles[6]} | {board_tiles[7]} | {board_tiles[8]}')

# create a function that prompts the user to choose a character
def player_input():
    mark = input('Would you like to be "X" or "O"? ').lower()
    if mark == 'x':
        player1 = 'x'
        player2 = 'o'
    else:
        player1 = 'o'
        player2 = 'x'
    print(f'Player1, you are {player1}.  That means Player2 is {player2}.  LETS PLAY!')

    return player1, player2

# create a function that defines a win
def winning_combo(player1, player2):
    players = [player1, player2]
    turn = 0
    player = players[turn]
    turn = (turn + 1) % len(players)
    while tiles_available:
        move = int(input('Where would you like to move? '))
        if move in tiles_available:
            tiles_available.remove(move)
            board_tiles.insert(board_tiles[move], player)
            board_tiles.remove(move)
        else:
            print('That move has already been taken.')

        return move, turn, player

# create a function to determine when a player wins
def win_combo():
    if board_tiles[0] == board_tiles[1] == board_tiles[2] or \
        board_tiles[3] == board_tiles[4] == board_tiles[5] or \
        board_tiles[6] == board_tiles[7] == board_tiles[8] or \
        board_tiles[0] == board_tiles[3] == board_tiles[6] or \
        board_tiles[1] == board_tiles[4] == board_tiles[7] or \
        board_tiles[2] == board_tiles[5] == board_tiles[8] or \
        board_tiles[0] == board_tiles[4] == board_tiles[8] or \
        board_tiles[2] == board_tiles[4] == board_tiles[6]:
        quit()
    else:
        True
# create a game function
def game():
    playing = True
    player1, player2 = player_input()
    while playing:
        draw_board()
        winning_combo(player1, player2)
        win_combo()

game()

2 个答案:

答案 0 :(得分:2)

除了不尊重油漆链(并致电super.paintComponent)之外,您的首要问题是使用KeyListener

短暂的搜索会很快告诉您KeyListener因为没有响应而臭名昭着,因为通常不可靠。

最常见的解决方案是使用key bindings API

以下是将键绑定实现到当前代码库

的非常简单的示例
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) throws IOException, InterruptedException {
        new Test();
    }

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

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

    public class RoomWars extends JPanel implements ActionListener {
        //public JPanel pane;

        int x = 0, y = 0, velx = 0, vely = 0;
        Timer t = new Timer(5, this);

        public RoomWars() {
            t.start();

            InputMap im = getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up.pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up.released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down.pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down.released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left.pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left.released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right.pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right.released");

            am.put("up.pressed", new MoveAction(-1, 0));
            am.put("up.released", new MoveAction(0, 0));
            am.put("down.pressed", new MoveAction(1, 0));
            am.put("down.released", new MoveAction(0, 0));
            am.put("left.pressed", new MoveAction(0, -1));
            am.put("left.released", new MoveAction(0, 0));
            am.put("right.pressed", new MoveAction(0, 1));
            am.put("right.released", new MoveAction(0, 0));
        }

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

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Color mypurple = new Color(34, 0, 56);
            g.setColor(mypurple);
            g.fillRect(x, y, 30, 30);
            //g.setColor(Color.PINK);
            //g.fillRect(655,632,30,30);
        }

        public class MoveAction extends AbstractAction {
            private int yDelta;
            private int xDelta;

            public MoveAction(int yDelta, int xDelta) {
                this.yDelta = yDelta;
                this.xDelta = xDelta;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                vely = yDelta;
                velx = xDelta;
            }
        }

        public void actionPerformed(ActionEvent e) {
            repaint();
            x += velx;
            y += vely;
        }

    }
}

答案 1 :(得分:-1)

请注意,在您的代码段中,未调用second(),因此未注册密钥侦听器。您的面板还需要具有焦点才能接收重要的新闻事件。您可能还想先在方法中调用super.paintComponent()

详情请见此处:

https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html