purebasic.info

PureBasic forum
Текущее время: Пт июл 20, 2018 4:22 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 33 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: 2D физический движок
СообщениеДобавлено: Вс янв 11, 2009 11:26 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Сб авг 18, 2007 6:26 pm
Сообщений: 605
Откуда: Северодвинск/Питер
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Собственно, возвращаюсь к этой теме =) Наконец-то я смог написать нечто более-менее стабильно работающе, не сильно тормозное и не очень глюченное =)

Единственный вид примитива на данный момент(и, видимо, для этого движка =) ) - 2D сфера. Тем не менее, есть ещё связи между сферами, так что можно делать более сложные структуры =)
В будущем я, видимо, дополню движок разбиением пространства и другими фишками, но пока вот вам всего лишь 7 килобайт кода: :)
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
 
Procedure GetFPS()
  Static GetFPS_Count.l, GetFPS_FPS.l, GetFPS_Start.l
  GetFPS_Count + 1
  If GetFPS_Start = 0
    GetFPS_Start = ElapsedMilliseconds()
  EndIf
  If ElapsedMilliseconds() - GetFPS_Start >= 1000
    GetFPS_FPS   = GetFPS_Count
    GetFPS_Count = 0
    GetFPS_Start + 1000
  EndIf
  ProcedureReturn GetFPS_FPS
EndProcedure
 
#Obj_Flag_Immobility=1
#Obj_Flag_Unknown1 = 2
#Obj_Flag_Unknown2 = 4
#Obj_Flag_Unknown3 = 8
#Obj_Flag_Unknown4 = 16
#Obj_Flag_Unknown5 = 32
#Obj_Flag_Unknown6 = 64
#Obj_Flag_Unknown7 = 128
 
#Collision_Speed_K = 0.5
#Max_NumOfLinks = 4
Structure Ball
  X.f
  Y.f
  SX.f
  SY.f
 
  Radius.f
  Weight.f
 
  Elastify.f
  FLags.b
 
  NumOfLinks.b
  *Link.Link[4]
EndStructure
Structure Link
  Length.f
  Type.b
  MetaData.f[2]
  *Obj.ball[#Max_NumOfLinks]
EndStructure
 
Global NewList Obj.ball()
 
Procedure LinkObjs(*Obj1.Ball, *Obj2.Ball, LinkType.b, LinkParam1.f=0,LinkParam2.f=0) ; Устанавливает связь (джойнт) между объектами =)
  Protected *Link.Link
 
  If *Obj1 And *Obj2
    *Link=AllocateMemory(SizeOf(Link))
   
    *Link\Length=Sqr((*Obj1\X-*Obj2\X)*(*Obj1\X-*Obj2\X)+(*Obj1\Y-*Obj2\Y)*(*Obj1\Y-*Obj2\Y))
    *Link\Type=LinkType
    *Link\Obj[0]=*Obj1
    *Link\Obj[1]=*Obj2
   
    If *Obj1\NumOfLinks>=#Max_NumOfLinks:FreeMemory(*Link):ProcedureReturn 0:EndIf
    If *Obj2\NumOfLinks>=#Max_NumOfLinks:FreeMemory(*Link):ProcedureReturn 0:EndIf
   
    *Obj1\Link[*Obj1\NumOfLinks]=*Link
    *Obj1\NumOfLinks+1
   
    *Obj2\Link[*Obj2\NumOfLinks]=*Link
    *Obj2\NumOfLinks+1
   
    *Link\MetaData[0]=LinkParam1
    *Link\MetaData[1]=LinkParam2
     
    ProcedureReturn *Link
  Else
    ProcedureReturn 0
  EndIf
EndProcedure
 
Procedure SolveLinks(*Obj.Ball,dT.f=1.0) ;Просчитывает взаимодействия связей
  Protected *Link.link
  Protected Dist.f, dX.f, dY.f, dL.f
 
  For C=1 To *Obj\NumOfLinks
    *Link=*Obj\Link[C-1]
    If *Link
      If *Link\Obj[0] And *Link\Obj[1] And *Link\Type>0
        dX=*Link\Obj[0]\X - *Link\Obj[1]\X
        dY=*Link\Obj[0]\Y - *Link\Obj[1]\Y
        Dist=Sqr(dX*dX + dY*dY)
        dX=dX/(Dist+0.01)
        dY=dY/(Dist+0.01)
        dL=Dist - *Link\Length
       
        Select *Link\Type
        Case 1
          dL=dL+*Link\MetaData[1]
          *Link\Obj[0]\SX-dL*dX**Link\MetaData[0]*dT
          *Link\Obj[0]\SY-dL*dY**Link\MetaData[0]*dT
          *Link\Obj[1]\SX+dL*dX**Link\MetaData[0]*dT
          *Link\Obj[1]\SY+dL*dY**Link\MetaData[0]*dT
        EndSelect
      EndIf
    Else
      Continue
    EndIf
  Next
EndProcedure
 
Procedure RenderObj(*Obj.ball); Рисует объект.
  Circle(*Obj\X, *Obj\Y, *Obj\Radius, RGB(255,0,0))
EndProcedure
 
Procedure SolveCollisions(*Obj.ball,dT.f=1.0) ;Ищет пересечения, и, если они есть, обрабатывает.
  Protected dX.f, dY.f, Dist.f
  Protected Last=@Obj()
 
  If *Obj\Flags & #Obj_Flag_Immobility
    ProcedureReturn 0
  EndIf
 
  While NextElement(Obj())
    If *Obj <> @Obj()
      dX=-(*Obj\X - Obj()\X)
      dY=-(*Obj\Y - Obj()\Y)
      Dist = Sqr(dX*dX + dY*dY)
     
      Overlay.f = (*Obj\Radius + Obj()\Radius) - Dist
      If Overlay>=0
        dX=dX/(Dist+0.01):dY=dY/(Dist+0.01); Нормализация вектора
       
        If Obj()\Flags & #Obj_Flag_Immobility
          *Obj\X-dX*Overlay
          *Obj\Y-dY*Overlay
          *Obj\SX+dX*| style="color: #924B72;">#Collision_Speed_K*dT
          *Obj\SY+dY*| style="color: #924B72;">#Collision_Speed_K*dT
        Else
          *Obj\X-dX*(Overlay/2)
          *Obj\Y-dY*(Overlay/2)
          *Obj\SX+dX*| style="color: #924B72;">#Collision_Speed_K*dT
          *Obj\SY+dY*| style="color: #924B72;">#Collision_Speed_K*dT
          Obj()\X+dX*(Overlay/2)
          Obj()\Y+dY*(Overlay/2)
          Obj()\SX-dX*| style="color: #924B72;">#Collision_Speed_K*dT
          Obj()\SY-dY*| style="color: #924B72;">#Collision_Speed_K*dT
        EndIf
        Velocity1.f=(*Obj\SX*dX + *Obj\SY*dY)
        Velocity2.f=(Obj()\SX*dX + Obj()\SY*dY)
       
        E.f = (Obj()\Elastify + *Obj\Elastify)/2
       
        FinalVelocity1.f=((*Obj\Weight-E*|!REG3XP3!>Obj()\Weight)*Velocity1+(1+E)*|!REG3XP3!>Obj()\Weight*Velocity2)/(*Obj\Weight+Obj()\Weight)
        FinalVelocity2.f=((Obj()\Weight-E**Obj\Weight)*Velocity2+(1+E)**Obj\Weight*Velocity1)/(*Obj\Weight+Obj()\Weight)  
       
        *Obj\SX=*Obj\SX+(FinalVelocity1-Velocity1)*dX
        *Obj\SY=*Obj\SY+(FinalVelocity1-Velocity1)*dY
       
        Obj()\SX=Obj()\SX+(FinalVelocity2-Velocity2)*dX
        Obj()\SY=Obj()\SY+(FinalVelocity2-Velocity2)*dY
      EndIf
    EndIf
  Wend
  ChangeCurrentElement(Obj(), Last)
EndProcedure
 
Procedure SolveMotion(*Obj.Ball,dT.f=1.0);Просчитывает движение
  If *Obj\Flags & #Obj_Flag_Immobility
    *Obj\SX=0
    *Obj\SY=0
  Else
    *Obj\X = *Obj\X+*Obj\SX*dT
    *Obj\Y = *Obj\Y+*Obj\SY*dT
   
    Falloff.f = Pow(0.999,dT)
    *Obj\SX=*Obj\SX*Falloff;Сопростивление воздуха
    *Obj\SY=*Obj\SY*Falloff;Сопростивление воздуха
  EndIf
EndProcedure
 
Procedure AddObject(X.f, Y.f, Weight.f, Radius.f, E.f=0.5,Flags=0) ;написана для упрощения добавления объекта =)
  If AddElement(Obj())
    Obj()\X=X
    Obj()\Y=Y
    Obj()\Elastify = E
    Obj()\Radius=Radius
    Obj()\Weight=Weight
    Obj()\Flags=Flags
    ProcedureReturn @Obj()
  Else
    ProcedureReturn 0
  EndIf
EndProcedure
 
 
Global SW=GetSystemMetrics_(#SM_CXSCREEN)
Global SH=GetSystemMetrics_(#SM_CYSCREEN)
 
InitSprite()
InitKeyboard()
OpenScreen(SW, SH, 32, "")
 
;{ Создаём мир
Last=AddObject(C,100,10,5,0.3,#Obj_Flag_Immobility)
For C=15 To SW Step 30
  AddObject(C,100+Sin((C*3.1415)/SW)*200,5,5,0.3)
  LinkObjs(@Obj(),Last,1,0.3,0.0)
  Last=@Obj()
Next
Obj()\Flags=#Obj_Flag_Immobility
 
For I=0 To 35
  AddObject(5+SW*I/30 + 1-Random(2000)/1000, 30, 10, 25+Random(10), 0.3)
Next
 
AddObject(SW/2,500,100,100,0.5,#Obj_Flag_Immobility)
;}
 
 
DeltaTime.f=1.0 ; Интервал временного интегрирования.
Repeat
  ExamineKeyboard()
  ClearScreen(0)
 
  ForEach Obj()
    Obj()\SY+0.04*DeltaTime ;Гравитация
   
    ;{ Ограничения по экрану
    If Obj()\Y+Obj()\Radius>SH
      Obj()\Y=SH-Obj()\Radius
      Obj()\SY*(-1)
    EndIf
   
    If Obj()\X-Obj()\Radius<0
      Obj()\X=Obj()\Radius
      Obj()\SX*(-1)
    ElseIf Obj()\X+Obj()\Radius>SW
      Obj()\X=SW-Obj()\Radius
      Obj()\SX*(-1)
    EndIf
    ;}
   
    SolveCollisions(@Obj(),DeltaTime)
    SolveLinks(@Obj(),DeltaTime)
    SolveMotion(@Obj(),DeltaTime)
  Next
 
  StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_Outlined )
    ForEach Obj()
      RenderObj(@Obj())
    Next
    DrawText(0,10,Str(GetFPS()))
  StopDrawing()
 
 
  If KeyboardPushed(#PB_Key_Return)
    DeltaTime=0.1 ; Слоу-мо =)
  Else
    DeltaTime=1.0
  EndIf
 
  FlipBuffers(1)
Until KeyboardReleased(#PB_Key_Escape)
End
;Вообще то, хороший тон - освободить Allocate'ы самостоятельно,
;но, судя по хэлпу, PureBasic и так автоматически убирает то,
;то было заAllocateMemory'но, в конце программы. =)
 


_________________
http://www.youtube.com/watch?v=XHosLhPEN3k


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн янв 12, 2009 2:14 am 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Пн ноя 27, 2006 2:43 pm
Сообщений: 931
Откуда: Санкт-Петербург
Благодарил (а): 1 раз.
Поблагодарили: 12 раз.
Пункты репутации: 15
Движок получился простой, мощный и довольно универсальный

(хотя я в ссылках на участки памяти слегка запутался :oops: )

это уже почти инструмент для моделирования
:idea:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн янв 12, 2009 2:49 am 
Не в сети
eternal student
Аватар пользователя

Зарегистрирован: Ср ноя 05, 2008 1:35 am
Сообщений: 447
Откуда: Екатеринодар
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Класс!

_________________
CQ DX...


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн янв 12, 2009 5:56 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Сб авг 18, 2007 6:26 pm
Сообщений: 605
Откуда: Северодвинск/Питер
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Спасибо! :oops:

Ну, в принципе, ничего особенно мощного нет, пока что производительность квадратично зависит от количества объектов... :( А насчёт ссылок - к этому я привык :roll: Хотя, говорят, указатели - тёмная сторона кодинга :lol: А данном случае они очень помогают сравнивать один элемент списка с другим. Точнее - указателя на один элемент и сам элемент. Это позволяет избежать копирования элементов через временные переменные :)

А ещё: обратите внимание на глюки веревки: она иногда может раскачиваться волнообразно. Это происходит потому, что связь может иметь натяжение. Под действием натяжения первые элементы смещаются, что создает волну, проходящую по всей веревке =) Надо с этим как-то бороться, гасить ненужные колебания :?

_________________
http://www.youtube.com/watch?v=XHosLhPEN3k


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт янв 13, 2009 3:08 am 
Не в сети
eternal student
Аватар пользователя

Зарегистрирован: Ср ноя 05, 2008 1:35 am
Сообщений: 447
Откуда: Екатеринодар
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Добрый час! Веревка заметно не может успокоится, будто фонит.
Такое впечатление, что у нее нет своего веса.

_________________
CQ DX...


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт янв 13, 2009 2:18 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Пн окт 13, 2008 4:43 pm
Сообщений: 342
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Сыровато, конечно, но интересно! Кружки лучше закрасить - закоментив ;DrawingMode(#PB_2DDrawing_Outlined ).
Еще ввести "сухое трение" в веревку. Жесткость веревки увеличить... и т.д. Напоминает 9 урок из враппера HGE. Кстати интересно, кто в этот враппер вставил свою физику, и откуда он ее взял?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт янв 13, 2009 8:10 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Сб авг 18, 2007 6:26 pm
Сообщений: 605
Откуда: Северодвинск/Питер
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Morganolla писал(а):
Сыровато, конечно, но интересно! Кружки лучше закрасить - закоментив ;DrawingMode(#PB_2DDrawing_Outlined ).

Не лучше. Во-первых, медленнее. Во-вторых, непонятно, есть взаимопроникновения или нету. Касательно закрасить - лучше отрбражать текстуру через Sprite3d =)

Morganolla писал(а):
Кстати интересно, кто в этот враппер вставил свою физику, и откуда он ее взял?

Насколько я знаю, в HGE используется физика Box2d - физический движок с открытыми исходниками.
pentod65 писал(а):
Добрый час! Веревка заметно не может успокоится, будто фонит.

Такое впечатление, что у нее нет своего веса.

Вес есть. Я же и говорю - нужно сделать затухание =)

_________________
http://www.youtube.com/watch?v=XHosLhPEN3k


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср янв 14, 2009 12:20 am 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Пн ноя 27, 2006 2:43 pm
Сообщений: 931
Откуда: Санкт-Петербург
Благодарил (а): 1 раз.
Поблагодарили: 12 раз.
Пункты репутации: 15
да, любые колебания - затухающие, если нет источника энергии :?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср янв 14, 2009 2:18 am 
Не в сети
eternal student
Аватар пользователя

Зарегистрирован: Ср ноя 05, 2008 1:35 am
Сообщений: 447
Откуда: Екатеринодар
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Не согласен с вами батенька, существует очень много
неучтенных законов, присутствующих в той же чорной
дыре, где наша с вами физика, заблуждение.

_________________
CQ DX...


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср янв 14, 2009 2:23 am 
Не в сети
eternal student
Аватар пользователя

Зарегистрирован: Ср ноя 05, 2008 1:35 am
Сообщений: 447
Откуда: Екатеринодар
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Можно вопрос, Morganolla, вы женщина?(так отрапортовались
на своем сайте) тогда извините, я постараюсь быть с вами более мягче!!!

_________________
CQ DX...


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср янв 14, 2009 3:33 am 
Не в сети
eternal student
Аватар пользователя

Зарегистрирован: Ср ноя 05, 2008 1:35 am
Сообщений: 447
Откуда: Екатеринодар
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
ХИ-ХИ-ХИ!!!

_________________
CQ DX...


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср янв 14, 2009 11:47 am 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Пн окт 13, 2008 4:43 pm
Сообщений: 342
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
pentod65 писал(а):
Можно вопрос, Morganolla, вы женщина?(так отрапортовались
на своем сайте) тогда извините, я постараюсь быть с вами более мягче!!!


Где это я отрапортовался??? Чуваки, я - мужик. Просто люблю полабать на разных органолах...:)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт янв 15, 2009 4:42 am 
Не в сети
GameC@Soft
Аватар пользователя

Зарегистрирован: Сб сен 22, 2007 12:45 pm
Сообщений: 1085
Откуда: Я из лесу вышел, и сразу зашел, в босоножках дырявых и взлядом ночным.
Благодарил (а): 1 раз.
Поблагодарили: 2 раз.
Пункты репутации: 0
В общем я удалил все это.

_________________
"Самый большой глюк в PureBasic - это твоя голова...." (с) Артем
Мой сайт: http://feelzone.org.ua/


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт янв 15, 2009 4:46 am 
Не в сети
eternal student
Аватар пользователя

Зарегистрирован: Ср ноя 05, 2008 1:35 am
Сообщений: 447
Откуда: Екатеринодар
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Меня то же желательно удалить.

_________________
CQ DX...


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт янв 15, 2009 5:19 am 
Не в сети
GameC@Soft
Аватар пользователя

Зарегистрирован: Сб сен 22, 2007 12:45 pm
Сообщений: 1085
Откуда: Я из лесу вышел, и сразу зашел, в босоножках дырявых и взлядом ночным.
Благодарил (а): 1 раз.
Поблагодарили: 2 раз.
Пункты репутации: 0
Помоему там был флуд и ругательство... в общем продолжаем флудить..... А вопрос в том, что Марганолла продолжает оскорблять людей открыт. Кто думает я не прав, пишите, я тоже могу ошибаться.

_________________
"Самый большой глюк в PureBasic - это твоя голова...." (с) Артем
Мой сайт: http://feelzone.org.ua/


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 33 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB