forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   2D-программирование (http://forum.boolean.name/forumdisplay.php?f=13)
-   -   нужна помощь по типам(эффект молнии) (http://forum.boolean.name/showthread.php?t=17159)

pepel 08.08.2012 19:02

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

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

Вобщем нужно както считать шаги для каждой ветки
Может отдельным типом запилить, чет ваще незнаю=(
*неудачный код закоментил"

Прикрепил картинку как должно быть и ехе того что получается покачто...


код:

PHP код:

Graphics 640,480,16,2
SetBuffer BackBuffer 
()


Type spline
    Field x
#,y#,new_x#,new_y#,num%,direction#,speed#,velosity#,end_spline%,set_direction%,branch%,num_branch%
End Type 

create_spline
(300,20)
create_spline(130,20)
create_spline(160,20)
Global 
last_direction#,set_direction%,last_num%,branch%
Global  number_line[30]

;
_________________________________________________________________________________+
Repeat
SeedRnd MilliSecs
() 
    
update_spline()

    For 
s.spline=Each spline
        
;Text 0,0,s\branch
    Next
    Text 0
,0,number_line[0]
    
Flip
    Cls

Until KeyDown
(1)
;
_________________________________________________________________________________|

Function 
create_spline(x,y,start=0,num_branch%=0)

    
s.spline=New spline
    s
\x=X
    s
\y=y
    s
\direction=Rnd(30,140)
    
s\speed=2
    
If start s\direction=Rnd(20,150):    s\branch=branch:    ;:number_line[num_branch]=0
    
;num_branch=s\branch
    
;If num_branch<1 number_line[num_branch]=number_line[num_branch]+1
    
    
End 
Function



Function 
update_spline(dist#=16,degradation%=4)
    
    
For s.spline =Each spline
        
;Если это не конец сплайна до движемся по рандомному углу
        
If s\end_spline=0
            
If s\new_x=0 s\new_x=s\x:  If s\new_y=0 s\new_y=s\y
            s
\new_x=s\new_x+Cos(s\direction)*s\speed
            s
\new_y=s\new_y+Sin(s\direction)*s\speed
        End 
If
        
        If 
last_direction<>0
            
;last_direction 
        End 
If
        
        
dx#=s\x-s\new_x
        
dy#=s\y-s\new_y
        
local_dist#=Sqr(dx^2+dy^2)
        
;If number_line[s\branch]>5     create_spline(s\new_x,s\new_y):branch=branch+1
        
;Если дистанция больше установленнойостанавливаем движение
        
If s\end_spline=And local_dist>dist
            s
\end_spline=1
            
;last_direction=s\direction
            create_spline
(s\new_x,s\new_y,s\branch)
        EndIf
        
Line s\x,s\y,s\new_x,s\new_y
    Next

End 
Function 


Жека 09.08.2012 11:15

Ответ: нужна помощь по типам(эффект молнии)
 
Вложений: 1
Привет. В общем, я сделал нечто похожее на молнию из твоего кода, глянь картинку.
В коде есть комментарии.
Работает удаление всех молний, но не работает удаление конкретно взятой.
В местах ответвления я создаю новые два "сплайна" (так они у тебя называются)
TBranch - это не целая ветка молнии, это отрезок.

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

Анимация появления отрезков завязана на время, типа dt = Rand(20,50)

ПРОБЕЛ - создать новые молнии с удалением текущих.

Стиль кода смешанный получился, т.к. ты и я разные именования предпочитаем и я не стал твои исправлять штуки.

Да и вообще это черновой вариант-заготовка, улучшить можно.

Код:

Код:

SeedRnd MilliSecs() 

Graphics 640,480,16,2
SetBuffer BackBuffer ()

create_spline(150,20,Rnd(20,30),0, 0,Null)
create_spline(300,20,Rnd(20,30),0, 0,Null)
create_spline(450,20,Rnd(20,30),0, 0,Null)
Global last_direction#,set_direction%,last_num%,branch%
Global number_line[30]



;_________________________________________________________________________________+
Repeat
        If(KeyHit(57)) ;создаём заново по пробелу
                delete_splines(Null)
                create_spline(150,20,Rnd(20,30),0, 0,Null)
                create_spline(300,20,Rnd(20,30),0, 0,Null)
                create_spline(450,20,Rnd(20,30),0, 0,Null)
        EndIf
        update_spline()
        draw_spline()
    Flip
    Cls
       
Until KeyDown(1)

End
;_________________________________________________________________________________|

Function create_spline(x#, y#, size%, id%=0, num_branch%=0, root.TSpline, direction%=0)
        If(num_branch = 0) Then num_branch = Rand(2,6) ;количество веток, после которых развилка будет
        Local s.TSpline = New TSpline
        If(root = Null) Then root = s
        root\total = root\total+1
        s\root = root
    s\x = x
    s\y = y
        s\size_x = size
        s\size_y = size
        s\num = 0
        s\num_branch = num_branch
        s\counter = id
        DebugLog("create_SPLINE, num = "+s\num_branch)
        create_branch(s, direction)
End Function


Function create_branch.TBranch(s.TSpline, direction%=0, createSpline%=True)
        DebugLog("create_branch")
       
        ;если создали уже нужное количество веток, то от последней ветки создаём ответвление, с некоторой вероятностью
        If(s\done = False And s\num = s\num_branch)
                DebugLog("try to create 2 new splines")
                If(createSpline = True And (Rand(100)<20 Or s\counter < 3)) ;не менее трёх развилок чтоб было
                        Local dir% = 1
                        If(Rand(100) > 50) Then dir = -dir ;
                        create_spline(s\lastBranch\new_x, s\lastBranch\new_y, s\size_x, s\counter+1, 0, s\root, dir) ;две новые ветки делаем
                        create_spline(s\lastBranch\new_x, s\lastBranch\new_y, s\size_x, s\counter+1, 0, s\root, -dir) ;расходятся в разные стороны
                EndIf
                s\done = True
                s\root\doneCount = s\root\doneCount+1 ;запоминаем сколько уже завершилось, чтоб удалить когда все создались
               
                DebugLog("s\root\doneCount = "+s\root\doneCount)
                DebugLog("s\root\total = "+s\root\total)
               
                If(s\root\doneCount = s\root\total)
                        DebugLog("----------s\root\doneCount = s\root\total------")
                        ;все ветки достроились, можно удалить например
                        ;delete_splines(s\root) ;коряво удаляет почему-то
                EndIf
               
                Return
        EndIf
       
        Local br.TBranch = New TBranch
        Local x#, y#
        If(s\lastBranch = Null) ;ещё нет веток
                x = s\x
                y = s\y
                s\firstBranch = br
                s\lastBranch = br
                DebugLog("last is null")
        Else
                x = s\lastBranch\new_x
                y = s\lastBranch\new_y
                s\lastBranch\nxt = br ;текущему последнему в качестве следующей ветки назначаем только что созданную ветку br
                s\lastBranch = br ;а сам последний теперь ссылается на новую br
                DebugLog("last is not null")
        EndIf
   
        br\x = x
        br\y = y
        ;br\new_x = x + Rnd(-s\size_x, s\size_x)
        ;br\new_y = y + Rnd(s\size_y/2.0, s\size_y)
       
        If(direction = 0)
                If(Rand(100) > 50)
                        direction = -1
                Else
                        direction = 1
                EndIf
        EndIf
               
        Local angle#
        If(direction = -1) ;влево ветка
                angle = Rnd(90,160)
        Else
                angle = Rnd(20,90)
        EndIf
       
        br\new_x = x + s\size_x * Cos(angle)
        br\new_y = y + s\size_x * Sin(angle)
       
       
        s\num = s\num+1 ;увеличиваем количество веток в сплайне
        DebugLog("s\num = "+s\num)
       
        s\timeCreateBranchStart = MilliSecs()
        s\timeCreateBranchDelay = Rand(20,50)
       
        Return br ;возвращаем новую ветку, может пригодиться вне функции
End Function

Function update_spline()
        Local s.TSpline
    For s = Each TSpline
                ;DebugLog("update_spline")
               
                If(s\done = False)
                        ;пришло ли время создать новую ветку?
                        If(MilliSecs() >= s\timeCreateBranchStart + s\timeCreateBranchDelay)
                                create_branch(s)
                        EndIf
                ;Else
                EndIf
               
                ;If(s\root\doneCount = s\root\counter
        Next
End Function


Function draw_spline()
        Local br.TBranch, s.TSpline
    For s = Each TSpline
                br = s\firstBranch
                While(br <> Null)
                        Line(br\x, br\y, br\new_x, br\new_y)
                        br = br\nxt
                Wend
        Next
End Function


Function delete_splines(spline.TSpline)
        Local br.TBranch, s.TSpline, tmp.TBranch
    For s = Each TSpline
                If(spline = Null Or s\root = spline)
                        br = s\firstBranch
                        While(br <> Null)
                                tmp = br
                                br = br\nxt
                                Delete(tmp)
                        Wend
                        Delete(s)
                EndIf
        Next
End Function



Type TSpline
    Field x#,y#,new_x#,new_y#,num%,direction#,speed#,velosity#,end_spline%,set_direction%,num_branch%
        Field firstBranch.TBranch, lastBranch.TBranch ;ссылки на ветки, чтобы пробегать по ним в цикле
        Field timeCreateBranchStart%, timeCreateBranchDelay% ;время создания
        Field size_x#, size_y# ;максимальные размеры каждой ветки
        Field done% ;больше не создаём
        Field doneCount%
        Field counter% ;порядковый номер в цепочке сплайнов
        Field root.TSpline ;головной сплайн
        Field total%
End Type 

;ветка
Type TBranch
        Field x#,y#,new_x#,new_y#
        Field num% ;порядковый номер
        Field nxt.TBranch ;следующая ветка
End Type


pepel 09.08.2012 12:22

Ответ: нужна помощь по типам(эффект молнии)
 
спасибо! ща буду разбиратся. как я и думал лучше наверно типом отдельным делать

burovalex 02.11.2012 00:10

Ответ: нужна помощь по типам(эффект молнии)
 
Да, делай типом отдельным. Всё очень просто.
Я делал растущие цветы http://forum.boolean.name/showthread.php?t=16605

В кратце суть такая, создаёшь вручную один отрезок, задаешь ему порядковый номер (1), задаешь поле handle - что это основная ветка, а от нее уже будут отростки.
И всё, "выращиваешь отрезок, создаешь новый с порядковым номером 2, с нужными смещениями, изменениями.
А потом провераешь, какой порядковый максимальный у handle, на каком порядковом номере создать отросток (у него уже не будет handle), и т.д. и т.п.


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

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