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.
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
Posting Komentar