Tugas PBO-B
Object Frist with Java : Pong Java
Nama : Hendra Ramadani
NRP : 05111740000055
Kelas : PBO-B
Dikembangkan pada tahun 1972 oleh Atari inc. Game pong merupakan salah satu game arkade pertama. Pada awalnya game ini dibuat sebagai latihan bagi Allan Alcom yang ditugaskan padanya oleh co-founder Atari Nolan Bushnell. Dirilisnya game ini menginspirasi banyak perusahaan game untuk membuat game-game arkade lainnya. Dan pada kesempatan kali ini saya akan mengoding game ini pada IDE BlueJ.
Berikut diagram class pada BlueJ:
Sebelum memulai membuat class-classnya dibuat package "pong" terlebih dahulu. Caranya pada BlueJ klik Edit->New Package ...-> beri nama "pong". Kemudian muncul kotak berwarna ungu pada diagram, klik dua kali kotak tersebut. Setelah itu barulah kita mulai membuat classnya.
Source Code :
- Class Pong
- Class Renderer
- Class Ball
- Class Paddle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pong; | |
import java.awt.BasicStroke; | |
import java.awt.Color; | |
import java.awt.Font; | |
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.Timer; | |
public class Pong implements ActionListener, KeyListener | |
{ | |
public static Pong pong; | |
public int width = 1200, 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, scoreLimit = 7, playerWon; //0 = Menu, 1 = Paused, 2 = Playing, 3 = Over | |
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) | |
{ | |
playerWon = 1; | |
gameStatus = 3; | |
} | |
if (player2.score >= scoreLimit) | |
{ | |
gameStatus = 3; | |
playerWon = 2; | |
} | |
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.GREEN); | |
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); | |
if (!selectingDifficulty) | |
{ | |
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 (selectingDifficulty) | |
{ | |
String string = botDifficulty == 0 ? "Easy" : (botDifficulty == 1 ? "Medium" : "Hard"); | |
g.setFont(new Font("Arial", 1, 30)); | |
g.drawString("<< Bot Difficulty: " + string + " >>", width / 2 - 180, height / 2 - 25); | |
g.drawString("Press Space to Play", width / 2 - 150, height / 2 + 25); | |
} | |
if (gameStatus == 1) | |
{ | |
g.setColor(Color.WHITE); | |
g.setFont(new Font("Arial", 1, 50)); | |
g.drawString("PAUSED", width / 2 - 103, 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 && playerWon == 2) | |
{ | |
g.drawString("The Bot Wins!", width / 2 - 170, 200); | |
} | |
else | |
{ | |
g.drawString("Player " + playerWon + " 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; | |
} | |
else if (id == KeyEvent.VK_S) | |
{ | |
s = true; | |
} | |
else if (id == KeyEvent.VK_UP) | |
{ | |
up = true; | |
} | |
else if (id == KeyEvent.VK_DOWN) | |
{ | |
down = true; | |
} | |
else if (id == KeyEvent.VK_RIGHT) | |
{ | |
if (selectingDifficulty) | |
{ | |
if (botDifficulty < 2) | |
{ | |
botDifficulty++; | |
} | |
else | |
{ | |
botDifficulty = 0; | |
} | |
} | |
else if (gameStatus == 0) | |
{ | |
scoreLimit++; | |
} | |
} | |
else if (id == KeyEvent.VK_LEFT) | |
{ | |
if (selectingDifficulty) | |
{ | |
if (botDifficulty > 0) | |
{ | |
botDifficulty--; | |
} | |
else | |
{ | |
botDifficulty = 2; | |
} | |
} | |
else if (gameStatus == 0 && scoreLimit > 1) | |
{ | |
scoreLimit--; | |
} | |
} | |
else if (id == KeyEvent.VK_ESCAPE && (gameStatus == 2 || gameStatus == 3)) | |
{ | |
gameStatus = 0; | |
} | |
else if (id == KeyEvent.VK_SHIFT && gameStatus == 0) | |
{ | |
bot = true; | |
selectingDifficulty = true; | |
} | |
else 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; | |
} | |
else if (id == KeyEvent.VK_S) | |
{ | |
s = false; | |
} | |
else if (id == KeyEvent.VK_UP) | |
{ | |
up = false; | |
} | |
else if (id == KeyEvent.VK_DOWN) | |
{ | |
down = false; | |
} | |
} | |
@Override | |
public void keyTyped(KeyEvent e) | |
{ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pong; | |
import java.awt.Graphics; | |
import java.awt.Graphics2D; | |
import javax.swing.JPanel; | |
public class Renderer extends JPanel | |
{ | |
private static final long serialVersionUID = 1L; | |
@Override | |
protected void paintComponent(Graphics g) | |
{ | |
super.paintComponent(g); | |
Pong.pong.render((Graphics2D) g); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pong; | |
import java.awt.Color; | |
import java.awt.Graphics; | |
import java.util.Random; | |
public class Ball | |
{ | |
public int x, y, width = 25, height = 25; | |
public int motionX, motionY; | |
public Random random; | |
private 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 (this.x < paddle.x + paddle.width && this.x + width > paddle.x && this.y < paddle.y + paddle.height && this.y + height > paddle.y) | |
{ | |
return 1; //bounce | |
} | |
else if ((paddle.x > x && paddle.paddleNumber == 1) || (paddle.x < x - width && paddle.paddleNumber == 2)) | |
{ | |
return 2; //score | |
} | |
return 0; //nothing | |
} | |
public void render(Graphics g) | |
{ | |
g.setColor(Color.BLACK); | |
g.fillOval(x, y, width, height); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pong; | |
import java.awt.Color; | |
import java.awt.Graphics; | |
public class Paddle | |
{ | |
public int paddleNumber; | |
public int x, y, width = 50, 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; | |
} | |
} | |
} | |
} |
Demonstrasi:
0 komentar:
Posting Komentar