Question

Ok, I'm trying to reinvent the wheel and program a snake game only with Swing and AWT and things that come with Java by default. But, far before that, I'm learning how to MOVE a square on the window. Cutting the mimimi, here's the thing:

I have a custom JComponent class called HeadSquare:

public class HeadSquare extends JComponent {

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = (int) screenSize.getWidth();
int screenHeight = (int) screenSize.getHeight();
int defaultSize = screenWidth / 2;
int snakeSquareDefaultSize = 10;

int headSquareXPos = ((defaultSize / 2) - (snakeSquareDefaultSize / 2));
int headSquareYPos = ((defaultSize / 2) - (snakeSquareDefaultSize / 2));

Rectangle head = new Rectangle(headSquareXPos, headSquareYPos, snakeSquareDefaultSize, snakeSquareDefaultSize);
Color snakeColor = Color.green;

private static final long serialVersionUID = 1L;

@Override
public Dimension getMinimumSize() {
    return new Dimension(0, 0);
}

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

@Override

public void paintComponent(Graphics g) {
    Graphics2D graphics2D = (Graphics2D) g;
    g.setColor(snakeColor);
    super.paintComponent(g);
    graphics2D.fill(head);

}

}

And I have a brilliant JPanel (that was declared up-somewhere-else):

snakePanel = new JPanel();

Main bla bla bla:

headSquare = new HeadSquare();
snakePanel.requestFocus();
snakePanel.add(headSquare);

And here it goes:

snakePanel.addKeyListener(new KeyListener() {

        @Override
        public void keyPressed(KeyEvent arg0) {
            if (arg0.getKeyCode() == KeyEvent.VK_LEFT) {
                headSquare.headSquareXPos -= 10;
                headSquare.head.setLocation(headSquare.headSquareXPos, headSquare.headSquareYPos);
                snakePanel.repaint();
            } else if (arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
                headSquare.headSquareXPos += 10;
                headSquare.head.setLocation(headSquare.headSquareXPos, headSquare.headSquareYPos);
                snakePanel.repaint();   
            } else if (arg0.getKeyCode() == KeyEvent.VK_UP) {
                headSquare.headSquareYPos -= 10;
                headSquare.head.setLocation(headSquare.headSquareXPos, headSquare.headSquareYPos);
                snakePanel.repaint();   
            } else if (arg0.getKeyCode() == KeyEvent.VK_DOWN) {
                headSquare.headSquareYPos += 10;
                headSquare.head.setLocation(headSquare.headSquareXPos, headSquare.headSquareYPos);
                snakePanel.repaint();   
            }
        }
    });
    contentPane.add(snakePanel, BorderLayout.CENTER);

The problem may become evident for the skilled ones (Everyone but me): The bloody square STOPS when you press an arrow, and thereafter press another arrow. E.g: Up.....Left. If you press both at the same time, it goes perfect, but if you press LEFT (-= 10), and then UP (it STOPS the (-= 10) of LEFT, it waits some time and it starts going UP, ignoring the old LEFT).

Well, I hope the topic is not too prolix, and that I've expressed myself clearly. I want it to combine the movement of the arrows without inconvenient haltings (in Allegro, in C, this happens by default). Do you know in depth why this happens? Do you know how to improve this movement?

I thank you very much!

Was it helpful?

Solution

See Motion Using the Keyboard that explains the problems of using a Key Listener. The preferred solution is to use Key Bindings.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top