Программирование стратегических игр с DirectX 9.0

         

Функция vGenerateMap()


Структура этой программы редактирования карт практически полностью повторяет структуру предыдущего примера. Главные отличия сконцентрированы в функции генерации карты. Ее цель — генерировать случайно расположенные участки суши, базируясь на передаваемом в качестве параметра номере используемого алгоритма. В рассматриваемом примере я реализовал только один тип алгоритма генерации карты, но ничто не мешает вам добавить и другие! Вот как выглядит код функции:

void vGenerateMap(int iType) { int iRandDirection; int iSeedPos[32]; int i, j; int iNumSeeds = 32; int iNumUpdates = 800;

// -- ТИП 0 -- Случайные семена if(iType == 0) { // Очиска карты vInitMap(); // Создание случайно расположенных начальных семян for(i = 0; i < iNumSeeds; i++) { // Установка начальной позиции семени iSeedPos[i] = rand() % (g_iMapHeight * g_iMapWidth); // Помещаем в позицию семени блок с изображением травы g_iTileMap[iSeedPos[i]] = 17; } // Перемещение семени for(i = 0; i < iNumUpdates; i++) { for(j = 0; j < iNumSeeds; j++) { iRandDirection = rand()%4;

// перемещаем семя вверх if(iRandDirection == 0) { iSeedPos[j] -= g_iMapWidth; } // Перемещаем семя вправо else if(iRandDirection == 1) { iSeedPos[j]++; } // Перемещаем семя вниз else if(iRandDirection == 2) { iSeedPos[j] += g_iMapWidth; } // Перемещаем семя влево else if(iRandDirection == 3) { iSeedPos[j]--; }

// Если семя вышло за пределы карты, // помещаем его в случайную позицию if(iSeedPos[j] < 0 || iSeedPos[j] >= (g_iMapHeight * g_iMapWidth)) { iSeedPos[j] = rand() % (g_iMapHeight * g_iMapWidth); } // Помещаем в позицию семени блок с изображением травы g_iTileMap[iSeedPos[j]] = 17; } } } // Отображение мини-карты vRenderMinimap(); // Воспроизведение звука, сообщающего о завершении операции PlaySound("bleep.wav",NULL,SND_FILENAME|SND_ASYNC); }

Код может выглядеть устрашающе, так что сперва взгляните на рис. 10.14, где показан ход выполнения функции.


Рис. 10.14. Ход выполнения функции vGenerateMap()


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

Как только семена размещены на карте, код в цикле указанное число раз перебирает каждое из семян и случайным образом смещает его на один квадрат влево, вправо, вверх или вниз. В новую позицию семени также помещается блок с изображением травы. Вот так, медленно но верно, данный метод заполняет карту случайно расположенными блоками с изображением травы. На рис. 10.14 справа от процедур перемещения семени изображено, как карта постепенно обретает форму.

Есть еще пара вещей, отсутствующих на иллюстрации. Во-первых, перед началом создания ландшафта я вызываю функцию vInitMap() для очистки карты. Это требуется для того, чтобы перед созданием случайно расположенных блоков с изображением травы массив карты был приведен в исходное состояние. Во-вторых, на иллюстрации отсутствует проверка, гарантирующая, что семя не будет блуждать за пределами карты. Если семя выходит за границы карты, оно помещается в случайную позицию внутри карты и продолжает формировать изображение суши в новом месте. И последняя отсутствующая вещь — вызов функции отображения миникарты, показывающей обновленный ландшафт.


Содержание раздела