Oca 15

Java’da Breakout Oyunu Yapımı

breakoutgame

Hemen hemen herkes oynamıştır bu oyunu. Ancak ismi yabancı gelebilir. Yine de kısaca bahsetmekte fayda var. Bu oyunda Aşağıdaki tahta üzerinden seken top ile yukarıdaki priketleri kırmaya çalışıyorsunuz. Topu aşağı düşürmemektir amaç. Topu aşağı düşürdüğünüzde yenilirsiniz. Priketleri bitirirseniz de siz yenersiniz. Top sürekli hareket halindedir. Tahtayı sağa sola (x ekseninde) hareket ettirerek topun tahtaya denk gelip sekmesini sağlarsınız. Proje alıntıdır. Proje içersindeki paddle görseli, top görseli ve priket görseli bana aittir. Kodları alıp class yapısını oluşturdum ve projeyi çalışır hale getirdim. Bu yazımda hangi kodun ne işe yaradığını ne yaptığını açıklayacağım. Projenin class yapısı görseldeki gibidir.

breakoutgamefiles

Ball.java//topla ilgili işlemler

package breakout;
import javax.swing.ImageIcon;
/**
*
* @author Eren
*/
public class Ball extends Sprite implements Commons {
private int xdir;
private int ydir;

protected String ball = “ball.png”;

public Ball() {
xdir = 1;
ydir = -1;
ImageIcon ii = new ImageIcon(this.getClass().getResource(ball));
image = ii.getImage();
width = image.getWidth(null);
heigth = image.getHeight(null);
resetState();
}

public void move()//topun hareketi
{
x += xdir;
y += ydir;

if (x == 0) {
setXDir(1);
}

if (x == BALL_RIGHT) {
setXDir(-1);
}

if (y == 0) {
setYDir(1);
}
}

public void resetState()
{
x = 230;
y = 355;
}

public void setXDir(int x)
{
xdir = x;
}

public void setYDir(int y)
{
ydir = y;
}

public int getYDir()
{
return ydir;
}
}

Board.java

package breakout;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JPanel;
/**
*
* @author Eren
*/
public class Board extends JPanel implements Commons{
Image ii;//Image
Timer timer;//Zamanlayıcı
String message = “Game Over”;
Ball ball;//Top
Paddle paddle;//Tahta
Brick bricks[];//Priketler

boolean ingame = true;//oyun içinde
int timerId;//timer idsi

public Board() {//Asıl işlerin yürüdüğü class burasıdır.
addKeyListener(new TAdapter());//Tuşa basılma olayını dinle
setFocusable(true);//Odaklanabilir

bricks = new Brick[30];//30 tane briket oluştur
setDoubleBuffered(true);//
timer = new Timer();//zamanlayıcı oluştur
timer.scheduleAtFixedRate(new ScheduleTask(), 1000, 10);
}

public void addNotify() {
super.addNotify();
gameInit();
}

public void gameInit() {

ball = new Ball();
paddle = new Paddle();
int k = 0;

//5*6’lık dizi mantığıyla priketleri oluşturma
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 6; j++) {
bricks[k] = new Brick(j * 40 + 30, i * 10 + 50);
k++;
}
}
}
public void paint(Graphics g) {
super.paint(g);
if (ingame) {
g.drawImage(ball.getImage(), ball.getX(), ball.getY(),
ball.getWidth(), ball.getHeight(), this);
g.drawImage(paddle.getImage(), paddle.getX(), paddle.getY(),
paddle.getWidth(), paddle.getHeight(), this);

for (int i = 0; i < 30; i++) {
if (!bricks[i].isDestroyed())
g.drawImage(bricks[i].getImage(), bricks[i].getX(),
bricks[i].getY(), bricks[i].getWidth(),
bricks[i].getHeight(), this);
}
} else {

Font font = new Font(“Verdana”, Font.BOLD, 18);
FontMetrics metr = this.getFontMetrics(font);

g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(message,
(Commons.WIDTH – metr.stringWidth(message)) / 2,
Commons.WIDTH / 2);
}
Toolkit.getDefaultToolkit().sync();
g.dispose();
}

private class TAdapter extends KeyAdapter {//tuş algılamaları

public void keyReleased(KeyEvent e) {
paddle.keyReleased(e);
}

public void keyPressed(KeyEvent e) {
paddle.keyPressed(e);
}
}
class ScheduleTask extends TimerTask {

public void run() {
//çalıştır 10 ms’de bir burası tetiklenir. 10 ms’de bir topun x ve ye de bir derece ilerlemesi sağlanır. Hareketin canlılığın sağlandığı fonksiyonların 10 ms’de bir çağırıldığı, çalıştırıldığı fonksiyon buradadır.
ball.move();
paddle.move();
checkCollision();
repaint();

}
}

public void stopGame() {//oyunu durdurma fonksiyonu
ingame = false;
timer.cancel();
}
public void checkCollision() {
//Olay burda Tüm hareketler topun sürekli hareketi burdan sağlanır
if (ball.getRect().getMaxY() > Commons.BOTTOM) {
stopGame();//alt kısıma geldiyse Burda Gol olduysa player sayacını artır
}

for (int i = 0, j = 0; i < 30; i++) {
if (bricks[i].isDestroyed()) {
j++;//Parçalanan piriketleri saydık
}
if (j == 30) {
message = “Victory”;//hepsi parçalandıysa KAZANDIK
stopGame();
}
}

if ((ball.getRect()).intersects(paddle.getRect())) {

int paddleLPos = (int)paddle.getRect().getMinX();
int ballLPos = (int)ball.getRect().getMinX();

int first = paddleLPos + 8;
int second = paddleLPos + 16;
int third = paddleLPos + 24;
int fourth = paddleLPos + 32;

if (ballLPos < first) {
ball.setXDir(-1);
ball.setYDir(-1);
}

if (ballLPos >= first && ballLPos < second) {
ball.setXDir(-1);
ball.setYDir(-1 * ball.getYDir());
}

if (ballLPos >= second && ballLPos < third) {
ball.setXDir(0);
ball.setYDir(-1);
}

if (ballLPos >= third && ballLPos < fourth) {
ball.setXDir(1);
ball.setYDir(-1 * ball.getYDir());
}

if (ballLPos > fourth) {
ball.setXDir(1);
ball.setYDir(-1);
}
}
for (int i = 0; i < 30; i++) {
if ((ball.getRect()).intersects(bricks[i].getRect())) {

int ballLeft = (int)ball.getRect().getMinX();
int ballHeight = (int)ball.getRect().getHeight();
int ballWidth = (int)ball.getRect().getWidth();
int ballTop = (int)ball.getRect().getMinY();

Point pointRight = new Point(ballLeft + ballWidth + 1, ballTop);
Point pointLeft = new Point(ballLeft – 1, ballTop);
Point pointTop = new Point(ballLeft, ballTop – 1);
Point pointBottom = new Point(ballLeft, ballTop + ballHeight + 1);

if (!bricks[i].isDestroyed()) {
if (bricks[i].getRect().contains(pointRight)) {
ball.setXDir(-1);
}

else if (bricks[i].getRect().contains(pointLeft)) {
ball.setXDir(1);
}

if (bricks[i].getRect().contains(pointTop)) {
ball.setYDir(1);
}

else if (bricks[i].getRect().contains(pointBottom)) {
ball.setYDir(-1);
}

bricks[i].setDestroyed(true);
}
}
}
}

}

Breakout.Java //Ana class

package breakout;
import javax.swing.JFrame;
/**
*
* @author Eren
*/
public class Breakout extends JFrame{

public Breakout()//ana class yapılandırıcısı. Applet’e ilişkin ayarlamalar
{
add(new Board());
setTitle(“Breakout”);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(Commons.WIDTH, Commons.HEIGTH);
setLocationRelativeTo(null);
setIgnoreRepaint(true);
setResizable(true);
setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Breakout();
}
}

Brick.java//priket

package breakout;
import javax.swing.ImageIcon;
/**
*
* @author Eren
*/
public class Brick extends Sprite{
String brickie = “brickie.png”;
boolean destroyed;
//Parçalandı
public Brick(int x, int y) {
this.x = x;
this.y = y;

ImageIcon ii = new ImageIcon(this.getClass().getResource(brickie));
image = ii.getImage();

width = image.getWidth(null);
heigth = image.getHeight(null);

destroyed = false;
//Parçalanmadı
}

public boolean isDestroyed()
{
//Parçalandı mı ?
return destroyed;
}

public void setDestroyed(boolean destroyed)
{
this.destroyed = destroyed;//Destroyed yapılandırıcısı
}

}

Commons.java

package breakout;

/**
*
* @author Eren
*/
public interface Commons//en boy boyut sağdan boşluk topun sınırları gibi verilerin tanımlı olduğu class {
public static final int WIDTH = 500;
public static final int HEIGTH = 800;
public static final int BOTTOM = 400;
public static final int PADDLE_RIGHT = 230;
public static final int PADDLE_LEFT=180;
public static final int BALL_RIGHT = 280;
}

Paddle.java//Tahta

package breakout;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;

/**
*
* @author Eren
*/
public class Paddle extends Sprite implements Commons{
String paddle = “paddle.png”;//??
int dx;

public Paddle() // tahtanın yapılandırıcısı{
ImageIcon ii = new ImageIcon(this.getClass().getResource(paddle));
image = ii.getImage();

width = image.getWidth(null);
heigth = image.getHeight(null);

resetState();

}

public void move()//Tahtanın hareketlerinin tanımlı olduğu fonksiyon{
x += dx;
if (x <= 2)
x = 2;
if (x >= Commons.PADDLE_RIGHT)
x = Commons.PADDLE_RIGHT;
if(x>=Commons.PADDLE_LEFT)
x=Commons.PADDLE_LEFT;

}

public void keyPressed(KeyEvent e) {

int key = e.getKeyCode();

if (key == KeyEvent.VK_LEFT) {
dx = -2;

}

if (key == KeyEvent.VK_RIGHT) {
dx = 2;
}
}

public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();

if (key == KeyEvent.VK_LEFT) {
dx = 0;
}

if (key == KeyEvent.VK_RIGHT) {
dx = 0;
}
}

public void resetState() {
x = 200;
y = 360;
}
}

Sprite.java//nesnelere yönelik en boy çap bilgileri

package breakout;
import java.awt.Image;
import java.awt.Rectangle;
/**
*
* @author Eren
*/
public class Sprite {
protected int x;
protected int y;
protected int width;
protected int heigth;
protected Image image;
public void setX(int x) {
this.x = x;
}

public int getX() {
return x;
}

public void setY(int y) {
this.y = y;
}

public int getY() {
return y;
}

public int getWidth() {
return width;
}

public int getHeight() {
return heigth;
}

Image getImage()
{
return image;
}

Rectangle getRect()
{
return new Rectangle(x, y,
image.getWidth(null), image.getHeight(null));
}
}

Son olarak proje içinde yer alan benim hazırlamış olduğum boyutları tam oturmasa da oyunu çalıştırmanıza yardımcı olacak görselleri paylaşıyorum.

ball.pngball

brickie.pngbrickie

paddle.pngpaddle

Bir Cevap Yazın