PBO 14

   muhammad rafi budi purnama

5025221307

PBO 14

Implementasi Game Pong

Pada penugasan kali ini, kita akan menerapkan konsep GUI lanjutan dari yang berupa GUI login sederhana menjadi game pong.


Gambar diatas adalah hasil dari implementasi dari kode berikut.

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

// Main class untuk menjalankan game
public class PongGame {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Pong Game");
                GamePanel gamePanel = new GamePanel();
                frame.add(gamePanel);
                frame.setSize(800, 600);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setResizable(false);
                frame.setVisible(true);
            }
        });
    }
}

// Panel game utama
class GamePanel extends JPanel implements Runnable, KeyListener {
    // Dimensi game
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;
    
    // Objek game
    private Paddle player1;
    private Paddle player2;
    private Ball ball;
    
    // Thread untuk game loop
    private Thread gameThread;
    private boolean running = false;
    
    // Skor
    private int scorePlayer1 = 0;
    private int scorePlayer2 = 0;
    
    // Status game
    private boolean gameStarted = false;
    
    public GamePanel() {
        setBackground(Color.BLACK);
        setFocusable(true);
        addKeyListener(this);
        
        // Inisialisasi objek game
        player1 = new Paddle(30, HEIGHT / 2 - 50, 15, 100, Color.WHITE);
        player2 = new Paddle(WIDTH - 45, HEIGHT / 2 - 50, 15, 100, Color.WHITE);
        ball = new Ball(WIDTH / 2 - 10, HEIGHT / 2 - 10, 20, 20);
        
        // Mulai game loop
        startGame();
    }
    
    private void startGame() {
        running = true;
        gameThread = new Thread(this);
        gameThread.start();
    }
    
    @Override
    public void run() {
        long lastTime = System.nanoTime();
        double nsPerTick = 1000000000.0 / 60.0; // 60 FPS
        double delta = 0;
        
        while (running) {
            long now = System.nanoTime();
            delta += (now - lastTime) / nsPerTick;
            lastTime = now;
            
            if (delta >= 1) {
                update();
                repaint();
                delta--;
            }
        }
    }
    
    private void update() {
        if (!gameStarted) return;
        
        // Update posisi paddle
        player1.update(HEIGHT);
        player2.update(HEIGHT);
        
        // Update posisi bola
        ball.update();
        
        // Cek tabrakan dengan dinding atas/bawah
        if (ball.y <= 0 || ball.y + ball.height >= HEIGHT) {
            ball.dy = -ball.dy;
        }
        
        // Cek tabrakan dengan paddle player 1
        if (ball.getBounds().intersects(player1.getBounds())) {
            ball.dx = Math.abs(ball.dx); // Pastikan bola bergerak ke kanan
            ball.dx += 0.5; // Tambah kecepatan sedikit
        }
        
        // Cek tabrakan dengan paddle player 2
        if (ball.getBounds().intersects(player2.getBounds())) {
            ball.dx = -Math.abs(ball.dx); // Pastikan bola bergerak ke kiri
            ball.dx -= 0.5; // Tambah kecepatan sedikit
        }
        
        // Cek jika bola keluar (scoring)
        if (ball.x <= 0) {
            scorePlayer2++;
            resetBall();
        } else if (ball.x + ball.width >= WIDTH) {
            scorePlayer1++;
            resetBall();
        }
    }
    
    private void resetBall() {
        ball.x = WIDTH / 2 - 10;
        ball.y = HEIGHT / 2 - 10;
        ball.dx = (Math.random() > 0.5) ? 5 : -5;
        ball.dy = (Math.random() * 4) - 2;
        gameStarted = false;
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        // Gambar garis tengah
        g2d.setColor(Color.WHITE);
        for (int i = 0; i < HEIGHT; i += 20) {
            g2d.fillRect(WIDTH / 2 - 2, i, 4, 10);
        }
        
        // Gambar paddle dan bola
        player1.draw(g2d);
        player2.draw(g2d);
        ball.draw(g2d);
        
        // Gambar skor
        g2d.setFont(new Font("Arial", Font.BOLD, 48));
        g2d.drawString(String.valueOf(scorePlayer1), WIDTH / 2 - 100, 60);
        g2d.drawString(String.valueOf(scorePlayer2), WIDTH / 2 + 80, 60);
        
        // Instruksi
        if (!gameStarted) {
            g2d.setFont(new Font("Arial", Font.BOLD, 20));
            String msg = "Tekan SPASI untuk mulai";
            int msgWidth = g2d.getFontMetrics().stringWidth(msg);
            g2d.drawString(msg, WIDTH / 2 - msgWidth / 2, HEIGHT - 50);
        }
        
        // Kontrol instruksi
        g2d.setFont(new Font("Arial", Font.PLAIN, 14));
        g2d.drawString("Player 1: W/S", 10, HEIGHT - 30);
        g2d.drawString("Player 2: ↑/↓", WIDTH - 120, HEIGHT - 30);
    }
    
    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        
        // Player 1 controls (W/S)
        if (key == KeyEvent.VK_W) {
            player1.setMovingUp(true);
        } else if (key == KeyEvent.VK_S) {
            player1.setMovingDown(true);
        }
        
        // Player 2 controls (Arrow keys)
        if (key == KeyEvent.VK_UP) {
            player2.setMovingUp(true);
        } else if (key == KeyEvent.VK_DOWN) {
            player2.setMovingDown(true);
        }
        
        // Start game
        if (key == KeyEvent.VK_SPACE && !gameStarted) {
            gameStarted = true;
        }
    }
    
    @Override
    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
        
        // Player 1
        if (key == KeyEvent.VK_W) {
            player1.setMovingUp(false);
        } else if (key == KeyEvent.VK_S) {
            player1.setMovingDown(false);
        }
        
        // Player 2
        if (key == KeyEvent.VK_UP) {
            player2.setMovingUp(false);
        } else if (key == KeyEvent.VK_DOWN) {
            player2.setMovingDown(false);
        }
    }
    
    @Override
    public void keyTyped(KeyEvent e) {}
}

// Class untuk Paddle (raket)
class Paddle {
    int x, y, width, height;
    Color color;
    private boolean movingUp = false;
    private boolean movingDown = false;
    private int speed = 7;
    
    public Paddle(int x, int y, int width, int height, Color color) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.color = color;
    }
    
    public void update(int screenHeight) {
        if (movingUp && y > 0) {
            y -= speed;
        }
        if (movingDown && y + height < screenHeight) {
            y += speed;
        }
    }
    
    public void draw(Graphics2D g) {
        g.setColor(color);
        g.fillRect(x, y, width, height);
    }
    
    public Rectangle getBounds() {
        return new Rectangle(x, y, width, height);
    }
    
    public void setMovingUp(boolean moving) {
        this.movingUp = moving;
    }
    
    public void setMovingDown(boolean moving) {
        this.movingDown = moving;
    }
}

// Class untuk Ball (bola)
class Ball {
    int x, y, width, height;
    double dx = 5;
    double dy = 2;
    
    public Ball(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }
    
    public void update() {
        x += dx;
        y += dy;
    }
    
    public void draw(Graphics2D g) {
        g.setColor(Color.WHITE);
        g.fillOval(x, y, width, height);
    }
    
    public Rectangle getBounds() {
        return new Rectangle(x, y, width, height);
    }
}

Komentar

Postingan populer dari blog ini

TUGAS 2 : Jettpack compose : Hello, World!

Pertemuan 3 PPB (A) - Mengenal Composable Aplikasi Selamat Ulang Tahun

Pertemuan 5 - Aplikasi Kalkulator Sederhana