David Liu
David Liu

Reputation: 1

how to use keylistener and timer at the same time?

I am trying to make the game snake but I cant seem to get the keyboard controls to run the same time as the graphics display. how can i implement keylistener inside the timer method?

import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.Timer;

public class Game extends JFrame {

    private static final long serialVersionUID = 7607561826495057981L;
    GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()
            .getDefaultScreenDevice();
    int width = gd.getDisplayMode().getWidth();
    int height = gd.getDisplayMode().getHeight();

    private Timer timer;
    private int xCor = 400, yCor = 150;
    private int speed = 1, move = 1;
    private final int top = 0, bottom = height - 10, right = width - 10,
            left = 0;
    private boolean north = false, south = false, east = true, west = false;

    public Game() {
        setTitle("Snake");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(width, height);
        setResizable(false);
        init();
        setVisible(true);
    }

    public void init() {

        timer = new Timer(speed, new TimerListener());

        timer.start();
    }

    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.black);
        g.fillRect(xCor, yCor, 10, 10);

    }

    private class TimerListener implements ActionListener {
        public void actionPerformed(ActionEvent f) {

            if (south) {
                if (xCor >= left && xCor <= right && yCor >= top
                        && yCor <= bottom) {
                    yCor += move;
                }
            }
            if (north) {
                if (xCor >= left && xCor <= right && yCor >= top
                        && yCor <= bottom) {
                    yCor -= move;
                }
            }
            if (west) {
                if (xCor >= left && xCor <= right && yCor >= top
                        && yCor <= bottom) {
                    xCor -= move;
                }
            }

            if (east) {
                if (xCor >= left && xCor <= right && yCor >= top
                        && yCor <= bottom) {
                    xCor += move;

                }
            }
            repaint();
        }
    }

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

this is my keyboard control class

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class KeyControls extends JFrame implements KeyListener {

    private static final long serialVersionUID = 2227545284640032216L;
    private boolean north = false, south = false, east = true, west = false;


    public void keyTyped(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        int i = e.getKeyChar();
        if (i == KeyEvent.VK_W && !south) {
            north = true;
            east = false;
            west = false;
            south = false;

        }
        if (i == KeyEvent.VK_S && !north) {
            north = false;
            east = false;
            west = false;
            south = true;
        }
        if (i == KeyEvent.VK_A && !west) {
            north = false;
            east = true;
            west = false;
            south = false;
        }
        if (i == KeyEvent.VK_D && !east) {
            north = false;
            east = false;
            west = true;
            south = false;
        }
    }
}

Upvotes: 0

Views: 1152

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

  1. You need to register the KeyControls to something that is capable of generating KeyEvents
  2. There is no need for KeyControls to extend from JFrame, that's just going to confuse things.
  3. Consider using the key bindings API instead the KeyListener, it will give you better control over the level of focus a component needs to have before it triggers a key event. See How to Use Key Bindings for more details
  4. Avoid overriding paint of top level containers like JFrame, in your case, this is going to cause flickering when ever the frame is updated. Instead, create a custom class extending from something like JPanel and override it's paintComponent method and place you custom painting there. It would probably be prudent to encapsulate the Timer and key bindings within this class as well. Have a look at Painting in AWT and Swing and Performing Custom Painting for more details

Upvotes: 1

Related Questions