import javax.swing.*;
import javax.swing.plaf.basic.BasicTreeUI;
import java.awt.*;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class GamePanel extends JPanel implements Runnable, KeyListener{
    final int originTileSize = 16; //The Size of the tiles, or grids
    final int scale = 3;
    final int tileSize = originTileSize * scale;
    final int screenCol = 10;
    final int screenRow = 12;
    final int screenHeight = screenCol * tileSize; //480 pixels
    final int screenWidth = screenRow * tileSize; //576 pixels
    int FPS = 60;
    boolean upPressed = false, downPressed = false, rightPressed = false, leftPressed = false;

    Thread gameThread;


    int playerX = 100;
    int playerY = 100;
    int playerSpeed = 4;

    public GamePanel(){
        this.setPreferredSize(new Dimension(screenWidth, screenHeight));
        this.setBackground(Color.black);
        this.setDoubleBuffered(true);
        this.addKeyListener(this);
        this.setFocusable(true);
        this.requestFocus();

        //Changes the frame so the panel comes out like this

    }

    public void startGameThread(){
        gameThread = new Thread(this);
        //Puts everything in the Class into the thread
        gameThread.start();
        //automatically calls the run method
    }


    @Override
    public void run() {


        double drawInterval = 1000000000/FPS; //0.1666 seconds
        double nextDrawTime = System.nanoTime() + drawInterval;

        while(gameThread != null){
            update();

            repaint();

            try {
                double remainingTime = nextDrawTime - System.nanoTime();
                remainingTime = remainingTime/1000000;

                if(remainingTime < 0){
                    remainingTime = 0;
                }

                Thread.sleep((long) remainingTime);

                nextDrawTime += drawInterval;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
//While this game loop is here it will keep running whatever is inside

    }
    private void update() {

        if(upPressed){
            playerY -= playerSpeed;
        }
        else if(downPressed){
            playerY += playerSpeed;
        }
        else if(rightPressed){
            playerX += playerSpeed;
        }
        else if(leftPressed){
            playerX -= playerSpeed;
        }
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D)g;

        g2.setColor(Color.white);

        g2.fillRect(playerX, playerY, tileSize, tileSize);

        g2.dispose();
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("Pressed W");
        int code = e.getKeyCode();
        if(code == KeyEvent.VK_W){
            System.out.println("Press W");
            upPressed = true;
        }
        else if(code == KeyEvent.VK_A) {
            System.out.println("Pressed A");
            downPressed = true;
        }
        else if(code == KeyEvent.VK_D) {
            System.out.println("Pressed D");
            rightPressed = true;
        }
        else if(code == KeyEvent.VK_S) {
            System.out.println("Pressed S");
            downPressed = true;
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        int code = e.getKeyCode();
        System.out.println(code);
        if(code == KeyEvent.VK_W) {
            upPressed = false;
        }
        else if(code == KeyEvent.VK_A) {
            downPressed = false;
        }
        else if(code == KeyEvent.VK_D) {
            rightPressed = false;
        }
        else if(code == KeyEvent.VK_S) {
            downPressed = false;
        }

    }
    //This is where we will keep a game loop. A thread is where it'll always keep running and so a game loop will always be running in here unless closed.
}

Recommended Answers

All 3 Replies

Do you have a program class (i.e., one with a main() method) which you could share with us, so we could test the GamePanel class ourselves? Even a minimal test class would help us.

If you have a public repo you could share with us, that would help immensely. You definitely should be using version control with an offsite repo, if you can, as it is crucial for ensuring the ability to monitor the progress of even small projects.

99% of the time this problem arises because the keyboard focus is not on the component that has the listener. It can often be fixed by the slightly tacky approach of adding the listener to all the JComponents involved.

The better solution is explained in this Oracle tutorial.

ps: looping with a sleep has problems as the app gets more complex. Use a ScheduledThreadPoolExecutor to run your updates at a fixed speed (and to simplify your code!).

I think you must put KeyListener this object into JFrame ,
and then it will be well

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.