1

I wrote this code for very simple pong and everything works well except I just can't figure out how to make KeyListener work. I don't know where to put the Listener or how to use it. Any other tips are welcome, I am a noob so please explain to that level.

package pong;

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

public class Pong extends JPanel implements KeyListener
{   
    int border = 15;

    int enemyScore = 0;
    int playerScore = 0;

    int ballx = 248;
    int bally = 170;

    int playerx = 482;
    double playery = 162;
    int playeryy = 162;

    int enemyx = 0;
    double enemyy = 162;
    int enemyyy = 162;

    boolean gameReset = true;

    boolean down;
    boolean right;

    //ball movement
    private void moveBall()
    {
        Random rand = new Random();

        while (gameReset == true)
        {
            ballx = 240;
            bally = 170;
            down = rand.nextBoolean();
            right = rand.nextBoolean();
            gameReset = false;
        }

        if (right == true)
        {
            ballx++;
        }
        else
        {
            ballx--;
        }

        if (down == true)
        {
            bally++;
        }
        else
        {
            bally--;
        }

        if(bally == getHeight()-border)
        {
            down = false;
        }
        else if (bally == 0)
        {
            down = true;
        }

        if (playeryy < bally+14 && playeryy+59 > bally && ballx == 468)
        {
            right = false;
        } 
        else if (ballx == getWidth()-border)
        {
            gameReset = true;
            enemyScore ++;
        }
        else if (enemyyy < bally+14 && enemyyy+59 > bally && ballx == 13)
        {
            right = true;
        } 
        else if (ballx == 0)
        {
            gameReset = true;
            playerScore ++;
        }
    }


    //enemy movement
    private void moveEnemy()
    {
        if (right == false && bally > enemyy+8 && enemyy < 294)
        {
            enemyy += 0.8;
            enemyyy = (int) enemyy;
        }
        else if (right == false && bally < enemyy+8 && enemyy > 0)
        {
            enemyy -= 0.8;
            enemyyy = (int) enemyy;
        }
    }

    //Drawing
    @Override                               
    public void paint(Graphics g)
    {
        super.paint(g);
        g.fillRect(enemyx, enemyyy, 15, 60);
        g.fillRect(playerx, playeryy, 15, 60);
        g.fill3DRect(ballx, bally, 15, 15, true);
        System.out.println("Enemy Score: " + enemyScore + " Player Score: "+ playerScore);
    }

    public static void main(String[] args) throws InterruptedException
    {

        JFrame frame = new JFrame("p0ng");                      //makes new frame
        frame.setSize(512,384);                                 //sets the size
        frame.setVisible(true);                                 //makes it visble
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   //allows it to sleep
        Pong game = new Pong();
        frame.add(game);

        while(true)
        {
            game.moveBall();
            game.moveEnemy();
            game.repaint();

            Thread.sleep(10);
        }     
    }  

    @Override
    public void keyTyped(KeyEvent ke) {
        //not being used
    }

    //Player movement
     @Override
    public void keyPressed(KeyEvent e) 
    {  
        if (e.getKeyCode() == KeyEvent.VK_UP && playery < 294)
        {
            playery += .8;
            playeryy = (int) playery;
        }
            else if (e.getKeyCode() == KeyEvent.VK_DOWN && playery > 0)
        {
            playery -= .8;
            playeryy = (int) playery;
        }
        repaint();
    }

    @Override
    public void keyReleased(KeyEvent ke) {
        //not being used
    }
}

2 Answers2

2

Any other tips are welcome

  • Don't use KeyListener, it's too unreliable, especially when there are better options available. Start by having a look at How to Use Key Bindings
  • As a generally rule of thumb, you should override paintComponent instead of paint. Have a look at Performing Custom Painting and Painting in AWT and Swing
  • You're violating the single thread rules of Swing and risking race conditions between you core logic and the UI. Have a look at Concurrency in Swing for more details and How to use Swing Timers for a simple solution
  • Your "main" loop is setup wrong. Each iteration of the loop should update the current state that needs to be painted. You shouldn't be using "holding" loops to "pause" the state, but instead use if statements to block out the sections you need/don't need to execute based on the current state
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Can you show me how it would look with this code. I'm having a hard time understanding how to use Key Binding –  Jun 06 '16 at 19:41
  • [Key bindings example](http://stackoverflow.com/questions/17984912/java-key-bindings-not-working/17984949#17984949) – MadProgrammer Jun 06 '16 at 20:20
0
public Pong(){
addKeyListner(this);
}

you need to register your panel to the keyListner. you can use addKeyListner method to do it, since you have implemented Keylistner to the same class . you can use this keyword.you can do this within the constructor.

Priyamal
  • 2,919
  • 2
  • 25
  • 52
  • *"this is a wrong answer."* - so is this. While it "might" work, it's unreliable and as a generally, `KeyListener` is a poor choice, especially when more reliable solutions exist – MadProgrammer Jun 06 '16 at 09:47
  • i have no idea why do you say that `KeyListener` is a poor choice can u tell me why. – Priyamal Jun 06 '16 at 09:51
  • `KeyListener` is a poor choice because it's unreliable. It will only trigger events when the component it is registered to is focusable AND has focus, since the OP's code meets neither of these constraints, it will continue to fail to work. Even if they do make the component focusable and are able to focus the component, it doesn't take much for focus to be changed and the whole thing breaks again – MadProgrammer Jun 06 '16 at 09:54
  • well `jPanel` is `isFocusable` by default , but it is a good choice to move with `KeyBindings` instead of key listner . this link http://stackoverflow.com/questions/15290035/key-bindings-vs-key-listeners-in-java explains why we should use KeyBindings. thanks @MadProgrammer that was really helpful – Priyamal Jun 06 '16 at 10:01