Меню сайта
Форма входа

Категории раздела
Уроки по созданию игр [38]
Программирование игр разной сложности
Игровые алгоритмы [24]
Алгоритмы, которые уже реализованы для разных жанров игр
Графика [5]
Учимся работать с графикой в Делфи
Мультимедиа [3]
Работа с мультимедийными возможностями Делфи
Другие статьи [18]
Статьи не вошедшие не в один из разделов
Ошибки [4]
Всевозможные ошибки и пути их решения
Четверг, 09.01.2025, 07:13
Приветствую Вас Гость

Статьи по программированию

Главная » Статьи » Уроки по созданию игр

Создание Ролевой игры РПГ на Паскале и Делфи. Урок 4

Урок 4. Программируем карту

 

Программируем карту

Сначала создадим, как обычно, главный файл программы main.pas:

 

program  LearningRPG;

begin

end.

 

Затем добавим к проекту модуль map.pas:

 

unit  Map;

interface

implementation

end.

 

Мы договорились, что будем работать с записями, избегая объектной технологии. Поэтому опишем новые типы - ячейку карты, и саму карту, как обычные записи:

 

type 

TMapCell  =   record Tile:  

Integer; IsVisible:Boolean

end;

 

TMap  =   record

Cells:   array[1.,MAP_WIDTH,1..MAP_HEIGHT]   of TMapCell;

LocalMapLeft, LocalMapTop: Integer-end;

 

Здесь поле Tile хранит значение таила ячейки карты, IsVisible определяет, виден ли таил. Все ячейки хранятся в массиве Cells (первая размерность - координата х, вторая - координата у), текущие координаты видимой части карты записываются в поля LocalMapLeft и LocalMapTop (значение левой и верхней координат). К этому тексту необходимо добавить некоторые важнейшие константы. MAP_WIDTH и MAX_HEIGHT задают размеры глобальной карты (счет начинается с нуля), LOCAL_MAP_W!DTH и LOCAL_MAP_HEIGHT - размеры видимой части.

 

const  

LOCAL_MAP_WIDTH  =   8;

LOCAL_MAP_HEIGHT   =   8;

MAP_WIDTH   =   32   +   L0CAL_MAP_WIDTH*2;

MAP_HEIGHT   =   32   +   L0CAL_MAP_HEIGHT*2;

 

  Обратите внимание как записаны константы размеров глобальной карты - к значению этих размеров (примем условную карту величиной 32*32 тайла) прибавляется два размера видимой части карты чтобы как уже говорилось раньше, эти краевые зоны карты заполнить непроходимыми тайлами и упростить процесс автоматического скроллирования.

  Размер карты 32*32 тайла и видимой части 8*8 тайлов конечно невелики, но в нашем случае они физически ограничены размером сегмента данных ДОС-а (64 килобайта). Для Windows игры размеры можно увеличить практически неограниченно. Здесь видно, как размеры этих констант существенно зависят от операционной системы, поэтому сразу определимся с директивами условной компиляции, не забыв добавить в самое начало файла {$ DEFINEC.INC} (об этом вызове - в следующем выпуске):

 

{$IFDEF DOS_GAME}

LOCAL_MAP_WIDTH = 8;

LOCAL_MAP_HEIGHT = 8;

MAP_WIDTH = 32+LOCAL_MAP_WIDTH*2;
         MAP_HEIGHT = 32+LOCAL_MAP_HEIGHT*2;

{$ ENDIF}

 

Далее определим какие значениям поля Tile каким тайлам будут равны. Условимся о двух типах покрытиях местности (например, земля и трава) и двух типах непроходимых зон(камни и дерево) Кроме того, подготовим такие тайлы, как "ступеньки вверх" (переход на уровень выше) и «ступеньки вниз» (переход на уровень ниже).

  Далее все нужные нам константы разделим для удобства на две группы проходимых и непроходимых типов и добавив дополнительную константу, определяющую границу этих групп:

 

TileGrass=1;

TileGround=2;

TileStairsUp=3;

TileStairsDown=4;

TileFirstStopTile=5;

TileTree = TileFirstStopTile;

TileStone = TileFirstStopTile+1;

TileLast = TileFirstStopTile+1;

 

Этот вариант удобен тем, что позволяет добавлять новые тайлы в этот список, не требуя переписывания всех  других тайлов группы. Достаточно лишь изменить значения TileFirstStopTile или TileLast.

Как узнать, проходимый ли некоторый таил? Вынесем такую проверку в отдельную функцию. Содержание ее будет тривиальным: (внимание в внутри функции  в выделенной области возможны ошибки)

 

Function FreeTile(Tile : Integer) : Boolean;

Begin

FreeTile := Tile < tileFirstStopTile;

End;

(На делфи данная функция сработа, на паскале – не тестировал)

 

Последовательность локаций

Количество уровней (семь уровней) зададим в константе

 

MaxDungeonLevel=7;

 

Создадим переменную хранящую текущую игровую карту. Она будет обьявлена в интерфейсном разделе, чтобы быть доступной в других модулях. Создадим массив для этой переменной, чтобы без особых затруднений быстро работать в заполняемом файле.

 

TGameMap: array[1..MaxDungeonLevel] of TMap;

 

Var

GameMap:TGameMap;

CurMap:integer;

 

Переменная CurMap будет хранить номер текущей локации (элемента массива GameMap), используемой в игре.

Следующий шаг - генерация карты. Для этого существует немало хороших алгоритмов, причем все они отличаются достаточно высокой сложностью. Мы возьмем простой вариант и будем расставлять непроходимые тайлы на пустой карте случайно. Практика показывает, что если на карте около 35% непроходимых, случайно "набросанных" тайлов, то перемещаться по ней становится ничуть не легче, чем по лабиринту. Запишется процедура генерации игровой карты так:

procedure MapGeneration{MapLevel:   Integer);

var x,y:   Integer;

begin

CurMap   :=  MapLevel; for x   :=   1   to MAP_WIDTH do for  у   :=   1   to MAP_HEIGHT  do

  begin

  if    (x   <=   LOCAL_MAP_WIDTH)    or    (x  >= MAP_WIDTH-LOCAL_MAP_WIDTH)    or

  (y  <=   LOCAL_MAP_HEIGHT)    or    (y  >= MAP_HEIGHT-LOCAL_MAP_HEIGHT)    then

     GameMap[CurMap].Cells[x,y].Tile   :=   tileStone else

     begin

     if random(100)   <   35

     then  GameMap[CurMap].Cells[x,y].Tile   :=  tileTree 

         else

         if  random(2)   =   0

         then  GameMap[CurMap].Cells[x,y].Tile   :=  tileGrass

            else

            GameMap[CurMap].Cells[x,y].Tile   :=  tileGround;

            end;

         GameMap[CurMap].Cells[x,y].IsVisible   :=   false;

         end;

      GameMap[CurMap].LocalMapLeft   := MAP_WIDTH div  2;

      GameMap[CurMap].LocalMapTop   := MAP_HEIGHT  div 2;

      end;

 

В качестве параметра указывается уровень в пещере для генерируемой локации. Первая проверка выясняет, находится ли точка карты (х,у) вблизи границ, которые мы договорились заполнять непроходимыми тайлами. Далее в зависимости от результата датчика случайных чисел выбирается таил - он может быть либо непроходимым (tileTree) либо одним из двух проходимых. В заключение данный таил помечается как исходно невидимый.

Начало видимой части сделаем примерно расположенной в центре глобальной карты. Далее - добавляем средства визуализации карты.

Категория: Уроки по созданию игр | Добавил: Armageddets (22.11.2012)
Просмотров: 2603 | Комментарии: 1 | Теги: программирование игр, Создание Ролевой игры РПГ на Паскал, как написать игру, урок по созданию игр, ролевая игра | Рейтинг: 4.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Наш опрос
Какие уроки по созданию игр Вам удобнее?
Всего ответов: 141
Мини-чат
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 4
    Гостей: 4
    Пользователей: 0