Статьи

Tower Defense в JavaFX

Я давно хотел использовать свой игровой движок для написания игры Tower Defense, но, поскольку была предпринята попытка создать JavaFX Tower Defense Game другой группой, я решил вместо этого создать другую игру. Из списка рассылки я узнал, что другая игра больше не разрабатывается. Поэтому я решил, что должен попробовать.

Tower Defense — игра, которая идеально подходит для подхода, основанного на тайлах, поэтому я начал искать некоторые тайлы. Я нашел некоторые здесь, и художник, Сильвиу Плойстяну, дал мне разрешение использовать их в моей демонстрации. Tower Defense как игра очень похожа на редактор TileMap, поэтому я смогу использовать много кода из редактора, который недавно создал:

Первым делом нужно было объединить отдельные графические изображения в изображения для мозаичного изображения. Я сгруппировал врагов, базы турелей, пушки, местность, а также создал один набор плиток для фона. После этого я использовал TileMap Editor ( http://www.mapeditor.org/ ) для создания TileSets из этих изображений. Вероятно, мне придется выполнить эту часть снова, потому что Gimp изменил цвета в этом процессе, но сейчас я не слишком беспокоюсь о визуальных эффектах.

Затем я добавил 5 слоев снизу вверх на новую карту: «фон», «ландшафт», «турели-базы» и «турели-пушки» и «враги». Также будет слой «пули и взрывы», но позже я добавлю его вручную. Пока что не требуется никакого кодирования, и благодаря подходу, основанному на TileMap, у нас уже есть формат сериализации для игры. Поэтому, когда пользователь редактирует карту, мы можем просто сохранить изменения в TileMap. Вот как карта выглядит сейчас:

Bildschirmfoto-2013-08-06-эм-16.41.16

Следующим шагом является кодирование. Я просто создал новое приложение JavaFX с BorderPane. В центре у меня будет игровое поле, справа — палитра с пушками.

Вот как вы создаете GameCanvas:

1
2
3
4
5
6
7
tileMap = TileMapReader.readMap(fileURL);
canvas = new GameCanvas(tileMap.getTilewidth() * tileMap.getWidth(), tileMap.getHeight() * tileMap.getTileheight(), tileMap.getTilewidth() * tileMap.getWidth(), tileMap.getHeight() * tileMap.getTileheight());
// add all the layers
ArrayList layers = tileMap.getLayers();
for (TileMapLayer tileMapLayer : layers) {
  canvas.addLayer(tileMapLayer);
}

Затем я получаю TileSet с пушками и создаю Палитру. Я использую VBox для палитры, так как я хочу сделать ландшафт редактируемым, и я мог бы добавить еще один TileSet для этого позже:

1
2
3
4
5
TileSet turrets = tileMap.getTileSet("turrets");
 
TileSetView turretView = new TileSetView(turrets);
VBox palette = new VBox();
palette.getChildren().addAll(turretView);

TileSetView просто отображает базовое изображение и позволяет выбрать плитку щелчком мыши. Возможно, я покажу код чуть позже, когда мы начнем с взаимодействия с пользователем. На данный момент это то, что мы видим после запуска игры:

Bildschirmfoto-2013-08-06-эм-16.44.09

Уродливая красная область является фоном по умолчанию. К сожалению, размер фонового изображения не кратен размеру плитки, поэтому позже мне придется определить предложение. А пока я проигнорирую это, это просто фон …

Теперь мы хотим, чтобы пользователь мог размещать турели. На данный момент у игрока неограниченное количество денег, поэтому он может разместить столько турелей, сколько захочет. Единственное ограничение заключается в том, что он может размещать их, только если он находится на платформе, и если там еще нет башни. Поэтому мы добавляем EventHandler для событий мыши, который получает выбранную турель из палитры и добавляет ее в базовый слой турели. Для простоты я объединил основание башни и башню в одно изображение:

01
02
03
04
05
06
07
08
09
10
11
12
13
canvas.setOnMousePressed(new EventHandler() {
@Override
public void handle(MouseEvent t) {
 
double x = t.getX();
double y = t.getY();
 
int idx = (int) ((int) x / tileMap.getTilewidth() + (((int) y / tileMap.getTileheight()) * tileMap.getWidth()));
if (platformLayer.getGid(idx) != 0 && turretBaseLayer.getGid(idx)==0) {
turretBaseLayer.getData().setGid(idx, turretView.getSelectedGid());
}
}
});

В результате теперь мы можем размещать турели там, где есть платформа и еще нет турели:

Я думаю, что первая часть уже показывает, что API действительно хорош для создания простых игр без необходимости писать очень много кода. В следующей части мы добавим точку возрождения и цель и используем A * для расчета пути врага.

Ссылка: Tower Defense в JavaFX от нашего партнера JCG Тони Эппла в блоге Eppleton .