Tested successfully on Win10x64, PB 5.62 x86
Code: Select all
#X=800:#Y=300 ;screen size /taille de l'écran
#Maxspeed=5.0:#MaxForce=1.0
#FleeAction=150 ;distance from mouse particles flee /Distance depuis laquelle les particules fuient la souris
#RepulseMagnitude=-3 ;should be negative to flee. Multiplicator to repulse particles /Multiplicateur négatif de la force de fuite
#DistanceToLand=20 ;distance to slowdown close to the goal, in pixels ;distance à partir de laquelle les particules ralentissent
#FontSize=160
#DistanceBetweenPoint=10 ;number of particles (space between dots in text's shape) /nombre de points dans le texte: donc nombre de particules
#ParticleSize=2 ;particles' radius /rayon d'une particule
text$="PureBasic"
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse()=0: MessageRequester("Error", "Can't open the sprite system", 0): End: EndIf
If OpenWindow(0, 0, 0, #X, #Y, "Steering Particle Text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) = 0: MessageRequester("Error", "Can't open windowed screen!", 0): EndIf
If OpenWindowedScreen(WindowID(0), 0, 0, #X, #Y, 0, 0, 0) = 0: MessageRequester("Error", "Can't open windowed screen!", 0): EndIf
Structure vector
x.f
y.f
EndStructure
Structure pt
Pos.vector
Vel.vector
Acc.vector
target.vector
size.i
color.i
EndStructure
Global NewList Pt.pt()
Procedure AddVector(*V1.vector,*V2.vector,*V3.vector)
*V3\x=*V1\x+*V2\x
*V3\y=*V1\y+*V2\y
EndProcedure
Procedure SubVector(*V1.vector,*V2.vector,*V3.vector)
*V3\x=*V1\x-*V2\x
*V3\y=*V1\y-*V2\y
EndProcedure
Procedure MultVector(*V1.vector,val.f)
*V1\x*val
*V1\y*val
EndProcedure
Procedure.f ReadMagnitudeVector(*V1.vector)
Magnitude.f=Sqr((*V1\x**V1\x)+(*V1\y**V1\y))
ProcedureReturn Magnitude
EndProcedure
Procedure.f SetMagnitudeVector(*V1.vector,magnitude.f)
angle.f=ATan2(*V1\x,*V1\y)
*V1\y=magnitude*Sin(angle)
*V1\x=magnitude*Cos(angle)
EndProcedure
Procedure.f LimitMagnitudeVector(*V1.vector,limit.f)
magnitude.f=ReadMagnitudeVector(*V1)
If magnitude>limit
SetMagnitudeVector(*V1,limit)
EndIf
EndProcedure
Procedure RandomVector(*V1.vector,MagnitudeMax.f)
*V1\x=Random(2000)-1000
*V1\y=Random(2000)-1000
SetMagnitudeVector(*V1,Random(MagnitudeMax*1000)/1000)
EndProcedure
Procedure UpdateParticlePhysic()
ForEach pt()
AddVector(pt()\pos,pt()\Vel,pt()\pos)
AddVector(pt()\Vel,pt()\Acc,pt()\Vel)
MultVector(pt()\Acc,0)
Next pt()
EndProcedure
Procedure Arrive()
Define steer.vector,desired.vector
ForEach pt()
SubVector(pt()\target,pt()\Pos,Desired)
distance.f=ReadMagnitudeVector(Desired)
MaxSpeed.f=#MaxSpeed
If distance<#DistanceToLand
MaxSpeed=MaxSpeed/(#DistanceToLand-distance)
EndIf
SetMagnitudeVector(Desired,MaxSpeed)
SubVector(Desired,pt()\vel,Steer)
LimitMagnitudeVector(Steer,#MaxForce)
AddVector(Steer,pt()\acc,pt()\acc)
Next pt()
EndProcedure
Procedure Flee(*mouse.vector)
Define Steer.vector,Desired.vector
ForEach pt()
SubVector(*mouse,pt()\Pos,Desired)
If ReadMagnitudeVector(Desired)<#FleeAction
SetMagnitudeVector(Desired,#Maxspeed)
MultVector(Desired,#RepulseMagnitude)
SubVector(Desired,pt()\vel,Steer)
LimitMagnitudeVector(Steer,#MaxForce)
AddVector(Steer,pt()\acc,pt()\acc)
EndIf
Next pt()
EndProcedure
;{ Transform text$ in a vector points shape. /transforme le text$ en une série de points
CreateImage(0,#x,#y)
LoadFont(0, "Arial", 20, #PB_Font_Bold)
If StartVectorDrawing(ImageVectorOutput(0,#PB_Unit_Pixel))
VectorFont(FontID(0),#fontSize)
MovePathCursor(0, 0)
AddPathText(Text$)
large.i=VectorTextWidth(Text$)
Haut.i=VectorTextHeight(Text$)
VectorSourceColor(RGBA(255, 0, 0, 255))
DotPath(1,#DistanceBetweenPoint)
StopVectorDrawing()
EndIf
;}
;{ Add a particle for each points of the text/ajoute une particule pour chacun de ces point
If StartDrawing(ImageOutput(0))
For j=0 To haut
For i=0 To large
If i>#x-1 Or j>#y-1:Continue:EndIf
If Point(i,j)<>0
AddElement(pt())
pt()\pos\x=Random(#x):pt()\pos\y=Random(#y)
pt()\target\x=i:pt()\target\y=j
RandomVector(pt()\vel,10)
pt()\size=#ParticleSize:pt()\color=RGB(Random(255),Random(255),Random(255))
EndIf
Next i
Next j
StopDrawing()
EndIf
FreeImage(0)
;}
Define mouse.vector:MouseLocate(#x/2,#y)
Repeat
Repeat
Until WindowEvent()=0
FlipBuffers()
ClearScreen($0)
ExamineKeyboard()
ExamineMouse()
mouse\x=MouseX():mouse\y=MouseY()
Arrive()
Flee(mouse)
UpdateParticlePhysic()
StartDrawing(ScreenOutput())
;display particles /affiche les particules
ForEach pt()
Circle(pt()\pos\x,pt()\pos\y,pt()\size,pt()\color)
Next
;display mouse cursor /affiche le curseur
Circle(mouse\x,mouse\y,2,RGB(0,255,0))
StopDrawing()
Until KeyboardPushed(#PB_Key_Escape)