forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Полезные функции (http://forum.boolean.name/forumdisplay.php?f=17)
-   -   Дым (http://forum.boolean.name/showthread.php?t=20)

SubZer0 04.09.2005 21:28

Пример создания дыма:

для начала сохраните у себя на компьютере в какую-нибудь папку следующие текстуры:





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

Код:

;устанавливаем видеорежим и ставим текущий буфер видеопамяти на задний фон
Graphics3D 1024,768,16,1
SetBuffer BackBuffer()

; определяем тип для облачков дыма
Type SmogT

Field SHandle%
Field STime%
Field SSpeed#
Field ScaleIndex#
Field ScaleI#
Field SAlpha#
Field SAlphaSpeed#

End Type

; создаем камеру и помещаем ее так, чтоб нам было наш дымящийся объект
camera=CreateCamera()
PositionEntity camera,0,15,-25
RotateEntity camera,10,0,0

;создаем свет
RotateEntity CreateLight(),0,45,0

;загружаем наши текстуры как спрайты
sm2=LoadSprite("smog2.bmp",1)
sm1=LoadSprite("smog1.bmp",1)
; скрываем их, чтоб они не мешались на экране
HideEntity sm2
HideEntity sm1

; создаем шарик который будет дымиться
smogobject=CreateSphere()

; здесь запускаем счетчик, он нам нужен для того, чтоб регулировать насыщенность дыма
; иными словами сколько шарик будет пускать облачков дыма за один проход общего цикла
CreateStep=4+Rnd(-2,2)
; запускаем цикл до нажатия клавиши ESC
Repeat

; уменьшаем наш счетчик на единицу, если он достиг нуля, то пускаем облачко дыма
CreateStep=CreateStep-1
If CreateStep=0

; создаем новый тип для облачка
Smog.Smogt=New Smogt
; копируем наш спрайт
Smog\SHandle=CopyEntity(sm1)
; сбрасываем счетчик времени
Smog\STime=0
; задаем скорость поднятия облачка ввоздух
Smog\SSpeed=0.15
; задаем начальные размеры облачка
Smog\ScaleIndex=1.5
; задаем величину изменения размеров облачка с каждым подняитием его ввоздух
Smog\ScaleI=-0.02
; задаем начальную прозрачность облачка
Smog\SAlpha=0.8
; задаем величину изменения прозрачности облачка с каждым поднятием его ввоздух
Smog\SAlphaSpeed=-0.02
; помещаем наше облачко над объектом горения
PositionEntity Smog\SHandle,EntityX(SmogObject),EntityY(SmogObject)+1,EntityZ(SmogObject)

; если вы запускали пример, то заметили, что дым состоит из двух потоков, красного (пламени) и серого (дыма)
; сверху мы создали поток облачков пламени, сейчас все тоже только с немного другими параметрами для дыма

Smog.Smogt=New Smogt
Smog\SHandle=CopyEntity(sm2)
Smog\STime=0
Smog\SSpeed=0.15
Smog\ScaleIndex=2
Smog\ScaleI=0.01
Smog\SAlpha=0.5
Smog\SAlphaSpeed=-0.005
PositionEntity Smog\SHandle,EntityX(SmogObject),EntityY(SmogObject)+1,EntityZ(SmogObject)

; если счетчик равен нулю, то чтоб поновой отмерялось время запускаем его снова
CreateStep=4+Rnd(-2,2)

EndIf

; по нажатию кнопки передвигаем наш дымящийся шарик
If KeyDown(200) Then MoveEntity SmogObject,0,0,0.5
If KeyDown(208) Then MoveEntity SmogObject,0,0,-0.5
If KeyDown(203) Then MoveEntity SmogObject,-0.5,0,0
If KeyDown(205) Then MoveEntity SmogObject,0.5,0,0

; а тут самое интересное, здесь идет обработка дыма, чтоб он взлетал ввоздух и растворялся
; запускаем цикл на весь тип (в нем с каждым проходом мы будем работать с каждым облачком дыма)
For Smog.SmogT=Each SmogT
; таймер для дыма, т.е. сколько раз каждое облачко должно быть обработано пока оно не будет удалено
If Smog\STime< 100
; поднимаем облачко на заданную скорость SSpeed
MoveEntity Smog\SHandle,Rnd(-0.05,0.05),Smog\SSpeed,Rnd(-0.05,0.05)
; рассчитываем и изменяем размер облачка
Smog\ScaleIndex=Smog\ScaleIndex+Smog\ScaleI
ScaleSprite Smog\SHandle,Smog\ScaleIndex,Smog\ScaleIndex

; рассчитываем и изменяем прозрачность облачка
Smog\SAlpha=Smog\SAlpha+Smog\SAlphaSpeed
EntityAlpha Smog\SHandle,Smog\SAlpha

; увеличиваем счетчик времени облачка
Smog\STime=Smog\STime+1
; если время больше заданного (100) то его (облачко) нужно удалить
If Smog\STime=100
; удаляем спрайт облачка
FreeEntity Smog\SHandle
; удаляем тип
Delete Smog
EndIf
EndIf
Next

; прорисовываем (обновляем) наш мир
RenderWorld
; обмениваем буфера видеопамяти, чтоб увидеть что у нас получилось,
; теперь все следующее будет
рисоваться в скрытый буфер
Flip

Until KeyHit(1)

; конец программы
End


SubZer0 04.09.2005 21:31

Примечание:

в зависимости от текстуры можно писать вот так:
Код:

sm2=LoadSprite("smog2.bmp",2)
sm1=LoadSprite("smog1.bmp",2)

:) :)

SubZer0 04.09.2005 21:33

А еще можно такую библу посмотреть.

(с) Impersonalis

:)

impersonalis 07.09.2005 00:47

не - делал не я. я только нарыл её )

SubZer0 17.09.2005 21:59

Вложений: 2
Можно еще вот такой дым сделать (см. аттач)

использование:

ObjectToSmog - делает объект дымящимся

параметры:
ObjectToSmog (
SmogObject% - идентификатор объекта который будет дымиться (например возвращенный созданием сферы)
Sprite% - идентификатор спрайта для дыма, возвращенный LoadSprite()
Timer% - таймер для дыма, для установки времени между пусканиями облачков дыма (в итерациях)
Height# - высота столба дыма (в блиц-координатах)
Speed# - скорость шага поднятия облачков дыма ввоздух (в блиц-координатах)
Radius# - на самом деле столб дыма не совсем столб, а как-бы конус расположенный острием вниз, дым ведь рассеивается, дак вот этим параметром можно настроить величину отклонения облачков дыма при движении вверх (в блиц-координатах)
Rotating From# - максимальная закрученность облачков дыма против часовой чтрелки
Rotating To# - максимальная закрученность облачков дыма по часовой чтрелке, на самом деле вызывается для каждого облачка rnd (Rotating From, Rotating To) что и определяет закрученность облаков в ту или иную сторону.
Size From# - начальный размер каждого облачка дыма
Size To# - размер достигаемый облачком при достижении высшей точки столба дыма
Alpha From# - прозрачность облачка дыма в самом начале
Alpha To# - прозрачность облачка дыма при достижении высшей точки столба дыма

)

RemoveSmog убирает дым с объекта

параметры:
RemoveSmog(
EntityHandle - идентификатор объекта на который был установлен дым
)

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

alcosholik 18.09.2005 17:37

Последний вариант дыма рулит! Особенно, если сравнить его с дымом в первом посте :)
Красиво и вполне реалистично. Респект. :super:

SubZer0 18.09.2005 20:22

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

Matt Merkulov 30.10.2005 01:42

Можно еще добавить анимацию и вращение. Так же и огонь можно сделать (в MaxPayne это было потрясно реализовано).

jimon 30.10.2005 12:21

а можно зделать клон lotusа
только использовать не спрайты, а блиттеры

я щас делаю систему партиклов на блиттерах
у maxusа вышло намного лутче 10 тыс обектов - 180 фпс
у меня 400 обектов - 120 фпс

правда у maxusа есть секрет :) и он им нехочет делится

ps. кто не в курсе lotus и lotus 2 ето самые красивые системы партиклов для блица , хотя они и самые тормозные

ps2. спрайт ето 2д еденица
а блиттер 3д

блиттер создается вот етим кодом :
Код:

mesh = CreateMesh()
surf = CreateSurface(mesh)
v0 = AddVertex (surf,-1,-1,0,0,1)
v1 = AddVertex (surf,1,-1,0,1,1)
v2 = AddVertex (surf,-1,1,0,0,0)
AddTriangle (surf,v0,v2,v1)
v3 = AddVertex (surf,1,1,0,1,0)
v4 = AddVertex (surf,1,-1,0,1,1)
v5 = AddVertex (surf,-1,1,0,0,0)
AddTriangle (surf,v3,v4,v5)
UpdateNormals mesh


pax 30.10.2005 20:56

2jimon Не вижку различий между блиттером и спрайтом у которого установлен режим "независим от камеры" - free тобишь. Может объяснишь в чем разница по конкретнее?

jimon 30.10.2005 22:39

спрайт рисуется 2д системой
а блиттер ето 3д иденица

у maxusа вышло что блиттеры быстрее спрайтов
у меня наоборот

я непонимаю

pax 30.10.2005 23:12

Цитата:

Originally posted by jimon@Oct 30 2005, 10:39 PM
спрайт рисуется 2д системой
а блиттер ето 3д иденица

у maxusа вышло что блиттеры быстрее спрайтов
у меня наоборот

я непонимаю

Я бы попробовал создавать много блиттеров в одном меше, храня в какихнить списках номера вертексов. Передвигал и поворачивал бы их с помощью VertexCoords.

Думаю так быстрее намного будет, только сложнее на столькоже :)

больше мыслей нет

PS: в своей игрухе я так делал, только не двигал ничего, просто заново создавал часть карты :)

pax 30.10.2005 23:55

Ответь мне тогда еще на один вопрос:

Если спрайт это 2D единица, то прокоментируй следующее (это из справки по блитцу):

Цитата:

Sprites have two real strengths. The first is that they consist of only two polygons; meaning you can use many of them at once. This makes them ideal for particle effects and 2D-using-3D games where you want lots of sprites on-screen at once.
Краткий перевод: У спрайтов два достоинства: 1-имеет два полигона, 2-идеален для создания частиц.

PS: просто немогу понять, как может 2Д единица иметь два полигона :dontknow:

PS2: И почему спрайтов нет в Blitz Basic 2D?

НУБ 31.10.2005 00:09

PАХ:
Спрайт - это не 2д единица, а 3д - квад из 2х поликов(но можно и 1), кот-й может быть повёрнут к камере.
в блице они организованы как отдельные объекты, поэтому тормозят.
так что их полюбому нужно делать как сингл-сурфейс :)

jimon 31.10.2005 18:58

2 ньюб - посмотри мой код создания блиттера
он правильный ? ничего неможеж зделать \ предложить чтобы ускорить рендер ?

copyentity юзаю
в тесте создается только один блиттер

pax 31.10.2005 23:09

Цитата:

copyentity юзаю в тесте создается только один блиттер
По мойму СopyЕntity тоже самое, что и функция создания блиттера :dontknow:

НУБ 01.11.2005 05:40

чтоб быстрее рисовался - надо всё в 1 сурфейс ложить, т.е. всё квады - 1 мешь (а по отдельности - это даже медленнее обычных спрайтов),
поворот на камеру - через поворот всех вершин.

jimon 01.11.2005 19:38

теперь понятно почему у maxus'а быстрее :)
ps. у него еще и программный z-buffer вроде :)

ps2. обясни примером работу с single surface :)
я слышал есть либа неплохая
можеж выложить ?

НУБ 01.11.2005 23:33

программный z-buffer - это ещё что за хрень такая? обычно так называют рендер в z(в цвет тоже) на проце ;) У них ни чего тагого нет и не надо, всё гораздо проще.

>обясни примером работу с single surface
А чего тут объяснять, создаёшь вершинный буфер размерностью 4*кол-воЧастиц и каждые 4 вершины из него - отдельная частица.
>я слышал есть либа неплохая
Есть - либа для партиклов Maxusa и Tormoza, обращайся к ним :))))
Я собсно тоже нечто подобное сделаю(конкретно под свою гаму), просто ради интереса :) если максус не против будет - выложу.

jimon 02.11.2005 00:00

вот я какрас и делаю чтото анологичное ихней либе
а программный z-buffer - всмысле они программно убирают блиттеры которых невидно :)

Diplomat 02.11.2005 00:04

Вроде ничего они не убирают: в демке с летящими листьями даже если в кадре всего пара листьев, всё равно ТрисРендеред= 20002 полигона. :dontknow:

jimon 02.11.2005 00:12

мне так максус говорил

< history icq >

jimon > программно както убираеш обекты которые непрорисовываются ? или оставляеш ето дело z-bufferу ?

maxus > програмно.

НУБ 02.11.2005 00:26

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

pax 04.11.2005 11:17

Цитата:

мне так максус говорил
< history icq >
jimon > программно както убираеш обекты которые непрорисовываются ? или оставляеш ето дело z-bufferу ?
maxus > програмно.

Незнаю... можно канечно включить режим VertexColors, а потом установить параметр Alpha = 0 (VertexColor surface,index,red#,green#,blue#,alpha#) для каждого вертекса блиттера, правда незнаю вырастет от этого производительность или нет...

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

PS: это только мысли :)


Часовой пояс GMT +4, время: 19:15.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot