Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование с нуля - это совсем просто! 152) Программирование ролевой игры: Квесты-6


Школа программирования

152) Программирование ролевой игры: Квесты-6

Последний выпуск по ролевой игре был N 149.

Вторым типом квеста мы выбрали задачу доставки некоторого предмета. То есть сначала надо передать герою некоторый предмет, а потом объяснить, кому его надо доставить. Этот тип квеста получит значение qSendItem. Пусть распределение квестов между типами будет равновероятным:

  { ----------------- }
  procedure CallQuest(hn, mn: Integer);
  ...

  if random(2) = 0
     then GenerateQuest(n,mn,qKillTarget)
     else GenerateQuest(n,mn,qSendItem);

  end;

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

  { ----------------- }
  procedure GenerateQuest(qi,hn: Integer; qt: TQType);
  var i,j: Integer;
        gi: TGameItem;
  label NextMon;
  begin

  case qt of

   qKillTarget:

    for i := 1 to MaxMonsters-MaxNPCNum do
      if Monsters[i].HP > 0 then
         begin
         for j := 1 to MaxQuests do
           if Quests[j].TargetId=i then
              goto NextMon;

         Monsters[i].Name := Monsters[i].Name + ' , ' + GenerateMonsterName;
         Quests[qi].QType := qt;
         Quests[qi].MainInd := hn;
         Quests[qi].TargetId := i;
         Quests[qi].Money := (Heroes[CurHero].Level+1)*(80+random(21));
         Quests[qi].XP := round( Heroes[CurHero].MaxExp*
                                  ((15+random(16))/100) );
         ShowInfo(STR_QUESTOK);
         Exit;

        NextMon:
         end;

   qSendItem:
         begin
         i := GetFreeBag(Heroes[CurHero]);
         if i = 0 then
             begin
            ShowInfo(STR_QUESTNOBAG);
            Exit
            end;
         end;

  end;
  end;

Текстовая константа:

  STR_QUESTNOBAG = ' У героя нет места в инвентаре! ' ;

Генерация предмета выполнится с помощью соответствующей подпрограммы:

  qSendItem:
        begin
        i := GetFreeBag(Heroes[CurHero]);
        if i = 0 then
           begin
           ShowInfo(STR_QUESTNOBAG);
           Exit
           end;

        GenerateRandomItem(gi,0,0,1);
        gi.Ints[MaxItemInt] := hn;
        Heroes[CurHero].Items[i] := gi;

        end;

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

Завершающий шаг по формированию квеста - нахождение персонажа, которому этот предмет надо доставить. Это должен быть, конечно, не монстр, а один из мирных жителей.

  while true do
    for i := MaxMonsters-MaxNPCNum+1 to MaxMonsters do
     if i <> hn then
     if random(MaxNPCNum)=0 then
        begin
        Quests[qi].QType := qt;
        Quests[qi].MainInd := hn;
        Quests[qi].TargetId := i;
        SetQuestPrize(qi);
        ShowInfo(STR_QUESTOK);
        Exit
        end;

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

  procedure SetQuestPrize(qi: Integer);
  begin
  Quests[qi].Money := (Heroes[CurHero].Level+1)*(80+random(21));
  Quests[qi].XP := round( Heroes[CurHero].MaxExp*
                               ((15+random(16))/100) );
  end;

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

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

  qSendItem:
    begin
    s := STR_QSEND + Monsters[ Quests[qi].TargetId ].Name + ' : ' +
               IntToStr(Monsters[ Quests[qi].TargetId ].x) + ' , ' +
               IntToStr(Monsters[ Quests[qi].TargetId ].y) + ' ' +s+ ' ; ' +
         STR_QRETURN +
               IntToStr(Monsters[ Quests[qi].MainInd ].x) + ' , ' +
               IntToStr(Monsters[ Quests[qi].MainInd].y) + ' . ' ;

    end;

Текстовая константа:

  STR_QSEND = ' Доставить предмет - кому: ' ;

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

Далее - продолжаем реализацию квестов.

Исходный код текущей версии для Turbo Pascal (всегда проверен и работоспособен, главный файл - main.pas):

тут, 627.zip, 19088 байтов


(c) 2004-2007 Сергей Бобровский bobrovsky as russianenterprisesolutions.com

Школа программирования с нуля
Все предыдущие выпуски базового курса всегда тут:
http://www.infiltration.ru/p/

Неофициальный сайт поддержки (со срочными вопросами - сюда):
www.prog-begin.net.ru.


Мои учебные курсы "Технологии Delphi / C++ / C#. Разработка приложений для бизнеса".
http://shop.piter.com/display.phtml?a_id=17681&web_ok=all

Все эти учебные курсы рассчитаны не только на разработчиков, но и на всех тех, кто хочет стать ИТ-менеджером. Для этого как минимум нужно иметь общее представление о современных технологиях разработки и их истории и владеть соответствующей терминологией.
В книгах описаны десятки технологий, каждой из которых посвящены отдельные книги. Таким образом, купив один учебный курс, вы существенно сэкономите :) В книгах полностью описаны:
- Delphi (версия 2006, полностью совместимая с Turbo Delphi) для обеих платформ - Win32 и .NET;
- C# (новый язык Microsoft, на котором базируется платформа .NET и все новые версии Windows);
- C++ для платформы Win32.
Охвачены также темы работы с файлами на этих платформах, создания файл-серверных, клиент-серверных, распределенных приложений, веб-программ (Indy, ASP.NET, веб-сервисы). Описаны языки SQL и OCL. Немало глав посвящены истории программирования и различных технологий. Особое внимание уделено созданию программ с помощью технологии ECO и языка моделирования UML - программы фактически рисуются, и теперь даже для создания корпоративных приложений и их переноса в Интернет не обязательно знать программирование!
Отдельная часть отведена технологиям организации групповой работы, управления требованиями, контроля версий, локализации и тестирования.
Тут подробнее про книги.

Мои книги, которые пока доступны в продаже:


Дизайн рассылки: Алексей Голубев - Web-дизайн и web-программирование


В избранное