Global things:TList=New TList Type thing Field x#,y#,vx#,vy#,r#,m#,ox#,oy# Field x2#,y2#,vx2#,vy2# Field cor#,cof# 'coefficient of restitution, friction Field an#,van# Field col# Method New() things.addlast Self m=1 r=1 cor=1 cof=0 col=Rand(360) End Method Function Create:thing(x#,y#,m#,r#,cor#,cof#) t:thing=New thing t.x2=x t.y2=y t.m=m t.r=r t.cor=cor t.cof=cof Return t End Function Method checkcollide(t:thing) 'quick bounding box check If Not (x-rt.x-t.r And y-rt.y-t.r) Return False EndIf 'find difference between new positions dx#=x-t.x dy#=y-t.y d#=dx*dx+dy*dy tr#=r+t.r If d=0 Return False 'if radii overlap If d1 'something mad has gone on, such as both objects beginning the frame overlapping d=Sqr(d) diff#=tr-d dx:/d dy:/d f#=diff*t.m/(m+t.m) f2#=diff*m/(m+t.m) mx#=dx*f my#=dy*f mx2#=-dx*f2 my2#=-dy*f2 x2:+mx y2:+my vx2:+mx vy2:+my t.x2:+mx2 t.y2:+my2 t.vx2:+mx2 t.vy2:+my2 Return True EndIf 'find positions of objects at time of collision nx#=ox+time*vx ny#=oy+time*vy nx2#=t.ox+time*t.vx ny2#=t.oy+time*t.vy 'find vector between objects at collision dx=nx-nx2 dy=ny-ny2 d=tr If d=0 Return False 'just in case# dx:/d dy:/d 'work out COR of collision (guess) rcor#=(m*cor+t.m*t.cor)/(m+t.m) 'find components of velocity towards collision normal and tangential in#=vx*dx+vy*dy in2#=t.vx*dx+t.vy*dy n#=-vx*dy+vy*dx n2#=-t.vx*dy+t.vy*dx 'find new velocities in direction of normal after collision nin#=(m*in+t.m*in2+t.m*rcor*(in2-in))/(m+t.m) nin2#=(m*in+t.m*in2+m*rcor*(in-in2))/(m+t.m) Rem 'work out friction and apply to tangential velocity rcof#=(cof+t.cof)/(m+t.m) rcof=0 f#=(in2-in)*rcof nn#=-Sgn(n)*f/m nn:+n If nn*n<0 nn=0 nn2#=-Sgn(n2)*f/t.m nn2:+n2 If nn2*n2<0 nn2=0 EndRem 'combine to give new velocities nvx#=nin*dx-n*dy nvy#=nin*dy+n*dx nvx2#=nin2*dx-n2*dy nvy2#=nin2*dy+n2*dx 'add remaining time's movement using new velocities nx:+(1-time)*nvx ny:+(1-time)*nvy nx2:+(1-time)*nvx2 ny2:+(1-time)*nvy2 'DEBUG dx=nx-x dy=ny-y If dx*dx+dy*dy>50 ' DebugStop ' Print "WOW"+(dx*dx+dy*dy) ' DrawLine t.x,t.y,x,y EndIf x2:+nx-x y2:+ny-y vx2:+nvx-vx vy2:+nvy-vy t.x2:+nx2-t.x t.y2:+ny2-t.y t.vx2:+nvx2-t.vx t.vy2:+nvy2-t.vy Rem x=nx y=ny t.x=nx2 t.y=ny2 vx=nvx vy=nvy t.vx=nvx2 t.vy=nvy2 EndRem Return True EndIf End Method Method update() x=x2 y=y2 vx=vx2 vy=vy2 ox=x oy=y x:+vx y:+vy If x600-r time#=(600-r-ox)/vx vx=-vx*cor x=600-r+(1-time)*vx EndIf If y600-r time#=(600-r-oy)/vy vy=-vy*cor y=600-r+(1-time)*vy EndIf x2=x y2=y vx2=vx vy2=vy End Method Method draw() col:+.5 SetColor Sin(col)*100+100,Cos(col*2)*100+100,Cos(col*3)*100+100 SetAlpha .8 'SetBlend lightblend DrawOval x-r,y-r,r*2,r*2 'DrawLine x,y,x+vx*10,y+vy*10 'SetBlend shadeblend SetAlpha .1 DrawRect x-r*10,y-r*10,r*20,r*20 End Method End Type Global me:thing Function setup() things=New TList me:thing=thing.Create(100,40,3,30,.5,0) me.vy2=1 me.vx2=1 'thing.Create(300,300,9,30,.5,0) thing.Create(100,500,4,20,.5,0) For c=1 To 100 makething Next End Function Function makething() in=1 While in pr=Rand(50,250) an=Rand(360) x=Cos(an)*pr+300 y=Sin(an)*pr+300 in=0 r=Rnd(5,10) For t:thing=EachIn things dx#=x-t.x dy#=y-t.y d#=dx*dx+dy*dy If d<=(t.r+r)*(t.r+r) in=1 Exit EndIf Next Wend thing.Create(x,y,.01*r,r,.5,.5) End Function AppTitle="some old ones" Graphics 600,600,0 SetBlend ALPHABLEND 'SetClsColor 255,255,255 setup While Not (KeyHit(KEY_ESCAPE) Or AppTerminate()) If KeyHit(KEY_SPACE) setup If Rand(50)=1 'makething EndIf me.vx2:+(KeyDown(KEY_RIGHT)-KeyDown(KEY_LEFT))*.1 'me.vy:+(KeyDown(KEY_RIGHT)-KeyDown(KEY_LEFT))*.1 me.vy2:+(KeyDown(KEY_DOWN)-KeyDown(KEY_UP))*.1 e#=0 For t:thing=EachIn things t.update te#=0.5*t.m*(t.vx*t.vx+t.vy*t.vy) 'DrawText te,t.x,t.y e#:+te Next DrawText e,0,15 collision=10 'While collision>0 ts:TList=things.copy() While ts.count()>1 t:thing=thing(ts.removefirst()) For t2:thing=EachIn ts If t.checkcollide(t2) collision:-1 Else collision=0 EndIf Next Wend 'Wend ts=things.copy() While ts.count()>1 t:thing=thing(ts.removefirst()) For t2:thing=EachIn ts dx#=t2.x-t.x dy#=t2.y-t.y d#=Sqr(dx*dx+dy*dy) If d<>0 f#=5/(d*d) t.vx2:+t2.m*f*dx/d t.vy2:+t2.m*f*dy/d t2.vx2:-t.m*f*dx/d t2.vy2:-t.m*f*dy/d EndIf Next Wend For t:thing=EachIn things t.draw Next DrawText things.count(),0,0 Flip Cls Wend