Minggu, 10 Desember 2017

PBO: osu! Catch The Beat Java Based (Final Project)


Untuk final project pemrograman berbasis objek, saya terinspirasi untuk membuat sebuah game setelah bermain game bernama osu!Catch the Beat. Saya ingin membuat game seperti itu namun menggunakan bahasa pemrograman java.

Potongan gambar dari osu! Catch the Beat yang asli:

Dengan pemrograman java seadanya saya berhasil membuat remake game ini namun dengan fitur yang lebih sedikit dari yang aslinya.

Program osu!ctb yang saya buat memiliki fitur basic yaitu menangkap buah yang jatuh dan permainan akan selesai setelah semua buah ditangkap.

Potongan gambar dari osu!ctb yang saya buat:

Class Schema untuk pemrograman osu!ctb ini adalah sebagai berikut:
  • frame
    •  class ini berfungsi untuk menggenerate frame yang digunakan untuk menjalankan permainan.
  • background
    • class ini merupakan motor utama game ini. class ini memiliki banyak fungsi salah satunya memanggil buah dan membuat ryu(alat penangkap buahnya). Selain itu background juga mengecek tabrakan antara ryu dan buah.
  • control
    • class ini berfungsi untuk mengatur gerakan dari ryu dan juga mengatur laju dari hasil inputan keyboard.
  • buah
    • class ini berfungsi untuk mengatur segala hal mengenai buah seperti laju turunnya buah dan menggenerate buahnya


Link github kodingan saya: osu!ctb
Link download program in jar: here 

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class background extends JPanel implements ActionListener {
private Timer timer;
private control buah;
private ArrayList fruits;
private boolean ingame;
private int B_WIDTH;
private int B_HEIGHT;
AudioClip soundTrack;
AudioClip sound;
Image gambar;
private Image back;
private int[][] pos = {
{89,-30}, {29,-90}, {59,-120},
{109,-280}, {259,-390}, {150,-590},
{170,-490}, {70,-510}, {60,-530},
{90,-540}, {45,-560}, {139,-580},
{80,-590}, {50,-660}, {239,-680},
{30,-700}, {180,-740}, {50,-760},
{109,-780}, {259,-790}, {150,-790},
{220,-810}, {128,-820}, {20,-860},
{259,-900}, {200,-920}, {159,-930},
{59,-940}, {209,-980}, {30,-990},
{89,-1380}, {29,-1680}, {59,-2000}
};
public background() {
addKeyListener(new TAdapter());
setFocusable(true);
setBackground(Color.black);
setDoubleBuffered(true);
ingame = true;
setSize(400,400);
buah = new control();
initFruits();
soundTrack=Applet.newAudioClip(getClass().getResource("backsound.wav"));
soundTrack.loop();
timer = new Timer(20, this);
timer.start();
}
@Override
public void addNotify() {
super.addNotify();
B_WIDTH = getWidth();
B_HEIGHT = getHeight();
}
public final void initFruits() {
fruits = new ArrayList();
for (int i=0; i<pos.length; i++ ) {
fruits.add(new buah(pos[i][0], pos[i][1]));
}
}
public static Image loadImage(String fileName) {
ImageIcon icon = new ImageIcon(fileName);
return icon.getImage();
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (ingame) {
Graphics2D g2d = (Graphics2D)g;
if (buah.isVisible()) {
g2d.drawImage(buah.getImage(), buah.getX(), buah.getY(),this);
}
for (int i = 0; i < fruits.size(); i++) {
buah a = (buah)fruits.get(i);
if (a.isVisible()) {
g2d.drawImage(a.getImage(), a.getX(), a.getY(), this);
}
}
g2d.setColor(Color.red);
g2d.drawString("Target Buah: " + fruits.size(), 5, 15);
} else {
String msg = "Permainan Selesai";
Font small = new Font("Helvetica", Font.BOLD, 30);
FontMetrics metr = this.getFontMetrics(small);
g.setColor(Color.red);
g.setFont(small);
g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) /2, B_HEIGHT /2);
}
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
@Override
public void actionPerformed(ActionEvent e) {
if (fruits.isEmpty()) {
ingame = false;
}
for (int i = 0; i < fruits.size(); i++) {
buah a = (buah) fruits.get(i);
if (a.isVisible()) {
a.move();
}
else {
fruits.remove(i);
}
}
buah.move();
checkCollisions();
repaint();
}
public void checkCollisions() {
Rectangle r3 = buah.getBounds();
for (int j = 0; j<fruits.size(); j++) {
buah a = (buah) fruits.get(j);
Rectangle r2 = a.getBounds();
if (r3.intersects(r2)) {
a.setVisible(false);
sound = Applet.newAudioClip(getClass().getResource("soft-slidertick.wav"));
sound.play();
}
}
}
private class TAdapter extends KeyAdapter {
@Override
public void keyReleased(KeyEvent e) {
buah.keyReleased(e);
}
@Override
public void keyPressed(KeyEvent e) {
buah.keyPressed(e);
}
}
}
view raw background.java hosted with ❤ by GitHub
import java.awt.Image;
import java.awt.Rectangle;
import javax.swing.ImageIcon;
public class buah {
private int x;
private int y;
private int width;
private int height;
private boolean visible;
private Image image;
public buah(int x, int y) {
ImageIcon ii = new ImageIcon(this.getClass().getResource("banana.png"));
image = ii.getImage();
width = image.getWidth(null);
height = image.getHeight(null);
visible = true;
this.x = x;
this.y = y;
}
public void move() {
if (y > 400) {
y = 0;
}
y += 1;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public boolean isVisible() {
return visible;
}
public void setVisible(Boolean visible) {
this.visible = visible;
}
public Image getImage() {
return image;
}
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
}
view raw buah.java hosted with ❤ by GitHub
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class control {
private int dx;
private int dy;
private int x;
private int y;
private int width;
private int height;
private boolean visible;
private Image image;
public control() {
ImageIcon ii = new ImageIcon(this.getClass().getResource("ryu.png"));
image = ii.getImage();
width = image.getWidth(null);
height = image.getHeight(null);
visible = true;
x = 40;
y = 340;
}
public void move() {
x += dx;
if (x < 1) {
x = 1;
}
if(x > 355){
x = 355;
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return image;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public boolean isVisible() {
return visible;
}
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = -5;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 5;
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = 0;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 0;
}
}
}
view raw control.java hosted with ❤ by GitHub
import java.awt.Component;
import javax.swing.JFrame;
public class frame extends JFrame {
public frame() {
Component add;
add = add(new background());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,400);
setLocationRelativeTo(null);
setTitle("CTB in Java");
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
frame frame = new frame();
}
}
view raw frame.java hosted with ❤ by GitHub

PBO: Pemrograman GUI





Jumat, 01 Desember 2017

PBO: Pong

Hasil Codingan:

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.WHITE);
g.fillOval(x, y, width, height);
}
}
view raw ball.java hosted with ❤ by GitHub
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;
}
}
}
}
view raw paddle.java hosted with ❤ by GitHub
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 = 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, 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.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);
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)
{
}
}
view raw pong.java hosted with ❤ by GitHub
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);
}
}
view raw renderer.java hosted with ❤ by GitHub

Potongan Gambar: