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

Новости сайта www.dyda.info

  Все выпуски  

DarkBASIC - легко создаем 3D миры и игры!


Информационный Канал Subscribe.Ru

БЕСПЛАТНО! Русский DarkBASIC демо + примеры и "фенечки"
  Ограничение по трафику
Номер 18/октябрь 2002
От редактора

  На этих выходных был сбой у провайдера, поэтому многие владельцы сотовых телефонов не смогли воспользоваться НОВОЙ УНИКАЛЬНОЙ услугой - получение новостей из Интернета на свой сотовый. С понедельника все заработало как надо! Так что, если вы владелец сотового телефона - воспользуйтесь единственной возможностью - БЕСПЛАТНО! Плохого рекомендовать вам не буду! Так что - вам сюда!

  В первой половине ноября возможна моя поездка в Мурманск. Так что, пару недель возможно (хотя и не обязательно) рассылка не будет выходить. Кто живет в Мурманске - давайте встретимся, пива попьем, пообщаемся! :-) Напишите мне - мурмчане! :-)

  Информация для новых подписчиков! Если вы "не врубаетесь" о чем идет речь в рассылке - посмотрите предыдущие номера рассылки. И вам станет интереснее! :-) Также советую посетить оффициальный русский сайт www.darkbasic.ru и darkbasic.narod.ru

  Замирая в глубоком пардоне, Илья Середа.


Содержание номера:

      1. Новости.

      2. Руководство по созданию 3D-игр.




Новости

  Автор сайта Russian Dark Basic Developers Network InF!nity "отошел от дел" и принял участие в проекте www.doomiii.ru. Бразды правления своим сайтом он передал мне. Я же, в свою очередь, очень надеюсь на его успешную деятельность в новом проекте и все же возвращение к нам.

  "Медиахауз" приготовил для нас новый конкурс! Какой и когда - вы узнаете из интервью данный мне Михаилом Новиковым (Медиахауз). Также из "недостоверных источников заслуживающих доверия" :-) стало известно о каком-то секретном конкурсе, который тоже собирается проводить "Медиахауз", но когда и где - мне пока неизвестно. Все планируется и разрабатывается в строжайшем секрете. Можно представить, что тогда ЭТО должно быть. Советую почаще заглядывать на официальный сайт DarkBASIC и читать рассылку. Вы узнаете о нем первыми! А пока читайте интервью данное мне Михаилом Новиковым:

  Здравствуйте Михаил!

  Здравствуйте!

  Поговорим о том, что недавно было и что будет в недалеком будущем... Я рад, что конкурс закончен! Честно говоря, я не был уверен в его успешном проведении, т.к. по моему было мало времени для подготовки достаточного числа конкурсных работ. В принципе, то что никому не досталось первого приза - это и подтвердило. Или я ошибаюсь? :-)

  Илья, я, честно, рад тому, что конкурс будет продолжаться. Огорчило то, что работ поступило не так много, как хотелось бы. Вижу несколько причин. Первая, чего собственно, опасались многие - остались ли еще какие-то зачатки творчества в наших людях, которым на каждом углу предлагают новейшие дорогущие в производстве игровые проекты по цене опилок... ДБ же именно то средство, которое позволяет БЫСТРО создать прототип игры. Что до призов - их у нас было достаточно, и я был готов поехать в Финляндию вместе с главным призером, но, увы, работы, достойной главного и первого приза, жюри не увидело.

  А вообще, сколько работ было представлено на конкурс?

  Полдюжины. Я пытался убедить и других (в том числе и наиболее часто упоминаемых на нашем форуме личностей из соседнего государства) прислать свои работы, а достаточно было одного играбельного уровня, но они постеснялись. Лучшее всегда враг хорошего, а гигантизм все еще жив в душах наших людей.

  Где можно увидеть скриншоты игр и где можно скачать сами игры?

  Стас из Москвы (3-е место) вчера был у нас в офисе и получил приз, дал согласие на то, чтобы поместить свой проект на диске первого тома Архива ДБ. Проект Георгия из Южно-Сахалинска (ему приз будет отправлен на следующей неделе) довольно большой и многоплановый, и может не хватить места. Я, конечно, попрошу его сделать какую-то версию для диска. Скачивать с сайта эти вещи мы не дадим, возможно будут скриншоты, но это не главное - основное в этих проектах - играбельность и быстрота и грамотность реализации. Почему не дадим скачивать - есть еще одна причина: в последние две недели сайт находится под постоянными атаками нескольких отморозков из Томска и Иркутска, которые пытаются вызвать отказ работы сервера путем скачивания патча. Мы защищаемся, провайдер готов в любой момент принять жесткие санкции против этих уродов, по поводу одного из них Костя (ВЕКТОР) и писал на форуме вчера.

  Да уж. Лучше бы они эту энергию направляли на созидание чего нибудь, а не на мелкие пакости всему сообществу. Тем более, что узнать вплоть до адреса проживания сейчас можно, а там и приехать за ними могут... Сменим тему. Может быть пора открывать "Галерею игр" на www.darkbasic.ru ?

  Пока мы можем только дать скриншоты со ссылками на сайты самих разработчиков. Пока есть ....ы из Томска, я бы не хотел рисковать нашим сервером и терпением провайдера.

  Если победители будут согласны, не могли бы вы дать мне их e-mail-ы.

  Оба довольно занятые люди. Могу сказать, что Стасу 16 лет и он сейчас очень занят подготовкой в ВУЗ. Георгию 36 лет и он только год назад стал программировать (понятно на чем!).

  Хотелось бы взять у них интервью для рассылки.

  Лучше это сделать через меня, я бы им переслал вопросы.

  Без проблем. Вопросы уже передал. А ориентировочно, когда ждать второго конкурса? (зима, весна, лето 2003 г.?)

  Через неделю или две объявим второй конкурс с окончанием в конце мая, в котором можно будет делать работы как в ДБ, так и в ДБПро - без разницы. Лишь бы была идея, играбельность и грамотность реализации.

  Не оговаривали еще, кто будет спонсором следующего конкурса и какие будут правила его проведения?

  Спонсоры, я надеюсь, те же! Хотел согласовать все эти вопросы на этой неделе, но у нас тут в деревне такое творится... :-((((

  Надеюсь, что все устаканиться! Спасибо, что уделили время и ответили на мои вопросы. До свидания!

  До свидания.




Руководство по созданию 3D-игр.

  Для более детальной и полной информации - рекомендую обратиться к первоисточникам. А это компания "Медиахаус" и "Руководство пользователя", которое вы получаете в коробке с лицензионным DarkBASIC-ом.

III. ИГРА

13.Столкновения с окружающими предметами

Цель урока: показать, как оживить 3D-экран путем добавления окружающих предметов.

В этом уроке мы добавим несколько колонн к нашему ландшафту. Мы также применим способ математического столкновения для расчета столкновений с этими колоннами.

rem Создаем окружающие объекты
load image "cottag02.bmp",300
t=300
For x = 1 to 9
 For z = 1 to 9
  Make object cube t,100
  Scale object t,100,600,100
  y = get ground height(1,x*1000,z*1000)
  position object t,x*1000,y+275,z*1000
  texture object t,300
  scale object texture t,1,-6
  inc t
 next z
next x

Эта часть кода вводится до основного цикла, но после того, как создана матрица. Загружаем изображение, чтобы наложить текстуру на колонны. Переменной t присваиваем значение 300. Это номер первого объекта-колонны. Чтобы создать и расположить каждый из этих объектов, мы используем вложенный цикл. Нежелательно, чтобы колонны помещались на краях матрицы, поэтому вместо того, чтобы выполнять цикл от 0 до 10, выполняем его от 1 до 9. Цикл по оси "x" используется для размещения объектов на матрице. Цикл по оси "z" -для размещения объектов сверху и снизу матрицы. Внутри цикла "z" мы создаем объект-куб с помощью переменной t. Задаем значение масштабирования куба 600 по оси Y, чтобы получить высокую колонну. Затем получаем значение высоты ячейки матрицы в новых координатах X и Z. Заметьте, что для получения координат X и Z мы умножаем переменные цикла на 1000, благодаря чему мы сможем поместить колонны на матрице через равные интервалы. Затем мы помещаем объект в 3D-сцене. К величине Y добавляем значение 275. Это почти половина высоты объекта. Эта операция приподнимает его по оси Y, так как видимое основание объекта находится в его центре. Мы не поднимаем объект на все 300 единиц только потому, что хотим, чтобы он "врастал" в землю. Затем накладываем декоративную текстуру на объект. Текстура также масштабируется, чтобы полностью покрыть объект. Для этого используем отрицательное значение 6, а не положительное. Это обращение необходимо, чтобы изображение накладываемой текстуры было обычным, а не перевернутым. С помощью этой уловки можно переворачивать текстуру. Затем мы увеличиваем значение переменной "t", чтобы начать создание следующего объекта.

Rem Проверка столкновения с декоративными объектами
Function DecoCollide(X#,Y#,Z#)

 for u = 1 to 9
  for v = 1 to 9
   if X#>u*1000-60
    if X#<u*1000+60
     if Z#>v*1000-60
      if Z#<v*1000+60
       if Y# < Get ground height(1,u*1000,v*1000)+575
        Collide=1
        Exitfunction Collide
       endif
      endif
     endif
    endif
   endif
  next v
 next u
 Collide=0

Endfunction Collide

Функции являются важной частью программирования. Их можно использовать для создания многих полезных и пригодных для повторного применения частей кода. Функция определяется после основного цикла, при этом используются ключевые слова "Function" и "EndFunction". После ключевого слова "Function" помещается имя создаваемой функции, а непосредственно за ним ставятся открывающая и закрывающая скобки. Внутри скобок помещаются переменные, с которыми работает код, находящийся в теле функции. Функция заканчивается ключевым словом "EndFunction". Чтобы функция возвращала какое-либо значение, необходимо поместить переменную, содержащую это значение, после ключевого слова "EndFunction". В середине функции находится команда "ExitFunction" с последующей переменной "Collide". Чтобы прервать выполнение функции, не дожидаясь выполнения остального кода, достаточно ввести команду "ExitFunction" для выхода из функции и возврата результата.

Function DecoCollide(X#,Y#,Z#)

Обратите внимание на переменные "X#", "Y#" и "Z#" внутри функции. Это совсем не те переменные, которые используются для указания координат игрока. Хотя имена переменных совпадают, все переменные, объявленные в функции, называются локальными и используются только внутри ее. Любые переменные, определенные вне функции, недоступны внутри ее. Все переменные, создаваемые внутри функции, уничтожаются при выходе из нее. Функция может использовать только значения переменных, указанных в скобках при определении функции. Посмотрите на команду "Object Angle Y(10)" - это функция, встроенная в DarkBASIC. Ее параметр 10, а возвращаемое значение - угол по оси Y для объекта с номером 10. Если какой-либо код вы применяете в программе многократно, то, возможно, его следует вводить в программу как функцию. В этом уроке мы используем функцию "DecoCollide()" для проверки столкновения игрока, монстра и ракеты со всеми декоративными колоннами путем ввода в функцию координат X, Y и Z объекта.

  for u = 1 to 9
  for v = 1 to 9
   if X#>u*1000-60
    if X#<u*1000+60
     if Z#>v*1000-60
      if Z#<v*1000+60
       if Y# < Get ground height(1,u*1000,v*1000)+575
        Collide=1
        Exitfunction Collide
       endif
      endif
     endif
    endif
   endif
  next v
 next u
 Collide=0

Два приведенных выше вложенных цикла похожи на те, что мы использовали при создании колонн. Колонны имеют в основании размеры 100х100 единиц, высоту 600 единиц, и заглублены в землю на 25 единиц. Так как колонны расположены на матрице через каждые 1000 единиц, мы используем циклы для вычисления столкновения с каждой колонной. Для проверки значений координат X# и Z# каждой колонны используются вложенные выражения сравнения "If". Мы добавляем и вычитаем по 60 единиц из переменных цикла, умноженных на 1000. На самом деле мы проверяем на 10 единиц больше, чем реальные габариты колонн, благодаря чему игрок не застревает между колонны. Первая колонна проверяется в координатах со значением 1000, если игрок находится в координатах (1059, 50, 10059), это дальний угол колонны. Проверяются следующие параметры. Значение координаты по оси X больше 940? Если да, то продолжаем последовательно выполнять вложенные сравнения. Если значение координаты по оси X меньше 1060, значение координаты игрока по оси Z меньше 1060, значение координаты игрока по оси Y меньше, чем высота колонны плюс 575 единиц, то в таком случае мы имеем столкновение. Значение переменной "Collide" устанавливается равным 1. Другие колонны проверять не требуется - искомый ответ найден. Для выхода из функции и возврата значения переменной Collide используется команда ExitFunction. Теперь мы знаем, что игрок сталкивается с колонной, поэтому можем остановить его дальнейшее движение в направлении колонны. Если столкновение не обнаружено, значение Collide устанавливается равным 0 и функция заканчивается при помощи команды "EndFunction".

rem Обнаружение столкновений
 if DecoCollide(X#,Y#,Z#) = 1
  X#=oldX#
  Y#=oldY#
  Z#=oldZ#
 Endif

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

  if DecoCollide(bX#,bY#,bZ#) = 1 then BulletLife = 0
  if DecoCollide(MbX#,MbY#,MbZ#) = 1 then MonsterBulletLife = 0

Эти две строки кода помещаются в подпрограммах "ShootBullet" и "MonsterShootBullet" для проверки попадания ракета в одну из колонн. Если обнаружено столкновение, ракета прекращает свое существование.

     mX#=rnd(10000)
     mZ#=rnd(10000)
     mY#= get ground height(1,mX#,mZ#)
     If DecoCollide(mX#,mY#,mZ#) = 1
      mX#=X#
      mY#=Y#
      mZ#=Z#
     endif

    X#=rnd(10000)
    Z#=rnd(10000)
    Y#= get ground height(1,X#,Z#)
    If DecoCollide(X#,Y#,Z#) = 1
     X#=mX#
     Y#=mY#
     Z#=mZ#
    endif

Эти две части кода помещаются в подпрограммах "PlacePlayer" и "PlaceMonster". Функции "DecoCollide" проверяют, не находятся ли новые координаты игрока и монстра внутри колонн. Если функция возвращает значение 1, то новые координаты игрока и монстра устанавливаются идентичными друг другу, что приводит к возобновлению цикла по созданию новых случайных координат игрока и монстра до тех пор, пока не будут созданы координаты, находящиеся за пределами колонны.

14. Монстр выходит на охоту

Цель урока: показать, как устроить охоту монстра на игрока.

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

Rem Загружаем мишень
Load object "idle.x",3
Append Object "Walk.x",3,21

Эти строки кода вводятся до начала основного цикла. Команда "Append Object" загружает данные анимации из другого файла и добавляет их к существующему объекту, не загружая новый. Объекты в каждом из файлов, которые вы собираетесь "склеить", должны быть идентичными, в противном случае команда будет выполнена неправильно. Команда использует три параметра. Первый параметр - имя присоединяемого файла. Второй параметр - номер объекта, к которому вы хотите присоединить данные анимации. Третий параметр - номер кадра, в который требуется добавить анимацию. Если номер кадра больше, чем общее число кадров в первой последовательности анимации, команда будет выполнена неправильно.

  if DecoCollide(MbX#,MbY#,MbZ#) = 1
   MonsterBulletLife = 0
   BulletAvoidDeco = BulletAvoidDeco + 2
  Endif

  if MbY# < Get Ground height(1,MbX#,MbZ#)
   MonsterBulletLife=0
   ShootUp=3
  endif

Переменные "ShootUp" и "BulletAvoidDeco" добавлены в подпрограмму "MonsterShootBullet". Переменной "ShootUp" присваивается значение 3, если ракета монстра попала в "землю". Эта переменная будет использоваться для изменения угла, под которым стреляет монстр, чтобы ракета огибала рельеф местности. Переменная "BulletAvoidDeco" увеличивается каждый раз на 2, когда ракета попадает в одну из колонн. Эта переменная изменяет угол стрельбы монстра, чтобы ракета огибала преграды. Хотя монстр в этом случае стреляет не прямо в игрока, ракета имеет возможность самонаведения после того, как она была выпущена.

  Rem Простой ИИ для самонаводящейся ракеты монстра
MonsterAI:
   Point object 3,X#,Y#,Z#
   If AvoidDeco >0
    mA# = Object Angle Y(3)
    Dec AvoidDeco
    Yrotate object 3,WrapValue(mA#+AvoidDeco*60)
   endif

   Rem Перемещаем монстра в новое место
   Position Object 3,mX#,mY#,mZ#

   Rem Проверяем расстояние до игрока
   PDist=Sqrt((mX# - X#)^2 + (mY#+25 - Y#)^2 + (mZ# - Z#)^2)

   Rem Если игрок в зоне видимости, выпускаем ракету
   if PDist<1500
    if MonsterBulletLife=0 or MonsterBulletLife < 500-Pdist/10
     Point object 3,X#,Y#-25,Z#
     If BulletAvoidDeco > 0
      CornerAim = Rnd(1)
      mA# = object angle Y(3)
      if CornerAim = 0 then Yrotate Object 3,WrapValue(mA#+BulletAvoidDeco*10)
      if CornerAim = 1 then Yrotate Object 3,WrapValue(mA#+BulletAvoidDeco*-16)
      Dec BulletAvoidDeco
     Endif

     If ShootUp > 0
      mA# = object angle X(3)
      XRotate Object 3,WrapValue(mA#+ShootUp*-8)
      Dec ShootUp
     Endif

     Position object 102,mX#,mY#+25,mZ#
     Set object to object orientation 102,3
     MonsterBulletLife =500
     show object 102
     Loop sound 102

     Rem Воспроизводим цикл анимации объекта
     Loop Object 3,0,20
    Endif
   Endif

   if PDist>1000
    Rem Сохраняем старое положение
    OldmX# = mX#
    OldmZ# = mZ#
    OldmY# = mY#

    Rem Воспроизводим анимацию ходьбы
    Loop Object 3,21,46

    Rem Переместить монстра
    Move Object 3,7

    Rem Получаем новую позицию
     mX# = Object Position X(3)
     mZ# = Object Position Z(3)
    mY# = Get Ground Height(1,mX#,mZ#)

    Rem Проверка столкновения с колоннами
    If DecoCollide(mX#,mY#,mZ#) = 1 and AvoidDeco = 0
     mX# = OldmX#
     mZ# = OldmZ#
     mY# = OldmY#
     AvoidDeco = 3
    Endif
   Endif
Return

В подпрограмме "MonsterAI" мы добавили код, необходимый для того, чтобы монстр обходил преграды, а также код, меняющий угол стрельбы монстра, в случае, если две переменные, описанные выше, имеют значение отличное от 0.

   If AvoidDeco >0
    mA# = Object Angle Y(3)
    Dec AvoidDeco
    Yrotate object 3,WrapValue(mA#+AvoidDeco*60)
   endif

Если значение переменной "AvoidDeco" больше 0, ее значение уменьшается на 1, а также изменяются углы поворота монстра путем добавления величины "AvoidDeco", умноженной на 60, к текущим углам поворота монстра. Когда монстр натыкается на колонну, переменная "AvoidDeco" принимает значение 3. При каждом проходе цикла монстр перемещается сначала на 180, затем на 120, а потом на 60 градусов. Это заставляет монстра полукругом отойти назад от того места, где он "уткнулся" в преграду. Эта часть кода показывает, как монстр перемещается между преградами.

     If BulletAvoidDeco > 0
      CornerAim = Rnd(1)
      mA# = object angle Y(3)
      if CornerAim = 0 then Yrotate Object 3,WrapValue(mA#+BulletAvoidDeco*10)
      if CornerAim = 1 then Yrotate Object 3,WrapValue(mA#+BulletAvoidDeco*-10)
      Dec BulletAvoidDeco
     Endif

Логика проверки переменной "BulletAvoidDeco" аналогична той, что описана выше, только величина изменения углов полета ракеты не такая большая. Когда ракета первый раз попадает в колонну, переменная "BulletAvoidDeco" принимает значение 2. Если ракета снова попадает в колонну, к этому значению прибавляется 2. Это делается до тех пор, пока ракета не сможет обогнуть преграду. Ракета выстреливается вправо или влево случайным образом, что увеличивает шансы того, что она пролетит мимо преграды.

   if PDist>1000
    Rem Сохраняем старое положение
    OldmX# = mX#
    OldmZ# = mZ#
    OldmY# = mY#

    Rem Воспроизводим анимацию движения
    Loop Object 3,21,46

    Rem Перемещаем монстра
    Move Object 3,7

    Rem Получаем новое положение
     mX# = Object Position X(3)
     mZ# = Object Position Z(3)
    mY# = Get Ground Height(1,mX#,mZ#)

    Rem Проверка столкновения с преградой
    If DecoCollide(mX#,mY#,mZ#) = 1 and AvoidDeco = 0
     mX# = OldmX#
     mZ# = OldmZ#
     mY# = OldmY#
     AvoidDeco = 3
    Endif
   Endif

Эта часть кода управляет перемещением монстра. Сначала мы сохраняем предыдущие координаты монстра, прежде чем начать перемещать его. Затем воспроизводим цикл анимации ходьбы при помощи команды "Loop Object". В данном случае у этой команды на два параметра больше, чем в предыдущем. Два параметра после номера объекта - это диапазон воспроизводимых кадров. Это те кадры, которые мы добавили к объекту ранее. Анимация воспроизводится в цикле, пока мы перемещаем объект. Потом мы сохраняем новые координаты монстра и проверяем, не сталкивается ли он с препятствиями. Если столкновение происходит, мы не меняем значение координат монстра и устанавливаем значение "AvoidDeco" равным 3, заставляя монстра полукругом обойти объект.

   If ShootUp > 0
      mA# = object angle X(3)
      XRotate Object 3,WrapValue(mA#+ShootUp*-8)
      Dec ShootUp
     Endif

Выражение сравнения для переменной "ShootUp" также добавлено к подпрограмме "MonsterAI". Если ракета монстра попадает в "землю", то переменная "ShootUp" принимает значение 3, а угол выстрела ракеты монстра увеличивается на 24 градуса. При каждом проходе цикла угол уменьшается на 8 градусов. Это дает возможность ракете монстра лететь по наилучшей траектории в направлении игрока.

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

  В конце концов у вас должно получиться следующее.


Выпуск закончил 31 октября 2002 года в 11:45 мск


(C) 2002 Илья Середа
http://darkbasic.narod.ru - это и так понятно :-)
    http://virland.narod.ru - "Домашняя киностудия"
     http://sereda.narod.ru - "ВАЗ 1111 ОКА"

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное