Ich habe am Wochenende mal ein wenig mit PB rumgespielt und da mir das Ergebnis einfach Freude gemacht hat, will ich es nicht vorenthalten. Wichtig: Das hat keinerlei Ansprüche an echte Physik oder sowas. Ist nur Spass.
Code: Alles auswählen
Structure strElement
PosX.f
PosY.f
VectorX.f
VectorY.f
Color.l
EndStructure
#Image = 2
; Werte
MaxEntfernung.l = 25 ; if distance is greater, there is no effect
GravityConstant.f = 0.010 ; (0 = no gravity >0 = falling <0 = raising)
Anzahl.l = 50 ; number of elements in game
SlowDownConstant.f = 0.990 ; 1 = no force <1 = slowdown >1 = dont try!
SpecialEffect.l = 1
FaktDivisor.l = 100
Dim Elements.strElement(1000)
If OpenWindow(0, 100, 100, 400, 400, "Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
CreateImage(#Image, WindowWidth(0), WindowHeight(0))
CreateGadgetList(WindowID(0))
ImageGadget(1,1,1,WindowWidth(0), WindowHeight(0), ImageOutput(#Image))
;SmartWindowRefresh(0, 1)
StartDrawing(ImageOutput(#Image))
Box(0, 0, WindowWidth(0), WindowHeight(0), #White) ; clear
StopDrawing()
For x.l = 1 To Anzahl.l
Elements(x.l)\PosX = Random(WindowWidth(0))
Elements(x.l)\PosY = Random(WindowHeight(0))
Elements(x.l)\VectorX = 0
Elements(x.l)\VectorY = 0
Elements(x.l)\Color = RGB(Random(200), Random(200), Random(200))
Next
Repeat
; calculate attraction
For x.l = 1 To Anzahl.l
For y.l = 1 To Anzahl.l
If x.l <> y.l
WidX.l = Elements(x.l)\PosX - Elements(y.l)\PosX
WidY.l = Elements(x.l)\PosY - Elements(y.l)\PosY
Distance.l = Sqr(Pow(Abs(WidX.l), 2) + Pow(Abs(WidY.l), 2))
If Distance.l <= MaxEntfernung.l
; only affected if distance < MaxEntfernung.l
Faktor.f = ((MaxEntfernung.l * SpecialEffect.l) - Distance.l) / FaktDivisor.l
If WidX.l > 0
FakX.f = Faktor.f
Else
FakX.f = -Faktor.f
EndIf
If WidY.l > 0
FakY.f = Faktor.f
Else
FakY.f = -Faktor.f
EndIf
Elements(x.l)\VectorX = Elements(x.l)\VectorX + FakX.f
Elements(x.l)\VectorY = Elements(x.l)\VectorY + FakY.f
EndIf
EndIf
Next
Next
For x.l = 1 To Anzahl.l
; final movement with vector
Elements(x.l)\PosX = Elements(x.l)\PosX + Elements(x.l)\VectorX
Elements(x.l)\PosY = Elements(x.l)\PosY + Elements(x.l)\VectorY
; bounce on border?
If Elements(x.l)\PosX > WindowWidth(0) - 1 Or Elements(x.l)\PosX < 1: Elements(x.l)\VectorX = - Elements(x.l)\VectorX: EndIf
If Elements(x.l)\PosY > WindowHeight(0) - 1 Or Elements(x.l)\PosY < 1: Elements(x.l)\VectorY = - Elements(x.l)\VectorY: EndIf
; too fast?
If Abs(Elements(x.l)\VectorX) > 10: Elements(x.l)\VectorX = Elements(x.l)\VectorX / 2: EndIf
If Abs(Elements(x.l)\VectorY) > 10: Elements(x.l)\VectorY = Elements(x.l)\VectorY / 2: EndIf
; slowdown
Elements(x.l)\VectorX = Elements(x.l)\VectorX * SlowDownConstant.f
Elements(x.l)\VectorY = Elements(x.l)\VectorY * SlowDownConstant.f
; gravity
Elements(x.l)\VectorY = Elements(x.l)\VectorY + GravityConstant.f
; out?
If Elements(x.l)\PosX > WindowWidth(0): Elements(x.l)\PosX = WindowWidth(0): EndIf
If Elements(x.l)\PosY > WindowHeight(0): Elements(x.l)\PosY = WindowHeight(0): EndIf
If Elements(x.l)\PosX < 1: Elements(x.l)\PosX = 1: Elements(x.l)\VectorX = 0.3: EndIf
If Elements(x.l)\PosY < 1: Elements(x.l)\PosY = 1: Elements(x.l)\VectorY = 0.3: EndIf
Next
; draw
StartDrawing(ImageOutput(#Image))
Box(0, 0, WindowWidth(0), WindowHeight(0), #White) ; clear
For x.l = 1 To Anzahl.l
If Elements(x.l)\PosX > 0 And Elements(x.l)\PosY > 0
Circle(Elements(x.l)\PosX, Elements(x.l)\PosY, 10, Elements(x.l)\Color)
EndIf
Next
StopDrawing()
SetGadgetState(1, ImageID(#Image))
; one for the mouse!
If WindowMouseX(0) > 0 And WindowMouseY(0) > 0 And WindowMouseX(0) < WindowWidth(0) And WindowMouseY(0) < WindowHeight(0)
Elements(1)\PosX = WindowMouseX(0)
Elements(1)\PosY = WindowMouseY(0)
Elements(1)\VectorX = 0
Elements(1)\VectorY = 0
EndIf
Delay(1)
EventID.l = WindowEvent()
If EventID.l = #PB_Event_CloseWindow ; If the user has pressed on the close button
Quit.l = 1
EndIf
If EventID.l = #PB_Event_SizeWindow
ResizeImage(#Image, WindowWidth(0), WindowHeight(0))
ResizeGadget(1,1,1,WindowWidth(0), WindowHeight(0))
EndIf
Until Quit.l = 1
EndIf
Auch schön ist diese Parameterversion (Fluidial Movement):
Code: Alles auswählen
; Werte
MaxEntfernung.l = 40 ; if distance is greater, there is no effect
GravityConstant.f = 0.000 ; (0 = no gravity >0 = falling <0 = raising)
Anzahl.l = 100 ; number of elements in game
SlowDownConstant.f = 1.0000 ; 1 = no force <1 = slowdown >1 = dont try!
SpecialEffect.l = 1.5
FaktDivisor.l = 10000
Code: Alles auswählen
; Werte
MaxEntfernung.l = 40 ; if distance is greater, there is no effect
GravityConstant.f = 0.000 ; (0 = no gravity >0 = falling <0 = raising)
Anzahl.l = 100 ; number of elements in game
SlowDownConstant.f = 1.000 ; 1 = no force <1 = slowdown >1 = dont try!
SpecialEffect.l = 0.6
FaktDivisor.l = 5000
Code: Alles auswählen
; Werte
MaxEntfernung.l = 20 ; if distance is greater, there is no effect
GravityConstant.f = 0.000 ; (0 = no gravity >0 = falling <0 = raising)
Anzahl.l = 140 ; number of elements in game
SlowDownConstant.f = 0.990 ; 1 = no force <1 = slowdown >1 = dont try!
SpecialEffect.l = 1
FaktDivisor.l = 100
Oder das hier (Gelee):
Code: Alles auswählen
; Werte
MaxEntfernung.l = 100 ; if distance is greater, there is no effect
GravityConstant.f = 0.000 ; (0 = no gravity >0 = falling <0 = raising)
Anzahl.l = 40 ; number of elements in game
SlowDownConstant.f = 0.970 ; 1 = no force <1 = slowdown >1 = dont try!
SpecialEffect.l = 1.1
FaktDivisor.l = 1000
Mit Sprites und weniger Flimmern würde das schicker aussehen. Aber für meine Neugierde war es genug. Viel Spass.
Volker