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 юзаю
в тесте создается только один блиттер


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

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