Добавил:
abhai2013@gmail.com Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Диплом.docx
Скачиваний:
98
Добавлен:
30.06.2018
Размер:
4.09 Mб
Скачать
  1. Спеціальна частина

2.1 Результати поглибленої розробки окремих модулів комп'ютерної гри-стратегії "Tower Defense".

В даному ПК рівні розділені на дві категорії:

- сюжетні, які створені розробниками;

- кастомні, які створює користувач.

Сюжетні рівні знаходяться у таблиці Levels в базі даних з id 1…3. На рис. 2.1 представлено запит до бази даних, який витягує з неї сюжетні рівні.

publicvoidloadLevel(intlevelID) {

JsonArrayjsonArray=newJsonArray();

try{

Gsongson=new Gson();

dataBaseHandler.openDatabase();

DatabaseCursor cursor = dataBaseHandler.rawQuery(loadQuery);

if (cursor.next())

jsonArray.addAll(gson.fromJson(cursor.getString(0), JsonArray.class));

for (int i = 0; i < jsonArray.size(); i++) {

JsonArray jsonElements = jsonArray.get(i).getAsJsonArray();

for (int j = 0; j < jsonElements.size(); j++) {

mapMask[i][j] = jsonElements.get(j).getAsInt();

if (!gameWorld.isEdit())

gameWorld.getGrid().get(i).get(j).setState(mapMask[i][j]);

}

}

dataBaseHandler.closeDatabase();

} catch (SQLiteGdxException e) {

e.printStackTrace();

}

}

Рисунок 2.1 – Звернення до рівню у базі даних

Кастомний рівень знаходиться у таблиці Levels з id 0. На рис. 2.2 представлена функція, яка зберігає рівень користувача у базу даних.

public void saveLevel() {

for (int i = 0; i < GameWorld.MAP_HEIGHT_MAX; i++)

for (int j = 0; j < GameWorld.MAP_WITH_MAX; j++)

mapMask[i][j] = GameWorld.getInstance().getEditGrid().get(i).get(j).getState();

Json json = new Json();

insertOrUpdateQuery = "UPDATE Levels SET content = '" + json.toJson(mapMask) + "' WHERE id = 0;";

GameWorld.getInstance().setShowSaveText(true);

super.saveLevel();

}

Рисунок 2.2 – Виклик методу saveLevel()

В іграх-стратегіях вороги представлені як хвилі з їх типом, кількістю, інтервалом початку та координатами. В даному ПК хвилі зберігаються у таблиці Waves з id рівня, котрий пов'язаний з id рівня в таблиці Levels. Розглянемо запит до бази даних, який витягує з неї хвилі противників по id рівня(levelId) на рис. 2.3.

public void init(int levelId) {

JsonArray jsonArray = new JsonArray();

String loadQuery = "SELECT content FROM Waves WHERE id = " + levelId;

try {

Gson gson = new Gson();

dataBaseHandler.openDatabase();

DatabaseCursor cursor = dataBaseHandler.rawQuery(loadQuery);

if (cursor.next())

jsonArray.addAll(gson.fromJson(cursor.getString(0), JsonArray.class));

for (int i = 0; i < jsonArray.size(); i++)

enemyWaves.add(gson.fromJson(jsonArray.get(i), EnemyWave.class));

dataBaseHandler.closeDatabase();

} catch (SQLiteGdxException e) {

e.printStackTrace(); } }

Рисунок 2.3 – Звернення до хвилі противників у базі даних

В іграх жанру «Оборона веж» вороги повинні мати маршрут, по якому вони будуть проходити по рівню. Для цього використовуються алгоритми пошуку маршруту. В ПК «Tower Defense» використаний «Хвильовий» алгоритм, який починає шукати маршрут з кінцевої точки. На вхід він приймає початкову та кінцеву точку, та використовує сітку рівня. На рис. 2.4 представлений метод алгоритму пошуку маршруту противників.

public ArrayList<Vector2> findWay(Vector2 start, Vector2 end) {

grid[(int)end.y][(int)end.x] = WATER_KEY;

int counter = 0;

while (counter < MAX_ITERATIONS) {

for (int y = 0; y < mapHeight; y++)

for (int x = 0; x < mapWidth; x++)

if (grid[y][x] == WATER_KEY)

goWater(x, y);

if (grid[(int)start.y][(int)start.x] == WATER_KEY)

return getWay(start, end);

counter++;

}

return new ArrayList<Vector2>();

}

Рисунок 2.4 – Метод алгоритму пошуку маршруту противників

Хвильовий алгоритм проходиться по всій сітці рівня на пошук маршруту від кінцевої до початкової точки. Він перевіряє клітинки, чи може ворог потрапити на цю чи іншу в напрямку початкової точки, та заповнює її своїм кодом по якому потім ПЗ може побачити, що ця клітинка находиться в маршруті ворога. На рис. 2.5 представлено метод goWater(x, y), який перевіряє клітки на карті.

private void goWater(int ax, int ay) {

// Если клеточка сверху свободна

if (inMap(ax, ay - 1) && checkCell(ax, ay - 1)) {

grid[ay - 1][ax] = WATER_KEY;

mapDirs.get(ay - 1).get(ax).x = ax;

mapDirs.get(ay - 1).get(ax).y = ay;

}

// Если клеточка слева свободна

if (inMap(ax - 1, ay) && checkCell(ax - 1, ay)) {

grid[ay][ax - 1] = WATER_KEY;

mapDirs.get(ay).get(ax - 1).x = ax;

mapDirs.get(ay).get(ax - 1).y = ay;

}

// Если клеточка снизу свободна

if (inMap(ax, ay + 1) && checkCell(ax, ay + 1)) {

grid[ay + 1][ax] = WATER_KEY;

mapDirs.get(ay + 1).get(ax).x = ax;

mapDirs.get(ay + 1).get(ax).y = ay;

}

// Есле клеточка справа свободна

if (inMap(ax + 1, ay) && checkCell(ax + 1, ay)) {

grid[ay][ax + 1] = WATER_KEY;

mapDirs.get(ay).get(ax + 1).x = ax;

mapDirs.get(ay).get(ax + 1).y = ay;

}

}

Рисунок 2.5 – Метод goWater(x, y)

Маршрут противників зберігається як список клітинок, по яким він буде проходити рівень. На рис. 2.6 представлений метод getWay(), який повертає противнику як раз цей список клітинок, тобто його маршрут.

private ArrayList<Vector2> getWay(Vector2 start, Vector2 end) {

ArrayList<Vector2> way = new ArrayList<Vector2>();

Vector2 p1 = new Vector2(start.x, start.y);

Vector2 p2 = new Vector2();

while (true) {

p2.x = mapDirs.get((int) p1.y).get((int) p1.x).x;

p2.y = mapDirs.get((int) p1.y).get((int) p1.x).y;

way.add(new Vector2(p2.x, p2.y));

p1.x = p2.x;

p1.y = p2.y;

if (p1.x == end.x && p1.y == end.y)

break;

}

return way;

}

Рисунок 2.6 – Метод getWay().

Вежі в «Tower Defense» мають два стани:

- стан покою(в цьому стані вежа прораховує відстань між собою та противниками і якщо ця відстань менша за суму половин радіусів веж та ворога, вежа переходить до стану атаки

- стан атаки(у цьому стані вежа обстрілює ворога, доки він находиться у полі досяжності)

На рис. 2.7 представлена частина методу update() вежі у стані спокою, де вона перевіряє відстань між противниками та собою.

if (idleDelay >= 5) {

ObjectController enemies = gameWorld.getEnemies();

int size = enemies.size();

for (int i = 0; i < size; i++) {

if (Vector2.dst(getX(), getY(), ((EnemyBase)enemies.get(i)).getX(), ((EnemyBase)enemies.get(i)).getY()) <= attackRadius) {

enemyTarget = (EnemyBase) enemies.get(i);

state = ATTACK_STATE;

}

}

idleDelay = 0;

}

idleDelay++;

setRotation(getRotation() + 0.4f);

Рисунок 2.7 – Частина методу update() вежі у стані спокою

На рис. 2.8 представлена частина методу update() вежі у стані атаки, де вона розраховує кут між собою та противником під яким полетить куля.

if (enemyTarget != null) {

setRotation((float) Amath.angle(getX(), getY(), enemyTarget.getX(), enemyTarget.getY()));

shootDelay--;

if (enemyTarget.isDead()) {

enemyTarget = null;

state = IDLE_STATE;

} else if (Vector2.dst(enemyTarget.getX(), enemyTarget.getY(), getX(), getY()) > attackRadius) {

enemyTarget = null;

state = IDLE_STATE;

} else

shoot();

} else

state = IDLE_STATE;

Рисунок 2.8 – Частина методу update() вежі у стані атаки

Соседние файлы в предмете Дипломная работа (подготовка и защита)