Bu yazıda ise, yılan oyununu, küçük sınıflara bölerek ve JAVA dilinin bize sağladığı bazı esneklikleri kullanarak okunması ve anlaşılması kolay bir hale getirmeye, işin özünü anlamaya çalışacağız. Bu projemiz tamamlandığında, sınıflarımızın genel görünümü şöyle olacak:
Şimdi gelelim sınıflarımızı yazmaya. İlk sınıfımız Cell.java olsun. Bu sınıfı hem yılanı oluşturmak için hem de yılanın hareket edeceği alanı oluşturmak için kullanacağız. Sınıfımız şöyle:
public class Cell {
final static int CELL_TYPE_EMPTY = 0, CELL_TYPE_FOOD = 10, CELL_TYPE_SNAKE_NODE = 20;
final int row, col;
int type;
public Cell(int row, int col) {
this.row = row;
this.col = col;
}
}
final static int CELL_TYPE_EMPTY = 0, CELL_TYPE_FOOD = 10, CELL_TYPE_SNAKE_NODE = 20;
final int row, col;
int type;
public Cell(int row, int col) {
this.row = row;
this.col = col;
}
}
Bu sınıfımız sadece satır ve sütun değerlerini tutuyor. Bir de hücrelerin tiplerini belirleyecek olan sabit integer değerler tutuyor.
İkinci sınıfımız Board.java olsun. Bu sınıf, yılanın gezineceği alanı tanımlamamızı sağlayacak (satranç tahtası gibi). Sınıfımız şöyle:
public class Board {
final int ROW_COUNT, COL_COUNT;
Cell[][] cells;
public Board(int rowCount, int columnCount) {
ROW_COUNT = rowCount;
COL_COUNT = columnCount;
cells = new Cell[ROW_COUNT][COL_COUNT];
for (int row = 0; row < ROW_COUNT; row++) {
for (int column = 0; column < COL_COUNT; column++) {
cells[row][column] = new Cell(row, column);
}
}
}
public void generateFood() {
int row = (int) (Math.random() * ROW_COUNT);
int column = (int) (Math.random() * COL_COUNT);
cells[row][column].type = Cell.CELL_TYPE_FOOD;
}
}
final int ROW_COUNT, COL_COUNT;
Cell[][] cells;
public Board(int rowCount, int columnCount) {
ROW_COUNT = rowCount;
COL_COUNT = columnCount;
cells = new Cell[ROW_COUNT][COL_COUNT];
for (int row = 0; row < ROW_COUNT; row++) {
for (int column = 0; column < COL_COUNT; column++) {
cells[row][column] = new Cell(row, column);
}
}
}
public void generateFood() {
int row = (int) (Math.random() * ROW_COUNT);
int column = (int) (Math.random() * COL_COUNT);
cells[row][column].type = Cell.CELL_TYPE_FOOD;
}
}
Bu sınıfta, Cell sınıfımızdan rowCount * colCount büyüklüğünde iki boyutlu bir array oluşturuyoruz ve constructor içerisinde bu hücrelerin atamasını yapıyoruz.
Bir diğer methodumuz ise generateFood() methodu. Bu method, rastgele bir satır-sütundaki Cell nesnesinin tipini CELL_TYPE_FOOD'a eşitliyor. Dolayısıyla o hücreyi yılan için bir yem haline getirmiş oluyoruz.
Gelelim üçüncü sınıfımız olan Snake.java sınıfına. Sınıfımız şöyle:
public class Snake {
LinkedList<Cell> snakePartList = new LinkedList<>();
Cell head;
public Snake(Cell initPos) {
head = initPos;
snakePartList.add(head);
}
public void grow() {
snakePartList.add(head);
}
public void move(Cell nextCell) {
Cell tail = snakePartList.removeLast();
tail.type = Cell.CELL_TYPE_EMPTY;
head = nextCell;
snakePartList.addFirst(head);
}
public boolean checkCrash(Cell nextCell) {
for (Cell cell : snakePartList) {
if (cell == nextCell) {
return true;
}
}
return false;
}
}
LinkedList<Cell> snakePartList = new LinkedList<>();
Cell head;
public Snake(Cell initPos) {
head = initPos;
snakePartList.add(head);
}
public void grow() {
snakePartList.add(head);
}
public void move(Cell nextCell) {
Cell tail = snakePartList.removeLast();
tail.type = Cell.CELL_TYPE_EMPTY;
head = nextCell;
snakePartList.addFirst(head);
}
public boolean checkCrash(Cell nextCell) {
for (Cell cell : snakePartList) {
if (cell == nextCell) {
return true;
}
}
return false;
}
}
Yılanın kafasını oluşturan hücre, bir sonraki hamlemizi oluşturacağı ve çarpışma kontrolü sırasında önemli olduğu için, bunu 'head' değişkeninde tutuyoruz.
Burada move() methodunu inceleyecek olursak, yılanı nasıl hareketlendirdiğimizi anlamış oluruz. Buradaki espiri, her bir adımda, yılanın en sonunda bulunan hücreyi, yılanın en önüne taşımak (hareket yönünü dikkate alarak tabi ki).
Diğer bir methodumuz olan checkCrash()'i incelersek, burada yapılan işlem, yılanın bir sonraki harekette gideceği hücrenin, yılanın herhangi bir parçasına denk gelip gelmediğini kontrol etmek.
Bir sonraki sınıfımız ise Router.java olsun. Bu sınıf, kullanıcı tarafından verilen yön bilgisine göre yılanın bir sonraki adımının nasıl olacağını hesaplayan, çarpışma testini yapacak olan sınıftır. Bir nevi yılanın yol göstericisidir. Sınıfımız şöyle:
public class Router {
public static final int DIRECTION_NONE = 0, DIRECTION_RIGHT = 1, DIRECTION_LEFT = -1, DIRECTION_UP = 2, DIRECTION_DOWN = -2;
private Snake snake;
private Board board;
private int direction;
private boolean gameOver;
public Router(Snake snake, Board board) {
this.snake = snake;
this.board = board;
}
public void setDirection(int direction) {
this.direction = direction;
}
public void update() {
if (!gameOver) {
if (direction != DIRECTION_NONE) {
Cell nextCell = getNextCell(snake.head);
if (snake.checkCrash(nextCell)) {
setDirection(DIRECTION_NONE);
gameOver = true;
} else {
snake.move(nextCell);
if (nextCell.type == Cell.CELL_TYPE_FOOD) {
snake.grow();
board.generateFood();
}
}
}
}
}
private Cell getNextCell(Cell currentPosition) {
int row = currentPosition.row;
int col = currentPosition.col;
if (direction == DIRECTION_RIGHT) {
col++;
} else if (direction == DIRECTION_LEFT) {
col--;
} else if (direction == DIRECTION_UP) {
row--;
} else if (direction == DIRECTION_DOWN) {
row++;
}
Cell nextCell = board.cells[row][col];
return nextCell;
}
}
public static final int DIRECTION_NONE = 0, DIRECTION_RIGHT = 1, DIRECTION_LEFT = -1, DIRECTION_UP = 2, DIRECTION_DOWN = -2;
private Snake snake;
private Board board;
private int direction;
private boolean gameOver;
public Router(Snake snake, Board board) {
this.snake = snake;
this.board = board;
}
public void setDirection(int direction) {
this.direction = direction;
}
public void update() {
if (!gameOver) {
if (direction != DIRECTION_NONE) {
Cell nextCell = getNextCell(snake.head);
if (snake.checkCrash(nextCell)) {
setDirection(DIRECTION_NONE);
gameOver = true;
} else {
snake.move(nextCell);
if (nextCell.type == Cell.CELL_TYPE_FOOD) {
snake.grow();
board.generateFood();
}
}
}
}
}
private Cell getNextCell(Cell currentPosition) {
int row = currentPosition.row;
int col = currentPosition.col;
if (direction == DIRECTION_RIGHT) {
col++;
} else if (direction == DIRECTION_LEFT) {
col--;
} else if (direction == DIRECTION_UP) {
row--;
} else if (direction == DIRECTION_DOWN) {
row++;
}
Cell nextCell = board.cells[row][col];
return nextCell;
}
}
Evet, yılanımızın temelini oluşturmuş olduk. Geriye sadece kullanıcının yön bilgisini tayin etmesini sağlayacak ve yılanın ekranda çizilmesini sağlayacak sınıfın yazılması kaldı. Bir JFrame ve bir JPanel yardımıyla bu dediklerimizi de kolaylıkla yapabiliriz.
Oyunumuzun bitmiş hali aşağıdaki gibi olacak. İstediğimiz gibi şekillendirmek elimizde:
Bu yazımda, yılan oyununun temel özelliklerini yerine getiren sınıfları yazmış olduk. Ancak dikkat edildiğinde, bu sınıfların bazı gelişmiş özellikleri yerine getirmediği görülebilir.
Bir sonraki yazımda, bu yılan oyununa daha gelişmiş bir hale getirmeyi ve yılanın ekranda çizilmesini sağlayacak olan sınıfı tamamlamayı düşünüyorum.
Abi bu kodları not defterine mi yazıyoruz??
YanıtlaSilEclipse java indir kur orada yapıyorsun.
Siluzantısı ne olacak not defterinin
SilNetbeans ya da Eclipse gibi kod editörlerini kullanmanız, özellikle başlangıç aşamasında sizin için faydalı olacaktır.
Silubuntu üzerinden yazıldıgında bu kodların nasıl çalıştırılacagına değinebilir misiniz?
SilBahsettiğim kod editörlerinin Linux için sürümleri bulunuyor. Bunlardan faydalanabilirsiniz.
Silkodlar gayet güzel..teşekküler
YanıtlaSilTecrübelerini paylaştığın için sağol ama bu kodları kopyalayıp yapıştırınca snake ve router sınıflarında hatalar oluşuyor.Bunu nasıl çöze bilirim.
YanıtlaSilJDK 7 kullandığın takdirde sorun olmayacaktır.
SilJframe ve Jpanel için de yazınız var mı ?
YanıtlaSilÇok güzel bir paylaşım olmuş. bir sonraki yazınız hangisi acaba devamı niteliğinde olan yazınız?
YanıtlaSilmain kodu bir sonraki kodu nerede acaba teşekkürler
YanıtlaSilmain kodalrı yok bide snake class ında bi hata var linkedlist class ı yok dye
YanıtlaSilimport et linkedlisti
Silimport et
Silabi android studio ile nasıl yapabilirim bunu lütfen yardım edebilirmisin ödevim varda
SilGüzel Olmu sancak elle yazssakta kopyala yapsakta NetBeansda IDE Hata veriyor.
YanıtlaSilnetbeans ide den oyun yapmayı yayınlarmısınız
YanıtlaSilBiladerim her şeyi yazmışsın jframe ve jpanel eklemeyi göstermemişsin ya
YanıtlaSilyılanın boyunun hiç degişmeden nasılyapcaz ya pki
YanıtlaSilOyun dünyasına ilk adım emeğe saygı
YanıtlaSilellerine sağlık ama jframe jpaneli nası yapıcaz
YanıtlaSilbu kodu androide nasıl uyarlayacaz peki?
YanıtlaSilJpanel Jframe nasıl ya
YanıtlaSilJpanel Jframe nasıl ya
YanıtlaSilmain class ta istiyor
YanıtlaSileclipse indirdim amaq açilmiyor yardımcı olurmusunuz ??????????
YanıtlaSilmain sınıfı neden yok hocam
YanıtlaSilDenicem...
YanıtlaSil