НАВИГАЦИЯ
Главная
Учебник
Файлы
Новости
Примеры
Ссылки
Сообщения
Форум
От создателя







Создание пламени

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

Итак, создадим два файла: flame.bb и flamfunctions.bb. Первый файл будет основным, а второй будет подключаться к первому. В файле flamfunctions.bb будут описаны структура и функции пламени.

I. Начнём с описания структуры и функций.
Структура (назовём её atoms):

Type atoms
Field spark,lvtime,alph#,scle#
End Type


Поля: spark - поле, в котором будут храниться адресы каждого спрайта; lvtime - счетчик жизни спрайтов в циклах; alph# - поле прозрачности спрайтов; scle# - поле изменения размеров спрайта.

II. Создадим функцию, которая будет отвечать за создание спрайтов пламени:
Function create_flame(sp,px#,py#,pz#,sc#,cr,cg,cb)
End Function


Параметры функции: sp - значение адреса загруженного спрайта; px#,py#,pz# - начальное положение спрайта; sc# - начальный размер спрайта; сr,cg,cb - значение цвета спрайта. Добавим в нашу функцию следующий код:

Function create_flame(sp,px#,py#,pz#,sc#,cr,cg,cb)
fl.atoms=New atoms
If sp=0 Then sp=CreateSprite(): HideEntity sp
fl\spark=CopyEntity(sp)
PositionEntity fl\spark,px#,py#,pz#
EntityColor fl\spark,cr,cg,cb
fl\scle#=sc#
fl\alph#=1
End Function


Работа алгоритма функции create_flame:
1) Создаётся запись в структуре.
2) Если значение переменной загруженного ранее спрайта равно 0, то создаём спрайт (защита от ошибки) и делаем его невидимым.
3) Копируем спрайт и заносим его адрес в запись fl\spark.
4) Меняем позицию спрайта.
5) Меняем цвет спрайта.
6) Записывем размер спрайта в fl\scle#.
7) Устанавливаем прозрачность 1 для fl\alph#.

III. Создадим функцию, которая будет отвечать за динамику спрайтов пламени:
Function update_flame(lt,spx#,spy#,spz#,sa#,sc#,an#)
End Function


Параметры функции: lt - значение жизни спрайта; spx#,spy#,spz# - значение текущей позиции спрайта; sa# - коэффициент изменения прозрачности; sс# - коэффициент изменения размера спрайта; an# - угол поворота срайта.

Добавим в функцию update_flame код:
Function update_flame(lt,spx#,spy#,spz#,sa#,sc#,an#)
For fl.atoms=Each atoms
MoveEntity fl\spark,spx#,spy#,spz#
TurnEntity fl\spark,Rnd#(an,-1*an),0,Rnd#(an,-1*an)
fl\alph#=fl\alph#+sa
EntityAlpha fl\spark,fl\alph#
fl\scle#=fl\scle#+sc#
ScaleSprite fl\spark,fl\scle#,fl\scle#
fl\lvtime=fl\lvtime+1
If fl\lvtime=lt Then
FreeEntity fl\spark
Delete fl
End If
Next
End Function


Функция работает так:
1) Цикл For будет проверять все записи в структуре.
2) Движение текущего спрайта.
3) Вращение текущего спрайта.
4) Меняем значение прозрачноти fl\alph#.
5) Установим прозрачность текущего спрайта.
6) Меняем значение размера fl\scle#.
7) Изменим размер текущего спрайта.
8) Увеличиваем счётчик жизни на 1 для fl\lvtime.
9) Если значение жизни равно параметру lt, то удаляем спрайт и запись в структуре.

ИТАК, мы создали файл flamfunctions.bb. Полностью он выглядит так:
Type atoms
Field spark,lvtime,alph#,scle#
End Type

Function create_flame(sp,px#,py#,pz#,sc#,cr,cg,cb)
fl.atoms=New atoms
If sp=0 Then sp=CreateSprite(): HideEntity sp
fl\spark=CopyEntity(sp)
PositionEntity fl\spark,px#,py#,pz#
EntityColor fl\spark,cr,cg,cb
fl\scle#=sc#
fl\alph#=1
End Function

Function update_flame(lt,spx#,spy#,spz#,sa#,sc#,an#)
For fl.atoms=Each atoms
MoveEntity fl\spark,spx#,spy#,spz#
TurnEntity fl\spark,Rnd#(an,-1*an),0,Rnd#(an,-1*an)
fl\alph#=fl\alph#+sa
EntityAlpha fl\spark,fl\alph#
fl\scle#=fl\scle#+sc#
ScaleSprite fl\spark,fl\scle#,fl\scle#
fl\lvtime=fl\lvtime+1
If fl\lvtime=lt Then
FreeEntity fl\spark
Delete fl
End If
Next
End Function


Теперь осталось использовать наши функции в файле flame.bb:
Graphics3D 1024,768
SetBuffer BackBuffer()
Include "flamfunctions.bb"
;подключили файл
cam=CreateCamera()
PositionEntity cam,0,0,-5

sp=LoadSprite("flame.jpg")
; шаблон спрайта
HideEntity sp

Repeat
create_flame(sp,0,0,0,0.3,250,120,0)
update_flame(24,0,0.06,0,-0.04,-0.01,-2)

RenderWorld
Flip
Until KeyHit(1)
End
У меня получилось такое пламя:
Пламя

Функции следует писать внутри основного цикла. Функцию update_flame испльзуют один раз, а create_flame - много раз (изменяя её, соответсвенно, параметры). Ещё я советую использовать монохромную картинку спрайта.

Можете загрузить пример пламени: Flame.zip(1,9 кб)
X