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







Создание эффекта дождя.

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

I. Создадим два файла: rain.bb и rainfunct.bb.
Откроем файл rainfunct.bb и объявим в нём структуру:

Type rain
Field sprt,sprt2,alph#,alph2#,life,sp2x#,sp2y#
End Type

Что означает каждое поле: sprt - поле, в котром будет храниться адрес каждого спрайта дождя; sprt2 - поле, в котором будет храниться адрес спрайта кругов; alph# - поле прозрачности спрайта дождя; alph2# - прозрачность спрайта кругов; life - ; жизнь спрайтов дождя и кругов; sp2x#,sp2y# - координаты спрайтов кругов по оси x и y.

II. создадим функцию CreateRain():

Function CreateRain(parent,num,scx#,scy#,nx#,fx#,ny#,fy#,nz#,fz#,spx#,spy#,spz#,s2y#,spa#,lf%,lf2%,s2c#,spr)
End Function

Описание её параметров: parent - имя объекта, относительно которого будет идти дождь; num - количество спрайтов капель, созданных за один цикл; scx#,scy# - размер спрайта капли; nx#,fx# - координаты отклонения спрайтов по оси X; ny#,fy# - координаты отклонения спрайтов по оси Y; nz#,fz# - координаты отклонения спрайтов по оси Z; spx#,spy#,spz# - скорость движения спрайтов; s2y# - позиция кругов по оси y; spa# - коэффициент изменения прозрачности спрайтов; lf - время жизни спрайтов (в циклах); lf2 - время создания кругов;spr - адрес на спрайт кругов от дождя.

Напишем в функции алгоритм дождя:
Function CreateRain(parent,num,scx#,scy#,nx#,fx#,ny#,fy#,nz#,fz#,spx#,spy#,spz#,s2y#,spa#,lf%,lf2%,s2c#,spr)

If num>50 Then num=50

For i=1 To num
flg.rain=New rain
flg\sprt=CreateSprite()
SpriteViewMode flg\sprt,4
If parent<>0
PositionEntity flg\sprt,EntityX(parent)+Rnd#(nx#,fx#),EntityY(parent)+Rnd#(ny#,fy#),EntityZ(parent)+Rnd#(nz#,fz#)
Else
PositionEntity flg\sprt,Rnd#(nx#,fx#),Rnd#(ny#,fy#),Rnd#(nz#,fz#)
End If
ScaleSprite flg\sprt,scx#,scy#
flg\alph#=1
Next

For flg.rain=Each rain
MoveEntity flg\sprt,spx#,spy#,spz#
flg\alph#=flg\alph#+spa#
EntityAlpha flg\sprt,flg\alph#
flg\life=flg\life+1

If flg\life=lf2

If spr<>0
flg\sprt2=CopyEntity(spr)
Else
flg\sprt2=CreateSprite(spr)
End If

SpriteViewMode flg\sprt2,2
RotateEntity flg\sprt2,90,0,0
PositionEntity flg\sprt2,EntityX(flg\sprt),s2y#,EntityZ(flg\sprt)
ScaleSprite flg\sprt2,flg\sp2x#,flg\sp2x#
flg\alph2#=1
End If

If flg\sprt2<>0
flg\sp2x#=flg\sp2x#+s2c#
ScaleSprite flg\sprt2,flg\sp2x#,flg\sp2x#
flg\alph2#=flg\alph2#-0.02
EntityAlpha flg\sprt2#,flg\alph2#

End If If flg\life=lf%
FreeEntity flg\sprt
FreeEntity flg\sprt2
Delete flg
End If
Next

End Function
Алгоритм работает так:
1) Если кол-во создаваемых за цикл спрайтов больше 50 (num), то равно 50. Это позволяет защитить от большого числа объектов, чтобы комп не тормозил.
2) В цикле от 1 до num создаем запись в тип и спрайты дождя по указанным параметрам в функции (позиция, прозрачность, размер).
3) В этом же цикле, если parent не равен 0 (т.е. указана переменная объекта или адрес), то позиция спрайтов изменяется относительно него, иначе относительно нулевых координат.
4) Во втором цикле For flg.rain=Each rain пишем команды, отвечающие за динамику спрайтов, изменение прозрачности и их удалении.
5) В этом же цикле, если время жизни равно значению lf2%, то создаются спрайты кругов кругов в указанной позиции, с поворотом на 90 градусов по оси x. Причем, если спрайт вдруг не загружен, то создаётся обычный квадратный спрайт.
6) Далее идет проверка, если существует спрайт кругов (flg\sprt2<>0), то изменяется его масштаб и прозрачность.
7) Если значение жизни текущего спрайта равна параметру lf% (flg\life=lf%), то удаляем объекты и запись в структуре. Вот весь алгоритм функции.

Полностью файл rainfunct.bb выглядит так:
Type rain
Field sprt,sprt2,alph#,alph2#,life,sp2x#,sp2y#
End Type


Function CreateRain(parent,num,scx#,scy#,nx#,fx#,ny#,fy#,nz#,fz#,spx#,spy#,spz#,s2y#,spa#,lf%,lf2%,s2c#,spr)

If num>50 Then num=50

For i=1 To num
flg.rain=New rain
flg\sprt=CreateSprite()
SpriteViewMode flg\sprt,4
If parent<>0
PositionEntity flg\sprt,EntityX(parent)+Rnd#(nx#,fx#),EntityY(parent)+Rnd#(ny#,fy#),EntityZ(parent)+Rnd#(nz#,fz#)
Else
PositionEntity flg\sprt,Rnd#(nx#,fx#),Rnd#(ny#,fy#),Rnd#(nz#,fz#)
End If
ScaleSprite flg\sprt,scx#,scy#
flg\alph#=1
Next

For flg.rain=Each rain
MoveEntity flg\sprt,spx#,spy#,spz#
flg\alph#=flg\alph#+spa#
EntityAlpha flg\sprt,flg\alph#
flg\life=flg\life+1

If flg\life=lf2

If spr<>0
flg\sprt2=CopyEntity(spr)
Else
flg\sprt2=CreateSprite(spr)
End If

SpriteViewMode flg\sprt2,2
RotateEntity flg\sprt2,90,0,0
PositionEntity flg\sprt2,EntityX(flg\sprt),s2y#,EntityZ(flg\sprt)
ScaleSprite flg\sprt2,flg\sp2x#,flg\sp2x#
flg\alph2#=1
End If

If flg\sprt2<>0
flg\sp2x#=flg\sp2x#+s2c#
ScaleSprite flg\sprt2,flg\sp2x#,flg\sp2x#
flg\alph2#=flg\alph2#-0.02
EntityAlpha flg\sprt2#,flg\alph2#

End If If flg\life=lf%
FreeEntity flg\sprt
FreeEntity flg\sprt2
Delete flg
End If
Next

End Function

Теперь осталось использовать этот алгоритм в программе.
Откроем файл rain.bb и напишем в нём, например, вот такой код:
Graphics3D 1024,768,0,2
SetBuffer BackBuffer()

Include "rainfunct.bb"
;подключение файла с нашей функцией дождя

c=CreateCamera()
PositionEntity c,0,1,0
RotateEntity c,35,0,0

circ=LoadSprite("circ.bmp")
;загружаем спрайт кругов
HideEntity circ

pl=CreatePlane(4)
PositionEntity pl,0,-3,0
EntityAlpha pl,1
pltext=LoadTexture("water.jpg")
ScaleTexture pltext,5,5
EntityTexture pl,pltext

CameraFogMode c,True
CameraFogRange c,0,30

Repeat
TranslateEntity c,0,0,0.01
createrain(c,4,0.005,0.2,-8,8,5,6,2,15,0,-0.4,0,-2.9,-0.03,75,20,0.004,circ)
;наша функция дождя
RenderWorld
Flip
Until KeyHit(1)
End

Некоторые замечания по поводу функции:
1) Если хотите, чтобы не было кругов, то ставьте значение lf2%=0.
2) Функцию использовать только внутри цикла, иначе ничего двигаться не будет.
Итак, вот что получилось:
Дождь

Можете скачать пример:Rain.zip(7,54 кб)



X