Pertemuan 14 – Game Pong Java

Game Pong Java merupakan sebuah permainan klasik dua pemain yang dikembangkan menggunakan bahasa pemrograman Java dengan library Swing untuk antarmuka grafis. Permainan ini mengadopsi konsep dasar game Pong, di mana dua pemain mengendalikan paddle untuk memantulkan bola dan mencegah bola melewati area pertahanan masing-masing.

Tujuan utama dari permainan ini adalah mencetak skor sebanyak mungkin dengan cara membuat bola melewati paddle lawan. Setiap kali bola keluar dari batas layar di sisi kiri atau kanan, pemain lawan akan mendapatkan satu poin. Skor ditampilkan secara real-time pada bagian atas layar sehingga pemain dapat memantau jalannya pertandingan.

Project ini dirancang sebagai latihan penerapan Object-Oriented Programming (OOP), event handling, serta animasi sederhana dalam aplikasi desktop Java.


Fitur Game Pong Java

  1. Dua Pemain (Multiplayer Lokal)
    Permainan dapat dimainkan oleh dua pemain pada satu keyboard.
    • Pemain kiri menggunakan tombol W (atas) dan S (bawah).
    • Pemain kanan menggunakan tombol dan .
  2. Pergerakan Bola Otomatis
    Bola bergerak secara otomatis menggunakan mekanisme Timer, sehingga menghasilkan animasi yang halus dan konsisten.
  3. Sistem Skor
    Setiap pemain memperoleh skor ketika lawan gagal memantulkan bola. Skor ditampilkan di layar dan akan terus bertambah selama permainan berlangsung.
  4. Deteksi Tabrakan (Collision Detection)
    Sistem mendeteksi tabrakan antara bola dengan paddle serta dinding atas dan bawah, sehingga bola dapat memantul secara realistis.
  5. Reset Bola Otomatis
    Setelah terjadi penambahan skor, bola akan kembali ke posisi tengah untuk melanjutkan permainan tanpa harus me-restart aplikasi.
  6. Antarmuka Grafis Sederhana dan Responsif
    Tampilan game dibuat sederhana dengan warna kontras agar mudah dimainkan dan dipahami oleh pengguna.

Code Program dan Output

Code Program :

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

public class PongGame extends JPanel implements ActionListener, KeyListener {

    private final int WIDTH = 800;
    private final int HEIGHT = 500;

    // Bola
    private int ballX = 400, ballY = 250;
    private int ballDX = 3, ballDY = 3;
    private final int BALL_SIZE = 15;

    // Paddle
    private int paddleLeftY = 200;
    private int paddleRightY = 200;
    private final int PADDLE_WIDTH = 10;
    private final int PADDLE_HEIGHT = 80;

    // Skor
    private int scoreLeft = 0;
    private int scoreRight = 0;

    private Timer timer;

    public PongGame() {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setBackground(Color.BLACK);
        setFocusable(true);
        addKeyListener(this);

        timer = new Timer(10, this);
        timer.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setColor(Color.WHITE);

        // Bola
        g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);

        // Paddle
        g.fillRect(30, paddleLeftY, PADDLE_WIDTH, PADDLE_HEIGHT);
        g.fillRect(WIDTH - 40, paddleRightY, PADDLE_WIDTH, PADDLE_HEIGHT);

        // Garis tengah
        g.drawLine(WIDTH / 2, 0, WIDTH / 2, HEIGHT);

        // Skor
        g.setFont(new Font("Arial", Font.BOLD, 30));
        g.drawString(String.valueOf(scoreLeft), WIDTH / 2 - 60, 40);
        g.drawString(String.valueOf(scoreRight), WIDTH / 2 + 40, 40);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        ballX += ballDX;
        ballY += ballDY;

        // Pantul atas & bawah
        if (ballY <= 0 || ballY >= HEIGHT - BALL_SIZE) {
            ballDY *= -1;
        }

        // Paddle kiri
        if (ballX <= 40 &&
            ballY + BALL_SIZE >= paddleLeftY &&
            ballY <= paddleLeftY + PADDLE_HEIGHT) {
            ballDX *= -1;
        }

        // Paddle kanan
        if (ballX >= WIDTH - 55 &&
            ballY + BALL_SIZE >= paddleRightY &&
            ballY <= paddleRightY + PADDLE_HEIGHT) {
            ballDX *= -1;
        }

        // Skor
        if (ballX < 0) {
            scoreRight++;
            resetBall();
        }

        if (ballX > WIDTH) {
            scoreLeft++;
            resetBall();
        }

        repaint();
    }

    private void resetBall() {
        ballX = WIDTH / 2;
        ballY = HEIGHT / 2;
        ballDX = -ballDX;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_W && paddleLeftY > 0)
            paddleLeftY -= 20;

        if (key == KeyEvent.VK_S && paddleLeftY < HEIGHT - PADDLE_HEIGHT)
            paddleLeftY += 20;

        if (key == KeyEvent.VK_UP && paddleRightY > 0)
            paddleRightY -= 20;

        if (key == KeyEvent.VK_DOWN && paddleRightY < HEIGHT - PADDLE_HEIGHT)
            paddleRightY += 20;
    }

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

    public static void main(String[] args) {
        JFrame frame = new JFrame("Game Pong Java - With Score");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.add(new PongGame());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Output :

Simulasi :

Penjelasan Alur dan Struktur Kode

1. Struktur Kelas

Seluruh logika permainan ditempatkan dalam satu kelas utama yang mewarisi JPanel dan mengimplementasikan beberapa interface seperti:

  • ActionListener untuk mengatur pergerakan bola
  • KeyListener untuk menangani input keyboard pemain

Pendekatan ini memudahkan pengelolaan logika game dan tampilan dalam satu kesatuan.


2. Variabel dan Atribut

Kode menggunakan beberapa variabel utama untuk menyimpan:

  • Posisi dan kecepatan bola
  • Posisi paddle kiri dan kanan
  • Ukuran layar, paddle, dan bola
  • Skor masing-masing pemain

Variabel-variabel ini berperan penting dalam mengatur logika pergerakan dan interaksi antar objek dalam permainan.


3. Metode paintComponent()

Metode ini digunakan untuk:

  • Menggambar bola dan paddle
  • Menampilkan garis tengah lapangan
  • Menampilkan skor pemain

Setiap perubahan posisi akan diikuti dengan pemanggilan ulang metode ini agar tampilan selalu diperbarui.


4. Pergerakan dan Logika Game

Logika pergerakan bola dan pengecekan tabrakan dijalankan di dalam metode actionPerformed(), yang dipanggil secara berkala oleh Timer.
Di dalam metode ini juga dilakukan:

  • Pantulan bola pada dinding
  • Deteksi tabrakan dengan paddle
  • Pengecekan kondisi skor

5. Input Keyboard

Input dari keyboard diproses menggunakan metode keyPressed(). Setiap tombol yang ditekan akan mengubah posisi paddle sesuai dengan pemain yang mengendalikan.


6. Reset dan Skor

Ketika bola melewati batas kiri atau kanan layar:

  • Skor pemain lawan akan bertambah
  • Bola dikembalikan ke posisi tengah
  • Permainan langsung berlanjut

Kesimpulan

Game Pong Java ini merupakan project yang efektif untuk memahami konsep dasar pengembangan game sederhana menggunakan Java. Melalui project ini, pengembang dapat mempelajari penerapan GUI, event handling, animasi, serta logika permainan dalam satu aplikasi yang interaktif. Project ini juga dapat dikembangkan lebih lanjut dengan menambahkan fitur seperti AI, level kesulitan, atau efek suara.