Pong game in Java

Pong game image

Below is a simple implementation of a Pong game in Java using the Swing library. Copy and paste this code into a Java file (e.g., PongGame.java) and run it to play the game. You can further enhance it by adding features such as scoring, sound effects, or improving the graphics.

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class PongGame extends JFrame implements KeyListener {
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;
    private static final int PADDLE_WIDTH = 20;
    private static final int PADDLE_HEIGHT = 100;
    private static final int BALL_SIZE = 20;
    private static final int PADDLE_SPEED = 10;
    private static final int BALL_SPEED = 3;

    private int paddle1Y = HEIGHT / 2 - PADDLE_HEIGHT / 2;
    private int paddle2Y = HEIGHT / 2 - PADDLE_HEIGHT / 2;
    private int ballX = WIDTH / 2 - BALL_SIZE / 2;
    private int ballY = HEIGHT / 2 - BALL_SIZE / 2;
    private int ballXSpeed = BALL_SPEED;
    private int ballYSpeed = BALL_SPEED;

    public PongGame() {
        setTitle("Pong Game");
        setSize(WIDTH, HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        addKeyListener(this);
        getContentPane().setBackground(Color.BLACK);
        setFocusable(true);
    }

    public void movePaddle1Up() {
        if (paddle1Y - PADDLE_SPEED >= 0) {
            paddle1Y -= PADDLE_SPEED;
        }
    }

    public void movePaddle1Down() {
        if (paddle1Y + PADDLE_HEIGHT + PADDLE_SPEED <= HEIGHT) {
            paddle1Y += PADDLE_SPEED;
        }
    }

    public void movePaddle2Up() {
        if (paddle2Y - PADDLE_SPEED >= 0) {
            paddle2Y -= PADDLE_SPEED;
        }
    }

    public void movePaddle2Down() {
        if (paddle2Y + PADDLE_HEIGHT + PADDLE_SPEED <= HEIGHT) {
            paddle2Y += PADDLE_SPEED;
        }
    }

    public void moveBall() {
        ballX += ballXSpeed;
        ballY += ballYSpeed;

        // Collision with paddles
        if ((ballX <= PADDLE_WIDTH && ballY + BALL_SIZE >= paddle1Y && ballY <= paddle1Y + PADDLE_HEIGHT) ||
            (ballX + BALL_SIZE >= WIDTH - PADDLE_WIDTH && ballY + BALL_SIZE >= paddle2Y && ballY <= paddle2Y + PADDLE_HEIGHT)) {
            ballXSpeed = -ballXSpeed;
        }

        // Collision with top and bottom walls
        if (ballY <= 0 || ballY + BALL_SIZE >= HEIGHT) {
            ballYSpeed = -ballYSpeed;
        }

        // Scoring
        if (ballX <= 0 || ballX + BALL_SIZE >= WIDTH) {
            ballX = WIDTH / 2 - BALL_SIZE / 2;
            ballY = HEIGHT / 2 - BALL_SIZE / 2;
            ballXSpeed = -ballXSpeed;
        }
    }

    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.WHITE);

        // Draw paddles
        g.fillRect(0, paddle1Y, PADDLE_WIDTH, PADDLE_HEIGHT);
        g.fillRect(WIDTH - PADDLE_WIDTH, paddle2Y, PADDLE_WIDTH, PADDLE_HEIGHT);

        // Draw ball
        g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);

        // Draw center line
        for (int i = 0; i < HEIGHT; i += 30) {
            g.fillRect(WIDTH / 2 - 5, i, 10, 20);
        }

        Toolkit.getDefaultToolkit().sync();
    }

    public static void main(String[] args) {
        PongGame game = new PongGame();
        game.setVisible(true);

        // Game loop
        while (true) {
            game.moveBall();
            game.repaint();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {}

    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_W:
                movePaddle1Up();
                break;
            case KeyEvent.VK_S:
                movePaddle1Down();
                break;
            case KeyEvent.VK_UP:
                movePaddle2Up();
                break;
            case KeyEvent.VK_DOWN:
                movePaddle2Down();
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {}
}