Sync On
Sync Rate 60
Randomize Timer()
Autocam Off
 
Type Coordinates
   x as Float
   y as Float
   z as Float
Endtype
Global Object as Coordinates
Global Target as Coordinates
Global Total as Coordinates
Global Count as Float
 
set camera to image 0,1,512,512
  set camera aspect 800/600
  color backdrop RGB(150,150,220)
  sprite 1,0,0,1
  set sprite 1,0,1
  set sprite alpha 1,100
  size sprite 1,800,600
 
Create Bitmap 1,100,100
Set Current Bitmap 1
Box 0,0,99,99,RGB(255,128,0),RGB(164,169,213),RGB(233,235,169),RGB(89,91,0)
Get Image 2,0,0,99,99
Set Current Bitmap 0
Delete Bitmap 1
 
w=Screen Width():h=Screen Height()
Create Bitmap 1,w,h
Set Current Bitmap 1
Box 0,0,w/2,h-1,RGB(0,0,15),RGB(150,150,255),RGB(0,0,64),RGB(200,200,255)
Box w/2,0,w-1,h-1,RGB(0,0,64),RGB(200,200,255),RGB(0,0,15),RGB(150,150,255)
Get Image 3,0,0,w-1,h-1
Sprite 2,1,1,3
Set sprite alpha 2,100
`Set Sprite Priority 2,0
Set Current Bitmap 0
 
Dim m(1000) as Float
R# = 50        :` resting length
K# = 2         :` spring coefficient
v# = 0.0       :` velocity
f# = 0.9       :` friction
 
Dim dots(1000) as Coordinates
Dim vels(1000) as Coordinates
 
Global Fish as Float
Fish = 500
 
 
For i = 1 to Fish
   Fish(i)
   `Texture Object i,1
   Set Sphere Mapping On i,2
   Position Object i,rnd(20)-10,Rnd(20)-10,Rnd(20)-10
   Turn Object Right i,rnd(360)
   Pitch Object Down i,rnd(360)
   Roll Object Left i,rnd(360)
   Move Object i,rnd(R#)+.1
   m(i)=rnd(500.0)/10.0+100.0
   Return_Object(i)
   dots(i).x=Object.x:dots(i).y=Object.y:dots(i).z=Object.z
Next i
Make Object Sphere 1001,.5,8,8
Hide Object 1001
Position Object 1001,0,0,100
   Turn Object Right 1001,rnd(360)
   Pitch Object Down 1001,rnd(360)
   Roll Object Left 1001,rnd(360)
 
Count=249
Do
   Fix Object Pivot 1001
   Return_Object(1001)
   If rnd(300)=1 Then movex#=rnd(50.0)/10.0-3.0
   If rnd(300)=1 Then movey#=rnd(50.0)/10.0-3.0
   If rnd(300)=1 Then movez#=rnd(50.0)/10.0-3.0
   Position Object 1001,Object.x+movex#,Object.y+movey#,Object.z+movez#
   Return_Object(1001)
   If Object.x>80 or Object.x<-80
      Position Object 1001,Object.x-movex#,Object.y+movey#,Object.z+movez#
      movex#=-movex#
   Endif
   If Object.y>80 or Object.y<-80
      Position Object 1001,Object.x+movex#,Object.y-movey#,Object.z+movez#
      movey#=-movey#
   Endif
   If Object.z>250 or Object.z<50
      Position Object 1001,Object.x+movex#,Object.y+movey#,Object.z-movez#
      movez#=-movez#
   Endif
   cx#=Object.x:cy#=Object.y:cz#=Object.z
   Total.x=0:Total.y=0:Total.z=0
   For i =1 to Fish
      Return_Target(i)
      Total.x=Target.x+Total.x
      Total.y=Target.y+Total.y
      Total.z=Target.z+Total.z
   Next i
   cx#=(cx#*(Fish*.1)+Total.x)/(Fish*1.1):cy#=(cy#*(Fish*.1)+Total.y)/(Fish*1.1):cz#=(cz#*(Fish*.1)+Total.z)/(Fish*1.1)
   For i = 1 to Fish
      Return_Target(i)
      dx#=Target.x-(cx#+dots(i).x)
      dy#=Target.y-(cy#+dots(i).y)
      dz#=Target.z-(cz#+dots(i).z)
      d#=sqrt(dx#*dx#+dy#*dy#+dz#*dz#)
      vels(i).x=Spring(vels(i).x,K#,abs(dx#*d#)/dx#,m(i),f#)
      vels(i).y=Spring(vels(i).y,K#,abs(dy#*d#)/dy#,m(i),f#)
      vels(i).z=Spring(vels(i).z,K#,abs(dz#*d#)/dz#,m(i),f#)
      Position Object i,Target.x+vels(i).x,Target.y+vels(i).y,Target.z+vels(i).z
      Point Object i,(Object.x-cx#)*100+cx#,(Object.y-cy#)*100+cy#,(Object.z-cz#)*100+cy#
      Return_Target(i)
   Next i
   Set Cursor 0,0
   Print Screen FPS()
   Sync
Loop
 
 
 
 
Function Spring(vel#,spring#,dist#,resist#,frict#)
vel#=(vel# + (-spring# * dist#)/resist#)*frict#
EndFunction vel#
 
 
Function Return_Object(ObjectID)
Object.x=Object Position X(ObjectID):Object.y=Object Position Y(ObjectID):Object.z=Object Position Z(ObjectID)
EndFunction
 
Function Return_Target(TargetID)
Target.x=Object Position X(TargetID):Target.y=Object Position Y(TargetID):Target.z=Object Position Z(TargetID)
EndFunction
 
Function Fish(ObjectID)
Make Object Sphere ObjectID,3,8,8
Make Mesh From Object ObjectID,ObjectID
Delete Object ObjectID
Make Object Triangle ObjectID,0,1,-1,0,-1,-1,0,0,1
Offset Limb ObjectID,0,0,0,-.8
Add Limb ObjectID,1,ObjectID
Offset Limb ObjectID,1,0,0,1
Scale Limb ObjectID,1,20,80,100
EndFunction