Mecoba Game Pong dengan BlueJ
Mencoba game Pong dengan BlueJ
Oke teman teman kali ini saya mendapat tugas untuk mencoba game pong didalam aplikasi blueJ. Langsung saja saya jelaskan apa itu game pong. Game Pong merupakan game sejenis tenis meja. dalam game Pong ini terdapat beberapa Class yaitu :
1. Class Pong yang merupakan main dari game Pong ini.
2. Class Paddle yang merupakan class untuk objek paddle dalam game Pong dan memiliki fungsi untuk merubah warna ukuran dan sebagainya yang terdapat pada Paddle.
3. Class Ball yang berfungsi untuk membentuk bola, mengatur warna bola dan sebagainya.
4. Class Renderer yang berfungsi untuk menjadi tampilan dasar grafik pada game Pong.
Berikut Abstraksi class-class yang terdapat pada game Pong;
Untuk Source Code nya sebagai berikut:
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
/** | |
* Class yang merupakan dari main permainan pong. | |
* | |
* @author Abdun Nafi' | |
* @version 0.1 | |
*/ | |
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 = 700, height = 700; //mengatur lebar panel | |
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); //Warna dari panel | |
g.fillRect(0, 0, width, height); | |
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | |
if (gameStatus == 0) | |
{ | |
g.setColor(Color.WHITE); // warna dari game status | |
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) | |
{ | |
} | |
} |
2. 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
/** | |
* Class Paddle berfungsi untuk paddle dari permainan pong, bisa merubah dari warna,ukuran paddle | |
* dan sebagainya. | |
* | |
* @author Abdun Nafi' | |
* @version 0.1 | |
*/ | |
import java.awt.Color; | |
import java.awt.Graphics; | |
public class Paddle | |
{ | |
public int paddleNumber; | |
public int x, y, width = 30, height = 150; //mengatur ukuran paddle | |
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.BLACK); // warna dari paddle | |
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; | |
} | |
} | |
} | |
} |
3. Ball
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
/** | |
* Class ini akan membentuk bola dalam permainan pong yang mengatur warna , | |
* pergerakan dan ukuran bola dan sebagainya. | |
* | |
* | |
* @author Abdun Nafi' | |
* @version 0.1 | |
*/ | |
import java.awt.Color; | |
import java.awt.Graphics; | |
import java.util.Random; | |
public class Ball | |
{ | |
public int x, y, width = 25, height = 25;// ukuran dari bola | |
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.ORANGE);// menjadi warna dari bola | |
g.fillOval(x, y, width, height); | |
} | |
} |
4. Renderer
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
/** | |
* Class yang menjadi dasar dari panel | |
* | |
* @author Abdun Nafi' | |
* @version 0.1 | |
*/ | |
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); | |
} | |
} |
Untuk menjalankan Game Pong tersebut kita hanya perlu Klik kanan Pada Class Pong dan Pilih Fungsi Main dari class Pong.
Untuk Output Game yang telah saya coba sebagai berikut :
1. Tampilan Awal
Untuk bermain kita harus menekan tombol Space.
2. Tampilan saat bermain
tampilan ini telah saya rubah untuk warna paddle, warna panel dan bola.
3. Tampilan saat di PAUSE dengan menekan tombol space.
Komentar
Posting Komentar