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

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

  Все выпуски  

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


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


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

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

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

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


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

      1. Новости.

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

      3. DarkBASIC повзрослел. (Окончание).




Новости

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

  В конце этого месяца Crow Interactive собирается выложить в Интернете демоверсию своей игры ARMAGEDDON. А пока видеоролик игры вы можете скачать (
часть-1 и часть-2). Ролик разбит на две части для удобства скачивания.

  Новости сайта Russian Dark Basic Developers Network:

  • Недавно в России был издан DarkMATTER. Что же мы получим купив данный диск? Во-первых, мы получаем патч версии 1.10, который снимает ограничения патча 1.13. Данный патч позволяет работать с библиотеками dll,с блоками памяти, предоставляет доступ к обратному буферу для управления структурами графических и звуковых данных, и команды для создания мультиплеерных приложений и игр. Так же на диске вы найдете 107 моделей (оружие, машины, люди, и модели неба) и 180 качественных текстур. Большинство моделей анимированы и присутствуют в двух вариантах (низкое качество и хорошее качество). Все модели представленны в форматах 3ds и x. Текстуры представлены в форматах bmp и jpg. Также присутсвует игра 3d solitare (могли видеть на втором диске Дарк Бейсика), игра Bumper to Bumper и замена стандартному редактору CodeKEEPER(похож на редактор Дарк Бейсика Про).На диске присутствуют две полезные утилиты. Первая - DBmakeDDS. Данная программа конвертирует файлы формата bmp в формат dds. Вы можете использовать файлы формата DDS, чтобы автоматически добавлять уровни мипмэппинга к вашим файлам формата BMP и использовать непосредственно в качестве текстур на ваших моделях. DarkBASIC автоматически пытается загрузить файл формата DDS вместо файла формата BMP и использует данные мипмэппинга, содержащиеся в нем. Данные мипмэппинга используются, чтобы удалить эффект размытия пикселов, когда модели рассматриваются издалека. Другое преимущество файлов формата DDS заключается в том, что они меньшего размера, чем эквивалентные им по размеру файлы формата BMP. Вторая программа позволяет конвертировать модели формата 3DS в формат X. На диске есть несколько интересных исходников.

  • В разделе Готовые игры появилась новая игра - CooL Driver. Многие из вас наверняка играли в карманную игру Ралли. CooL DriveR чем-то напоминает ее, только выполнен в полном 3D. Скоро появится сама игра, а возможно и исходник.

  • На официальном сайте DB pro вышел первый патч. Интересно, почему разработчики стали нумеровать патчи не как в DB 1 (v 1.01, 1.09c, 1.13), а в виде: патч 1, патч 2 и т.д. В любом случае, патч можно скачать, а также посмотреть список исправлений, здесь. НО! Придется вас расстроить - патч предназначен только для коробочного DB pro, а таких в России по пальцам пересчитать можно (начиная с мизинца и заканчивая им). Но если вы такие же нехорошие, как и я, то можете распаковать winrar-ом содержимое в папку с ДБпро. Удачи!
    Внимание, мое мнение совем не обязательно совпадает с администрацией сайта. И я не призываю к действиям, описанным здесь.




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

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

III. ИГРА

10.Монстр отстреливается

Цель урока: показать, как создать игровую ситуацию, когда монстр начинает отстреливаться.

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

rem Создаем снаряд монстра
Make Object Sphere 102,2
texture object 102,2
Hide Object 102

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

rem Создаем эффект взрыва для монстра
Make Object Sphere 130,20
texture object 130,2
ghost object on 130
Hide Object 130
Make Object Sphere 131,20
texture object 131,2
ghost object on 131
Hide Object 131

Этот код также вставляется в программу до основного цикла. Он создает объекты взрыва для ракеты монстра.

rem Загружаем шлейф ракеты монстра
Load Image "fire.bmp",2
For x  =100 to 110
 Make object plain x+10,5,5
 Texture object x+10,2
 Set object x+10,1,0,0
 Ghost object on x+10
 Hide object x+10
Next x

MPn=110

Как вы заметили, эта часть кода взята из эффекта шлейфа снаряда игрока. Сам код остался прежним, изменились только номера объектов. Счетчик частиц шлейфа ракеты монстра "MPn" установлен в значение 110, что соответствует номеру первого объекта в совокупности частиц этого шлейфа.

Load 3Dsound "fireball2.wav",102
Load 3Dsound "Explode.wav",103

Этот код загружает звуковые эффекты для ракеты монстра. Заметьте, что мы не задействовали повторно звуковые эффекты, использованные ранее для снаряда игрока. Мы загрузили новые звуки, потому что звуковые эффекты для снарядов игрока и монстра могут воспроизводиться одновременно.

 If MonsterBulletLife > 0 then Gosub MonsterShootBullet
 If MonsterExplode > 0
  Gosub MonsterExplodeRocket
 else
   Gosub MonsterAI
 endif

Этот код помещается в нашем основном цикле. Здесь производится проверка времени "жизни" ракеты монстра, продолжительности ее взрыва и выполняются соответствующие подпрограммы, как и в отношении снаряда игрока. Добавилась лишь подпрограмма "MonsterAI". Мы ведь не хотим, чтобы монстр пытался стрелять в то время, когда взрывается предыдущий снаряд. Чтобы убедиться, что этого не происходит, мы используем сравнение "If Then Else".

Rem Простой AI для управляемой ракеты монстра
MonsterAI:
   Point object 3,X#,Y#,Z#
   PDist=Sqrt((mX# - X#)^2 + (mY#+25 - Y#)^2 + (mZ# - Z#)^2)
   if PDist<1500
    if MonsterBulletLife=0 or MonsterBulletLife < 500-PDist/10
     Point object 3,X#,Y#-25,Z#
     Position object 102,mX#,mY#+25,mZ#
     Set object to object orientation 102,3
     MonsterBulletLife =500
     show object 102
     Loop sound 102
    Endif
   endif
Return

Когда вызывается подпрограмма"MonsterAI", объект "монстр" направлен прямо на игрока. Рассчитывается расстояние между игроком и монстром. Если оно меньше 1500, то продолжается выполнение кода. Если игрок находится вне зоны видимости, ничего не происходит и подпрограмма далее не выполняется, а продолжает выполняться код из основного цикла. Если игрок находится в пределах досягаемости, программа проверяет, не закончилось ли время "жизни" ракеты и не попала ли она в игрока. Способ, с помощью которого мы проверяем, попала ли ракета в цель, заключается в вычислении значения "500-PDist/10". Ракета монстра пролетает 12 единиц координат в единицу своей "жизни". Время ее жизни составляет 500, таким образом, она может преодолеть расстояние в 6000 единиц. Если мы разделим расстояние, или величину переменной "PDist", на 12, то получим число единиц "жизни", которое ракета монстра затратила на подлет к игроку. Если расстояние между монстром и игроком составляет 1200 единиц, то необходимое на подлет к игроку число единиц "жизни" ракеты будет равно 100. Если мы вычтем эту величину из общего числа единиц "жизни" ракеты, то получим 400. Если это значение больше, чем значение переменной "MonsterBulletLife", тогда мы знаем, что ракета не попала в игрока. Мы делим расстояние на 12, а не на 10, что позволяет снаряду пролететь немного дальше, прежде чем можно будет выстрелить еще раз. Это делает игру более реалистичной, позволяя ракете пролететь мимо игрока. Если значение переменной "MonsterBulletLife" позволяет выстрелить еще раз, ракета монстра нацеливается прямо на координаты игрока. Ракете монстра задаются начальные и конечные координаты, устанавливается время ее "жизни" равное 500, объект "ракета" становится видимым и начинает воспроизводиться ее звук.

Rem Выстрел ракеты монстра
MonsterShootBullet:
  Dec MonsterBulletLife
  Move object 102,12

  MbX#=Object position X(102)
  MbY#=Object position Y(102)
  MbZ#=Object position Z(102)

  inc MPn
  if MPn=121 then MPn=110
  Scale object MPn,100,100,100
  Position object MPn,MbX#,MbY#,MbZ#
  Position sound 102,MbX#,MbY#,MbZ#
  point object MPn,X#,Y#,Z#
  Zrotate object MPn,rnd(180)
  Show object MPn
  for x = 1 to 10
   scale object int((Wrapvalue((MPn-9+x)*36))/36)+110,100+x*25,100+x*25,100+x*25
  next x

  if MbY# < Get Ground height(1,MbX#,MbZ#) then MonsterBulletLife=0
  Pdist=Sqrt((X# - MbX#)^2 + (Y#+25 - MbY#)^2 + (Z# - MbZ#)^2)
  if  Pdist<50
   GoSub PlacePlayer
   MonsterBulletLife = 0
  endif
  Rem Управляемая ракета
  if Pdist <500 and Pdist>250 then Point object 102,X#,Y#,Z#
  if Pdist < 100 then point object 102,X#,Y#,Z#

  if MonsterBulletLife = 0
   Hide object 102
   stop sound 102
   for x=110 to 120
    hide object x
   next x
   MonsterExplode = 20
  endif
Return

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

  Rem Управляемая ракета самонаведения
  if Pdist <500 and Pdist>250 then Point object 102,X#,Y#,Z#
  if Pdist < 100 then point object 102,X#,Y#,Z#

Это код для управляемой ракеты самонаведения. Если ракета находится на расстоянии от 500 до 250 единиц от игрока, она самонаводится по текущим координатам игрока. Находясь на расстоянии 100 единиц от игрока, ракета снова получает текущие координаты цели. Это дает игроку немного времени на попытку уклониться от ракеты.

Rem Взрыв ракеты монстра
MonsterExplodeRocket:
 Position object 130,MbX#,MbY#,MbZ#
 Show object 130
 Position object 131,MbX#,MbY#,MbZ#
 Show object 131
 EScale=20*(30-MonsterExplode)
 Scale object 130,EScale,EScale,EScale
 Yrotate object 130,WrapValue(MonsterExplode*37)
 Scale object 131,EScale/1.5,EScale/1.5,EScale/1.5
 Yrotate object 131,WrapValue(359-MonsterExplode*37)
 Dec MonsterExplode
 If MonsterExplode = 0 then hide object 130: Hide object 131
 If MonsterExplode=18
  position sound 103,X#,Y#,Z#
  play sound 103
 endif
 If MonsterExplode < 15 then position sound 103,X#,Y#,Z#
Return

Код подпрограммы "MonsterExplodeRocket" такой же, как и в подпрограмме "ExplodeRocket". Единственное, что отличает эти две подпрограммы - это переменные координат ракеты монстра и номера объектов и звуков.


11. Как вести счет

Цель урока: показать, как ведется счет игры.

В этом уроке мы покажем, как отслеживать счет игры для игрока и монстра, а также как перемещать игрока и монстра в новое положение, когда их поражает снаряд или ракета.

Gosub PlaceMonster
Gosub PlacePlayer

Мы поместили две команды "Gosub" до основного цикла. Соответствующие подпрограммы помещают игрока и монстра на случайные позиции матрицы.

PlaceMonster:
   mX#=X#
   mZ#=Z#
   mY#=Y#
   While Sqrt((X# - MX#)^2 + (Y#+25 - MY#)^2 + (Z# - MZ#)^2)<1600
     mX#=rnd(10000)
     mZ#=rnd(10000)
     mY#= get ground height(1,mX#,mZ#)
   EndWhile

   Position object 3,mX#,mY#,mZ#

Return

Подпрограмма "PlaceMonster", предназначенная для установки случайных координат монстра на матрице, первоначально устанавливает для монстра те же координаты, что и координаты игрока и затем проверяет, чтобы монстр и игрок находились на достаточном расстоянии друг от друга. Первоначальная установка одинаковых координат является необходимым условием для генерации случайной позиции. В тексте этой подпрограммы мы используем цикл "While", чтобы обеспечить определенное условие: цикл повторяется до тех пор, пока расстояние между игроком и монстром не станет больше 1600. Для вычисления расстояния между игроком и монстром мы используем формулу вычисления расстояний из урока по математическому столкновению. Если расстояние меньше 1600, снова выполняется код поиска позиции. Новая случайная позиция рассчитывается и сохраняется в переменных положения монстра. Когда расстояние между игроком и монстром становится больше 1600, цикл завершается и монстр помещается в новом месте.

PlacePlayer:

   While Sqrt((X# - mX#)^2 + (Y#+25 - mY#)^2 + (Z# - mZ#)^2)<1000
    X#=rnd(10000)
    Z#=rnd(10000)
    Y#= get ground height(1,X#,Z#)
    EndWhile

   Position camera X#,Y#,Z#
 
Return

Подпрограмма "PlacePlayer" аналогична подпрограмме "PlaceMonster". Различие только в том, что мы помещаем на матрицу игрока, а не монстра. Мы также направляем камеру в сторону монстра, чтобы его было легче найти.

 set cursor 550,20
 print "MScore: ",MonsterScore
 set cursor 550,40
 print "PScore: ",PlayerScore

Этот код помещается внутри основного цикла. Используя команду "Set cursor", помещаем текст в правой части экрана. В позиции курсора выводим слова "MScore" и "PScore", чтобы показать игровой счет монстра и игрока. Затем выводим значения переменных "MonsterScore" и "PlayerScore".

 if Sqrt((mX# - bX#)^2 + (mY#+25 - bY#)^2 + (mZ# - bZ#)^2) <20
   Gosub PlaceMonster
   inc PlayerScore
   MonsterBulletLife = 1
   BulletLife=0
  endif

Эта часть кода из подпрограммы "ShootBullet", которая проверяет, был ли монстр поражен снарядом игрока. Мы добавили в сравнение "If" две строки кода. Если монстр был поражен, вызывается подпрограмма "PlaceMonster", чтобы поместить его в новом месте. Затем мы увеличиваем счет игры в пользу игрока, изменяя переменную "PlayerScore" при помощи команды "Inc".

Pdist=Sqrt((X# - MbX#)^2 + (Y#+25 - MbY#)^2 + (Z# - MbZ#)^2)
  if  Pdist<50
   GoSub PlacePlayer
   MonsterBulletLife = 0
   inc MonsterScore
  endif

Эта часть кода из подпрограммы "MonsterShootBullet", которая, как и предыдущая, проверяет, был ли поражен игрок ракетой монстра. В случае поражения, вызывается подпрограмма "PlacePlayer", помещающая игрока в новом месте. После этого мы увеличиваем счет игры в пользу монстра при помощи команды "Inc" и возвращаемся в подпрограмму "MonsterShootBullet".

12.HUD

Цель урока: создание "вида сверху" и простого экрана радара.

В этом уроке мы покажем, как создать "вид сверху", также известный как HUD (heads up display). Чтобы упростить задачу поиска монстра, мы создадим экран радара на нашем виде сверху и прозрачный задний план для отображения счета игры.

rem Создаем HUD
Make object Plain 200,1,1
position object 200,-2.7,1.9,4
Lock object on 200
ghost object on 200

Эта часть кода помещается до основного цикла. Мы создаем плоский объект и привязываем его к положению камеры. Эта плоскость будет использоваться в качестве экрана радара.

Make object Plain 201,1,1
position object 201,2.7,1.9,4
Lock object on 201
ghost object on 201

Эта часть кода также вводится до основного цикла. Плоский объект будет использоваться в качестве заднего плана для экрана отображения счета игры.

rem Загружаем и создаем растровые изображения hud
Load Bitmap "Radar.bmp",2
Create Bitmap 1,50,50

В этой части кода мы загружаем изображение радара и сохраняем его как изображение под номером 2. Растровое изображение отличается от текстуры. На нем можно рисовать и оно может быть изменено в самой программе. Особенно важным является растровое изображение под номером 0. Это изображение становится вашим экраном, на котором вы видите 3D-сцену. При вызове команды "Sync" именно это изображение перерисовывается и отображается. Мы загружаем изображение "Radar.bmp" в изображение под номером 2 и создаем новое пустое изображение, присваивая ему номер 1. Имейте в виду, что в DarkBASIC можно загрузить или создать не более 32 изображений. Команда "Load Bitmap" аналогична команде "Load Image". Первый параметр - имя загружаемого растрового изображения. Второй параметр - присвоенный ему номер - уникальный идентификатор изображения. Команда "Create Bitmap" создает в памяти пустое изображение указанного размера. Первый параметр - номер, присваиваемый изображению. Второй и третий параметры - это ширина и высота создаваемого растрового изображения. Параметры ширины и высоты представляют собой размеры изображения в пикселах.

 Rem Создаем радар
 Copy Bitmap 2,1
 set current bitmap 1
 ink rgb(0,0,255),rgb(0,0,0)
 PRX#=X#/200
 PRZ#=50-(Z#/200)
 Circle PRX#,PRZ#,1
 ink rgb(255,0,0),rgb(0,0,0)
 MRX#=mX#/200
 MRZ#=50-(mZ#/200)
 Circle MRX#,MRZ#,1
 Get image 200,0,0,50,50
 set current bitmap 0
 texture object 200,200
 ink rgb(255,128,128),rgb(0,0,0)

Этот код помещается ближе к концу основного цикла. Так создается, прорисовывается и накладывается на плоскость экран радара.

 Copy Bitmap 2,1

Команда "Copy Bitmap" копирует одно растровое изображение из памяти в другое, также находящееся в памяти. Первый параметр этой команды - номер копируемого изображения. Второй параметр - номер изображения, в которое вы хотите скопировать первое. Здесь мы копируем изображение, загруженное для заднего плана экрана радара в изображение, которое мы будем использовать в качестве экрана радара.

 set current bitmap 1

С помощью команды "Set Current Bitmap", вы указываете программе, что определенное изображение будет изображением для рисования по умолчанию. Чтобы вновь увидеть 3D-сцену, вы должны установить номер текущего изображения снова равным 0. Текущим мы делаем изображение радара. Оно содержит скопированное изображение, которое мы загрузили для заднего плана радара.

 ink rgb(0,0,255),rgb(0,0,0)

Команда "Ink" применяется для установки значения цвета переднего и заднего плана для любой команды рисования или текста. Первый параметр команды "Ink" - это цвет, используемый для рисования на переднем плане. Чтобы указать голубой цвет, мы применяем команду "RGB". Второй параметр - цвет заднего плана, или фона. При помощи команды "RGB" мы устанавливаем для него черный цвет.

 PRX#=X#/200
 PRZ#=50-(Z#/200)
 Circle PRX#,PRZ#,1

С помощью этих трех строк кода рисуется голубая окружность на изображении радара, представляющая игрока. Переменные "PRX#" и "PRZ#" используются для хранения координат игрока. Так как наша матрица - квадрат со стороной 100000 единиц, а растровое изображение радара - квадрат со стороной 50 пикселов, то мы делим 100000 на 50 и получаем 200. 200 - это переменная масштабирования. Мы делим значение координаты X игрока на 200, чтобы получить примерное значение координаты X на экране радара, и сохраняем эту величину в переменной "PRX#". Те же вычисления повторяем и для координаты по оси Z. Так как отсчет координат растрового изображения начинается в левом верхнем углу, а координат матрицы - в левом нижнем, мы берем масштабированное значение Z и вычитаем его из 50 для того, чтобы получить обращенное значение для экрана радара. Если этого не сделать, то экран радара будет отображать обращенные координаты.

 Circle PRX#,PRZ#,1

Мы используем координаты X и Z игрока на радаре, чтобы с помощью команды "Circle" нарисовать окружность по этим координатам на изображении радара. Первые два параметра этой команды - это координаты X и Y центра окружности на изображении. Третий параметр - радиус окружности. Мы установили этот параметр равным 1, чтобы нарисовать очень маленький кружок.

 ink rgb(255,0,0),rgb(0,0,0)
 MRX#=mX#/200
 MRZ#=50-(mZ#/200)
 Circle MRX#,MRZ#,1

Эти строки кода аналогичны приведенным выше, только мы устанавливаем цвет красным и используем переменные X и Y монстра для рисования окружности, которая символизирует монстра на радаре.

 Get image 200,0,0,50,50

Команда "Get Image" копирует изображение или его часть для использования в качестве текстуры. Первый параметр этой команды - это номер создаваемого изображения. Второй и третий параметры - координаты X и Y левого верхнего угла прямоугольной области, которую мы желаем скопировать. Четвертый и пятый параметры - координаты правого нижнего угла этой прямоугольной области. Так как наше изображение имеет размеры 50х50 пикселов, мы копируем изображение целиком. Наше основное изображение - это по-прежнему изображение под номером 1, откуда и копируется изображение для текстуры.

 set current bitmap 0
 texture object 200,200
 ink rgb(255,128,128),rgb(0,0,0)

Последняя часть кода радара снова устанавливает в качестве текущего изображение под номером 0, в котором и происходит прорисовка нашей 3D-сцены. Затем мы накладываем на плоский объект текстуру из только что созданного изображения. Оно содержит картинку радара с нарисованными на ней двумя кружками, соответствующими игроку и монстру. Меняем цвет из красного на матовый красный. Этот цвет будет использоваться до обновления изображения на экране радара. Отметим, что значения счета в игре выводятся тем же цветом.

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



DarkBASIC повзрослел. (Окончание).

А теперь снова о пресловутых матрицах-ландшафтах. В DBPro господа из DarkBasic Software Ltd. окончательно ставят меня в тупик. Дело в том что в группе функций "World" (которая сама по себе новая) кроме функций для работы с BSP уровнями присутствует отдельный блок функция для работы с... Ландшафтами (!). Здесь они, как и полагается, названы ландшафтами. Чем же они отличаются от матриц-ландшафтов?
Способом создания, а способ весьма крут. Чтобы создать ландшафт нужно указать черно-белую картинку и движок создаст по ней ландшафт! Круто да? Светлые участки - возвышения, темные - впадины. После этого, можно натянуть цветную текстуру ландшафта. Только вот непонятно, зачем надо было размазывать общие функции по разным группам.

Не 3D единым: Давайте посмотрим, какие изменения в 2D части, тем более, многие слышали громкое заявление авторов DBPro, что времена медленного 2D дескать, кончились.

А вот и нет. Это не времена кончились, а 2D скончался :-).

Для осмысления выше сказанного и нижеследующего текста проведу небольшой экскурс в историю. До приобретения DarkBasic наша команда (CloneSoft) кочевряжилась над собственным 3D движком. Дык вот, в нашем движке для отображения 2D интерфейса на экране мы написали блок функций отвечающих за это дело и все объединили в общий модуль под названием "название_движка_Interface_2D" который базировался на низкоуровневых функциях 2D (на них же был повешен и 3D). Короче движок дает более 700 (!) FPS при отображении истинного 2D TrueColor на Celeron 566 MHz 128 Mb с TNT Pro 32 Mb. Такое количество FPS достигается благодаря очень умному 2D движку и возможностью отключения VSync.

В DarkBasic классический 2D движок, работающий "по старинке". Я, было, подумал, что господа из DarkBasic Software Inc. дотямкали как ускорить 2D, ан нет. Не сообразительные. Они пошли другим путем - вырезали 2D и заменили его 3D.

А что, не помните их слоган из DB - "Будущее 2D это 3D".

Группа функций BITMAP по-прежнему работает с истинным 2D, т.к. их назначение не вывод изображения, а манипуляции с ним.

Функции IMAGE и SPRITE теперь базируются на 3D.

LOAD IMAGE теперь работает так:

1. Создается 3D полигон
2. Грузится картинка и натягивается на полигон как текстура.
3. Созданный полигон не вносится в список рендеринга.

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

Все функции SPRITE теперь работают так же - мы имеем дело не с картинками, а с полигонами (поэтому спрайтам стала доступна такая фича как аппаратный альфа-канал - эффект прозрачности).

Координаты можно по-прежнему указывать в виде 2D координат экрана, движок сам преобразовывает их 3D.

Кстати, шрифт теперь тоже 3D, поэтому символы теперь сглаживаются по краям.

Что дает переход с 2D на 3D? Два эффекта - сглаживание и альфа-канал. Недостаток - если размеры картинки Вашего спрайта не кратны 2, то 3D движок DBPro создавая из нее текстуру, для наложения на полигон, автоматически подтянет ее размер под этот стандарт, а затем, для устранения корявых пикселов, сгладит. Короче, на экране спрайт выглядит несколько мутновато.

Вывод. Если Вы только начали работать над интерфейсом своей игры и делаете его в 3D срочно переходите на 2DDBPro, естественно) - эффект тот же, плюс удобная система координат.

Раз уж мы заговорили о 2D, давайте посмотрим, что новенького в "Aniamtion" (сдесь собраны функции воспроизведения видео).

В DB мы могли воспроизводить только AVI. В DBPro этот список расширился, добавили поддержку MPG формата и несколько экзотических. Последние нам в упор не нужны, а вот MPG большой шажок в сторону профессионального геймдевелопмента. Если в Вашей игре будут видеовставки, делайте их в MPG формате. Почему? Я ничего не имею против AVI, это отличный формат, но у него есть одно достоинство превращающееся в существенный недостаток при использовании в играх. Это отсутствие собственного видео кодека. AVI является всего лишь хранилищем для видео, сжимаемого разными подключаемыми кодеками. А кто может гарантировать, что кодек, который Вы использовали для сжатия своих мувисов, окажется на машине юзверей? Конечно Вы можете распространять кодек с игрой, но тут появляются глюки с установкой и настройкой. Так поступают только последние ламаки и чайники. Профессионалы пользуются системонезависимыми форматами. Лидер - Bink Video кодирующий по стандарту DVD. Большинство современных игрушек использует этот формат. На втором месте - MPG. Этот формат также не зависит ни от каких кодеков. MPG - выбор профессионала. Хотя, если позволяют средства, рекомендую купить Bink SDK у RAD Gametools, благо DBPro поддерживает подключение DLL.

Ну и заканчивая описание движка, вернемся к проектной панели, раздел "Settings". Если кто помнит, настройки, содержащиеся в рамке "Display Settings" я оставил на потом, т.к. эти настройки касаются непосредственно движка.

Не буду объяснять Вам действие переключателей "Windowed" и "Windowed - Desktop", это и ежу понятно. Важнее ознакомится с полноэкранным режимом, т.к. здесь произошли кардинальные изменения.

И так. У нас по-прежнему имеется режим "Fullscreen Exclusive Mode". Рядом имеется пимпа "Pick" позволяющая задать стартовое разрешение экрана, которое Вы затем можете изменить в своей программе функцией "Set Display Settings".

Что ж. Этот режим нам знаком по DB. Но в DBPro появился еще и "Windowed - FullScreen". Что-то не понятно - Оконный - Полноэкранный. Вот тут самое интересное.

Для тех не знаком с Microsoft Direct3D (а именно на этом 3D движке и работает DBPro) - разработчики Direct3D в руководстве программиста на каждом шагу доказывают, что самый лучший режим это полноэкранный эксклюзивный. Только в этом режиме все ресурсы отдаются нашей программе и т.п. И действительно, их доводы подтверждаются тестами FPS.

В DarkBasic использовался этот режим, но FPS был весьма низок. Я решил, что это из-за слабого движка, но тут в DBPro, к эксклюзивному режиму добавился полноэкранный-оконный и теперь я в недоумении.

Смотрите сами. Запускаю программу в эксклюзивном режиме, FPS такой же, как и в DarkBasic (!): Запускаю в полноэкранном-оконном - 80 FPS (!). Хоть убейте из рогатки не пойму в чем суть (суть в сортире - замечание прохожего :-).

Объясняю, как работают эти два режима.

Эксклюзивный - запрашивает у системы все ресурсы и сообщает GDI что программе нужен весь экран. Система приостанавливает все процессы, GDI отдает экран. DirectDraw (2D часть DirectX) меняет разрешение на требуемое переключая монитор и захватывает первичный буфер видеокарты (содержимое этого буфера Вы и видите на экране). Когда вы вызываете функцию "Sync", DBPro рендерит картинку в задний буфер и затем отражает на экран аппаратным методом "flip". При использовании флиппинга первичный и вторичный (задний) буфера просто меняются местами. Сообразительные сразу догадались, что это очень быстрый метод.

Как работает режим "Windowed - Fullscreen" - так же как и оконный, но при этом создается простое плоское окно без всяких  рюшечек и растягивается на весь экран. Затем, нужно как-то переключить разрешение экрана на то, которое требует наша программа, а об этом не может быть и речи, т.к. режим то у нас оконный!

И что же делает движок DBPro? А вот что. Допустим разрешение Вашего DeskTop'а 800x600. Следовательно, первичный буфер имеет такое же разрешение. Ваша же программа запрашивает 640x480. В этом случае DBPro создает задний буфер (в нем и происходит создание кадра) размером 640x480, а когда вы вызываете функцию "Sync" (рендеринг) он рендерит 3D сцену в задний буфер и переносит его содержимое на экран, т.е. первичный буфер, растягивая до 800x600 аппаратным методом - блиттинг. Т.е. в этом режиме функция "Set Display Settings" не меняет разрешение монитора физически, а лишь создает задний буфер указанного размера.

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

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

Допустим у юзверя (к которому попала Ваша игра) текущее разрешение экрана 1024x768, а Ваша игрушка сработана под 640x480. Конечно же, движок DBPro сделает все как я писал и юзверь увидит картинку на весь экран, но с побочными действиями как то: сильное искажение интерфейса, он будет растянут и для устранения артефактов сглажен - юзверь увидит муть; более низкий FPS, чем тот, на который мы рассчитывали при создании игрушки.

Есть ли выход из этой ситуации? Да.

Первый путь состоит в том, чтобы использовать эксклюзивный режим, но здесь по причине низкого FPS вы сильно сузите круг пользователей вашей гамесы.

Второй путь - написать DLL (на C++ или Delphi) с функцией переключения разрешения. Затем при старте в оконном-полноэкранном режиме Ваша DBPro программа переключит разрешение монитора на нужное, а уже после этого можно применить функцию "Set Display Settings" и тогда мы получим задний буфер равный по размеру первичному, а это - качественная картинка и высокий FPS!

Часть четвертая: Язык

Теперь коротко :-) о языке.

Свершилось! Теперь на DBPro станет программировать намного легче. Можете браться за мощную РПГ и т.п. А все потому что появилась поддержка пользовательских типов.

Что такое тип? Тип это Ваш друг :-). Вы сэкономите многие часы, если будете пользоваться типами вместо массивов (массивы, конечно же, тоже пригодятся).

Смотрите сами. Допустим в нашей РПГ есть пять персонажей у каждого по пять характеристик. Раньше Вы хранили бы это в массиве:

Dim characters(5,5)

Ну, мы сохранили в этом массиве номера моделей и характеристики персонажей (жизнь, сила, ловкость и т.п.)

А где хранить имена? Придется добавить еще массивчик:

Dim char_names$(5)

Удобно? Да это же нервотрепка!

Смотрите, как это делается с типом:

`Объявляем тип
Type type_Characters
       Char_Names$(5)
       Char_Lifes(5)
       Char_Power(5)
EndType

`Присваиваем переменной
t_Characters As type_Characters

Теперь в любом месте программы (там где нужно, например, увеличить силу персонажу) пишем:

t_Characters.Char_Power(3) = t_Characters.Char_Power(3) + 10

Этой строчкой я увеличил силу третьего персонажа на десять пунктов.

Думаю, Вы просекли фишку. К сожалению, пользоваться ею не удобно. В VB и C++ после нажатия точки всплывает список со всеми переменными типа и нужно лишь щелкнуть в нужную переменную в списке. В DBPro же придется держать все переменные типа в голове или записывать на листок. Но все равно, теперь нам будет намного легче.

Добавлю ложку дегтя в бочку дерьма :-). Объявлять типы можно только в главном модуле вашего проекта. В противном случае DBPro вообще их не воспримет, да еще обматерит Вас трехэтажным.

Отсюда вывод - создать некий Game Engine (надстройку к DBPro) использующий типы, в одном модуле, а затем запросто подключать его к новым проектам Вам не удастся, т.к. типы должны быть объявлены в главном модуле. Придется постоянно интегрировать модуль в проект извращенным способом - вырезанием объяв типов и вставлением в главный модуль.

Заключение

Вот Вы мы подошли к концу, пора делать выводы и давать рекомендации.

Покупать или не покупать - вот в чем вопрос. На этот вопрос я спокойно отвечу - ДА!

Когда покупать и у кого? Мой Вам совет - не в коем разе не покупайте DBPro сейчас! Первые версии программ (да чего угодно) всегда содержат массу глюков и недоделок. Вспомните как нам повезло с DB - англичанам досталась глючная версия 1.0 и им еще патчи качать пришлось. Нам же - уже обкатанная 1.09с с гораздо большим количеством функций и альтернативным редактором в одном флаконе!

А пока, в ожидании Российской версии лицензионного DBPro рекомендую скачать демо с официального сайта, пока халяву не обломали - не пожалеете.

David Good

advcoder@mail.ru

www.clonesoft.narod.ru


Выпуск закончил 18 октября 2002 года в 13:00 мск


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

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

В избранное