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

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

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

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

Урок 29. Что у монстра внутри?

Урок 29. Что у монстра внутри

 

Теперь, когда мы полиостью определились с перечнем и структурой типов предметов в игре, реализуем упомянутый режим, когда из убитого монстра выпадает некий предмет. Для этого нам потребуется нечто, схожее с кодом процедуры расстановки предметов на генерируемой карте. Ведь в этом коде предметы формируются случайно, и было бы неплохо этим кодом воспользоваться и в текущем случае. Для этого давайте выделим соответствующую часть процедуры MapGeneration в отдельную процедуру GenerateRandomltem (в модуле Gameltcm), которая будет выдавать случайно созданный предмет. Правильнее оформить ее в виде функции, но к сожалению версия Borland Pascal еще не умела поддерживать функции, которые возвращают значения сложных типов данных. В число параметров также добавим начальные координаты предмета на земле и текущий уровень генерации карты (MapLevel) - он нужен нам для подсчета случайно разбрасываемой суммы.

 

procedure GenerateRandomltem(   var  gi:   TGameltem;   x,y,   ml: Integer   );

begin

gi   :=   ItemTypes[random(MaxItemTypes)+1];

gi.x   :=  x;

gi.y   :=   y;

  if  gi.ID =  7   then

  begin

  gi.Ints[intMagikType]    :=   random(mintMax)+1;

     case  gi.Ints[intMagikType]   of

      mintStormStf   :   gi.Ints[intMagikNum]    :=  5;

      mintHealingStf:   gi.Ints[intMagikNum]    :=   10;

  else 

  gi.Ints[intMagikNum]    :=   1;

  end;

end

else

if gi.ID  =   8   then

begin

gi.Ints[intMoney]    :=   random(ml*10)+1;

end

end;

 

А в процедуре MapGenerale код сократится:

 

if random(100)   =   0   then

begin

inc(n);

  if  n  <= Maxltems   then

  begin

  GerateRandomItem (Items [n] , x, y,MapLevel) ;        .     ,     ..-,

  end;

end;

 

Теперь воспользуемся новой процедурой для создания предмета, который выпадает из монстра после его убийства. Для этого дополним в конце процедуру HeroAttaekFin, которая вызывается всегда, когда уничтожается противник:

 

if monsters [m] .HP   <=   0   then

begin

Showlnfo(Monsters[m].Name  +   STR_MON_KILL);

incXP(   H,Monsters [m] .XP   ) ;

n   := GetFreeltemNum;

if n>0   then

GenerateRandomItem(Items[n],Monsters[m].x,Monsters[m].y,CurMap);

end;

end;

 

Теперь после уничтожения любого монстра на его клетке останется какой-то предмег. Его можно подобрать и, например, продать. А где?

Магазины.

Пусть магазины будут особым типом тайлов (tileShop), при вступлении на которые герой будет оказываться внутри магазина, в соответствующем интерфейсе:

 

TileGrass   =   1;

TileGround  =   2;

TileStairsUp  =   3;

TileStairsDown  =   4;

TileTrap = 5;

TileLive   =   6;

TileShop  =   7;

TileFirstStopTile  =   8;

TileTree   =   tileFirstStopTile;

TileStone  =   tileFirstStopTile+1;

TileLast  =  tileFirstStopTile+1;

 

Показыться на карте они будут, как и лежащие на земле деньги, символом '$', только не иного, а зеленого цвета:

 

Const TileRecords:   array[1..tileLast]   of  TTileRecord  =

(

(C:   '   .   '   ;   Clr:Green),

(C:    '   _   '    ;   ClrrBrown),

(C:    '   <   '    ;   ClrrLightGray),

(C:    '   >   '    ;   ClrrLightGray),

(C:    '    .    '    ;   ClrrGreen),

(C:    *   *   '   ;   Clr:LightCyan),

(C:    '   $   '   ;   ClrrLightGreen),

(C:    •   л   '   ;   ClrrLightGray),

(C:    '    !    '    ;   ClrrLightGreen) );

 

Типов магазинов для повышения интереса к игре обычно бывает несколько. Мы введем два типа магазинов - торгующих обычным оружием и магическими предметами. А в полноценной игре можно дополнительно создать магазины, в которых торгуют только зельями, жезлами, луками или топорами.

Как различать типы магазинов? Во-первых, можно ввести дополнительные тайлы для каждого из таких типов. Во-вторых, можно расширить описание структуры TMapCell, дополнив ее значением, уточняющим "смысл" текущего таила (для магазина - его тип; для горы - степень кривизны и т. д.). В третьих, тип магазина можно запрятать непосредственно в сам программный код, договорившись, что например магазины магических предметов будут находиться на четных вертикалях координатной сетки, а магазины обычного оружия -на нечетных.

Для крупных проектов лучше подойдет второй вариант с информационной избыточностью, а мы реализуем первый принцип, менее простой в плане реализации, но более простой в плане наглядности. Уточним название констант-тайлов магазинов, и их цвета:

 

TtileLive  =   6;

tileMagicShop =   7;

tileWeaponShop  =   8;

tileFirstStopTile  =   9;

 

const TileRecords:   array[1..tileLast]   of  TTileRecord =

(

(C:       '           .           '           ;           Clr:Green),

(C:       '           _          '           ;           ClrrBrown),

(Cr       '           <          '           ;           ClrrLightGray),

(C:       '           >          '           ;           ClrrLightGray),

(C:       '           .           '           ;           ClrrGreen),

(C:       '           *          '           ;           ClrrLightCyan),

(Cr       '           л          '           ;           ClrrLightGray),

(C:       '           !           '           ;           ClrrLightGreen),

(Cr       '           $          •          ;           ClrrLightGreen),

(Cr       '           $          '           ;           ClrrLightCyan)

);

 

В завершение процедуры MapGeneration запишем следующий код установки двух новых тайлов магазинов:

 

FreeMapPoint (x, у) ;

GameMap[CurMap].Cells[x,у].Tile   :=   tileMagicShop;

FreeMapPoint(x,y);

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

end;

 

Теперь нам надо запрограммировать реакцию программы на посещение магазина. Для этого объединим все тайлы магазинов в одну константу-множество ShopTileSet:

 

TrapTileSet  =   [tileTrap];

LiveTileSet  =   [tileLive];

ShopTileSet  =   [tileMagicShop,tileWeaponShop];

 

а в процедуре перемещения героя MoveHero добавим проверку вступления на это множество:

 

if  GameMap[CurMap].Cells[ Heroes[CurHero].x,Heroes[CurHero].y].Tile  

in ShopTileSet  then

begin

end;

 

Пусть в таком случае будет вызываться подпрограмма из модуля LowLevel (так как начнется непосредственная работа с интерфейсом магазина), назовем ее GoToShop. В качестве параметра такой процедуры передадим таил, чтобы знать, какой магазин создавать:

 

With GameMap[CurMap] .Cells [ Heroes [CurHero] . x;HFroes [CurHero] .y]

if Tile in ShopTileSet then

begin

GoToShop(Tile) ;

End;

 

Подготовим шаблон процедуры в модуле LowLevel:


Procedure  GoToShop(til:   Integer);

Begin

End;

 

Мы должны сформировать для каждого из магазинов предлагаемую ими номенклатуру товаров. Как это сделать?

Определим внутри данной процедуры локальный массив предметов магазина:

 

procedure  GoToShop(til:   Integer);

Const MaxShopItems   =   5;

Var ShopItems :   array [1..MaxShopItems]   of TGameltem;

Begin

End;

 

Он должен заполняться случайно и в зависимости от типа продаваемых предметов. Чтобы упроститъ процесс подбора товаров, выполним предварительно подсчет числа профильных предметов в массиве Item Types.

 

for   n   :=   1   to MaxShopItems   do

case  til  of

TleWeaponShop:

  begin ni   :=   0;

  for   i   :=   1   to MaxItemTypes  do

   if   ItemTypesfi].IType  in

  [itemHandWeapon, itemArmor, itemAmmo, itemRangedWeapon]   then

  inc(ni);

  end;   ,

TiileMagicShop:

begin

ni   :=   0;

for  i   :=   1   to MaxItemTypes   do

if  ItemTypes[i].IType  in   [itemMagik]   then

inc(ni);

end;

end;

 

Далее мы выбираем какой-то случайный номер в диапазоне от 1 до ni, который и станет номером очередного n-го предмета (типа), предлагаемого в магазине.

 

TileWeaponShop:

begin

ni   :=   0;

for  i   :=   1   to  MaxItemTypes  do if   ItemTypes[i].IType  in

[itemHandWeapon,    itemArmor,    itemAmmo,   itemRangedWeapon]   then

inc(ni);

ni   :=   random(ni)+1;

for  i   :=   1   to MaxItemTypes  do

if ItemTypes[i].IType  in

[itemHandWeapon,    itemArmor,    itemAmmo, . itemRangedWeapon]   then

begin

dec(ni);

if ni   =   0   then

begin

ShopIterns[n]    :=  ItemTypesfi];

break

end;

end;

 

tileMagicShop:

begin

ni   :=   0;

for  i   :=   1   to MaxItemTypes  do

if   ItemTypes[i].IType   in   [itemMagik]   then

inc(ni);

ni   :=  random(ni)+1;

for  i   :=   1   to MaxItemTypes   do

if   ItemTypes[i].IType   in   [itemMagik]   then

begin

dec(ni);

if ni   =   0   then

begin

ShopItems[n]    :=   ItemTypesfi];

break

end;

end;

 

Массив товаров у нас сформирован. Правда, пока в товарах не хватает главного параметра - цены.

Далее: Расширяем возможности магазинов. Изучаем функции двумерного рисования.

 

Источник: delgame.at.ua

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

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