PBO-15 Implementasi Game Pong Java
Laporan mata kuliah Pemrograman Berorientasi Objek (A) - Pertemuan 15
Last updated
Laporan mata kuliah Pemrograman Berorientasi Objek (A) - Pertemuan 15
Last updated
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Pong implements ActionListener, KeyListener {
public static Pong pong;
public int width = 700, height = 700;
public Renderer renderer;
public Paddle player1;
public Paddle player2;
public Ball ball;
public boolean bot = false, selectingDifficulty;
public boolean w, s, up, down;
public int gameStatus = 0;
public int scoreLimit = 7;
public int player1Won = 0;
public int botDifficulty, botMoves, botCooldown = 0;
public Random random;
public JFrame jframe;
public Pong() {
Timer timer = new Timer(20, this);
random = new Random();
jframe = new JFrame("Pong");
renderer = new Renderer();
jframe.setSize(width + 15, height + 35);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.add(renderer);
jframe.addKeyListener(this);
timer.start();
}
public void start() {
gameStatus = 2;
player1 = new Paddle(this, 1);
player2 = new Paddle(this, 2);
ball = new Ball(this);
}
public void update() {
if (player1.score >= scoreLimit) {
player1Won = 1;
gameStatus = 3;
}
if (player2.score >= scoreLimit) {
player1Won = 2;
gameStatus = 3;
}
if (w) player1.move(true);
if (s) player1.move(false);
if (!bot) {
if (up) player2.move(true);
if (down) player2.move(false);
} else {
if (botCooldown > 0) {
botCooldown--;
if (botCooldown == 0) botMoves = 0;
}
if (botMoves < 10) {
if (player2.y + player2.height / 2 < ball.y) {
player2.move(false);
botMoves++;
}
if (player2.y + player2.height / 2 > ball.y) {
player2.move(true);
botMoves++;
}
if (botDifficulty == 0) botCooldown = 20;
if (botDifficulty == 1) botCooldown = 15;
if (botDifficulty == 2) botCooldown = 10;
}
}
ball.update(player1, player2);
}
public void render(Graphics2D g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (gameStatus == 0) {
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", 1, 50));
g.drawString("PONG", width / 2 - 75, 50);
g.setFont(new Font("Arial", 1, 30));
g.drawString("Press Space to Play", width / 2 - 150, height / 2 - 25);
g.drawString("Press Shift to Play with Bot", width / 2 - 200, height / 2 + 25);
g.drawString("<< Score Limit: " + scoreLimit + " >>", width / 2 - 150, height / 2 + 75);
}
if (gameStatus == 1) {
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", 1, 50));
g.drawString("PAUSED", width / 2 - 100, height / 2 - 25);
}
if (gameStatus == 1 || gameStatus == 2) {
g.setColor(Color.WHITE);
g.setStroke(new BasicStroke(5f));
g.drawLine(width / 2, 0, width / 2, height);
g.setStroke(new BasicStroke(2f));
g.drawOval(width / 2 - 150, height / 2 - 150, 300, 300);
g.setFont(new Font("Arial", 1, 50));
g.drawString(String.valueOf(player1.score), width / 2 - 90, 50);
g.drawString(String.valueOf(player2.score), width / 2 + 65, 50);
player1.render(g);
player2.render(g);
ball.render(g);
}
if (gameStatus == 3) {
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", 1, 50));
g.drawString("PONG", width / 2 - 75, 50);
if (bot && player1Won == 2) g.drawString("The Bot Wins!", width / 2 - 170, 200);
else g.drawString("Player " + player1Won + " Wins!", width / 2 - 165, 200);
g.setFont(new Font("Arial", 1, 30));
g.drawString("Press Space to Play Again", width / 2 - 185, height / 2 - 25);
g.drawString("Press ESC for Menu", width / 2 - 140, height / 2 + 25);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (gameStatus == 2) update();
renderer.repaint();
}
public static void main(String[] args) {
pong = new Pong();
}
@Override
public void keyPressed(KeyEvent e) {
int id = e.getKeyCode();
if (id == KeyEvent.VK_W) w = true;
if (id == KeyEvent.VK_S) s = true;
if (id == KeyEvent.VK_UP) up = true;
if (id == KeyEvent.VK_DOWN) down = true;
if (id == KeyEvent.VK_RIGHT) {
if (selectingDifficulty) {
if (botDifficulty < 2) botDifficulty++;
else botDifficulty = 0;
} else if (gameStatus == 0) scoreLimit++;
}
if (id == KeyEvent.VK_LEFT) {
if (selectingDifficulty) {
if (botDifficulty > 0) botDifficulty--;
else botDifficulty = 2;
} else if (gameStatus == 0 && scoreLimit > 1) scoreLimit--;
}
if (id == KeyEvent.VK_ESCAPE && (gameStatus == 2 || gameStatus == 3)) gameStatus = 0;
if (id == KeyEvent.VK_SHIFT && gameStatus == 0) {
bot = true;
selectingDifficulty = true;
}
if (id == KeyEvent.VK_SPACE) {
if (gameStatus == 0 || gameStatus == 3) {
if (!selectingDifficulty) bot = false;
else selectingDifficulty = false;
start();
} else if (gameStatus == 1) gameStatus = 2;
else if (gameStatus == 2) gameStatus = 1;
}
}
@Override
public void keyReleased(KeyEvent e) {
int id = e.getKeyCode();
if (id == KeyEvent.VK_W) w = false;
if (id == KeyEvent.VK_S) s = false;
if (id == KeyEvent.VK_UP) up = false;
if (id == KeyEvent.VK_DOWN) down = false;
}
@Override
public void keyTyped(KeyEvent e) {}
public class Renderer extends JPanel {
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
render((Graphics2D) g);
}
}
public class Paddle {
public int paddleNumber;
public int x, y, width = 25, height = 250;
public int score;
public Paddle(Pong pong, int paddleNumber) {
this.paddleNumber = paddleNumber;
if (paddleNumber == 1) this.x = 0;
if (paddleNumber == 2) this.x = pong.width - width;
this.y = pong.height / 2 - this.height / 2;
}
public void render(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
public void move(boolean up) {
int speed = 15;
if (up) {
if (y - speed > 0) y -= speed;
else y = 0;
} else {
if (y + height + speed < Pong.pong.height) y += speed;
else y = Pong.pong.height - height;
}
}
}
public class Ball {
public int x, y, width = 25, height = 25;
public int motionX, motionY;
public Random random;
public Pong pong;
public int amountOfHits;
public Ball(Pong pong) {
this.pong = pong;
this.random = new Random();
spawn();
}
public void update(Paddle paddle1, Paddle paddle2) {
int speed = 5;
this.x += motionX * speed;
this.y += motionY * speed;
if (this.y + height - motionY > pong.height || this.y + motionY < 0) {
if (this.motionY < 0) {
this.y = 0;
this.motionY = random.nextInt(4);
if (motionY == 0) motionY = 1;
} else {
this.motionY = -random.nextInt(4);
this.y = pong.height - height;
if (motionY == 0) motionY = -1;
}
}
if (checkCollision(paddle1) == 1) {
this.motionX = 1 + (amountOfHits / 5);
this.motionY = -2 + random.nextInt(4);
if (motionY == 0) motionY = 1;
amountOfHits++;
} else if (checkCollision(paddle2) == 1) {
this.motionX = -1 - (amountOfHits / 5);
this.motionY = -2 + random.nextInt(4);
if (motionY == 0) motionY = 1;
amountOfHits++;
}
if (checkCollision(paddle1) == 2) {
paddle2.score++;
spawn();
} else if (checkCollision(paddle2) == 2) {
paddle1.score++;
spawn();
}
}
public void spawn() {
this.amountOfHits = 0;
this.x = pong.width / 2 - this.width / 2;
this.y = pong.height / 2 - this.height / 2;
this.motionY = -2 + random.nextInt(4);
if (motionY == 0) motionY = 1;
if (random.nextBoolean()) motionX = 1;
else motionX = -1;
}
public int checkCollision(Paddle paddle) {
if (paddle.paddleNumber == 1) {
if (x < paddle.x + paddle.width && y < paddle.y + paddle.height && y > paddle.y) return 1;
else if (x < paddle.x + paddle.width && y > paddle.y + paddle.height) return 2;
else if (x < paddle.x + paddle.width && y < paddle.y) return 2;
} else if (paddle.paddleNumber == 2) {
if (x + width > paddle.x && y < paddle.y + paddle.height && y > paddle.y) return 1;
else if (x + width > paddle.x && y > paddle.y + paddle.height) return 2;
else if (x + width > paddle.x && y < paddle.y) return 2;
}
return 0;
}
public void render(Graphics g) {
g.setColor(Color.WHITE);
g.fillOval(x, y, width, height);
}
}
}