Type cog Field notches,pattern[] Field radius# Field x#,y# Field angle#,anstep#,ticks Field links:tlist Field depth,upnotch Field shade# Field shooters:tlist Function create:cog(pattern[],notches,radius#,x#,y#) c:cog=New cog c.notches=notches c.radius=radius c.x=x c.y=y c.anstep=360.0/notches c.links=New tlist c.shade=1 c.shooters=New tlist i=0 c.pattern=New Int[notches] For n=0 To notches-1 c.pattern[n]=pattern[i] i=(i+1) Mod Len(pattern) Next cogs.addlast c Return c End Function Method link(c:cog) dx#=x-c.x dy#=y-c.y an#=ATan2(dy,dx) If an<180 an=360+an upnotch=Int(an/c.anstep) an=c.anstep*upnotch d#=Sqr(dx*dx+dy*dy) r#=radius+c.radius x=c.x+r*Cos(an) y=c.y+r*Sin(an) c.links.addlast Self depth=c.depth+1 shade=1-.2^depth End Method Method draw() SetAlpha shade*.8 DrawOval x-radius+4,y-radius+4,radius*2-8,radius*2-8 SetAlpha 1 For i=0 To notches-1 an#=(i+ticks)*anstep+angle c#=Cos(an) s#=Sin(an) sx#=x+c*(radius-4) sy#=y+s*(radius-4) If pattern[i] ex#=x+c*(radius+4) ey#=y+s*(radius+4) Else ex#=x+c*(radius-2) ey#=y+s*(radius-2) EndIf DrawLine sx,sy,ex,ey Next End Method Method turn(an#) angle:+an While Abs(angle)>anstep dir=Sgn(angle) tick(dir) angle:-anstep*dir Wend For c:cog=EachIn links notch=(c.upnotch + ticks) Mod notches If notch<0 Then notch=notches+notch If pattern[notch] c.turn(-an*radius/c.radius) EndIf Next End Method Method tick(dir) ticks:+dir For s:shooter=EachIn shooters s.shoot() Next End Method End Type Type shooter Field tick Field shotpattern[],anglepattern[] Field mycog:cog Function create:shooter(c:cog,shotpattern[],anglepattern[]) s:shooter=New shooter s.shotpattern=shotpattern s.anglepattern=anglepattern c.shooters.addlast s s.mycog=c Return s End Function Method shoot() tick:+1 shotn=tick Mod Len(shotpattern) angle=tick Mod Len(anglepattern) If shotpattern[shotn] shot.create(mycog.x,mycog.y,anglepattern[angle]) EndIf End Method EndType Type shot Field x#,y#,vx#,vy# Function create:shot(x#,y#,angle#) b:shot=New shot b.x=x b.y=y b.vx=Cos(angle)*10 b.vy=Sin(angle)*10 shots.addlast b Return b End Function Method update(delta#) x:+vx*delta y:+vy*delta If x<0 Or x>800 Or y<0 Or y>800 shots.remove Self EndIf End Method Method draw() DrawRect x-2,y-2,4,4 End Method End Type Global cogs:tlist=New tlist Global shots:tlist=New tlist Graphics 800,800,0 SetBlend ALPHABLEND Global maincog:cog=cog.create([1],16,50,400,400) c:cog=cog.create([1,1,1,0,1,1,0,0],32,25,500,400) c.link(maincog) c2:cog=cog.create([1,0,1,1,1,0],24,75,600,400) c2.link(c) c3:cog=cog.create([1],6,25,550,450) c3.link(c2) s:shooter=shooter.create(c3,[1],[80,100]) c3:cog=cog.create([1],6,25,650,450) c3.link(c2) s:shooter=shooter.create(c3,[1,1,0],[80,100]) c:cog=cog.create([1,0,1,1],24,50,300,400) c.link(maincog) c2:cog=cog.create([1],12,25,300,450) c2.link(c) s:shooter=shooter.create(c2,[1],[90,75,90,115]) ms=MilliSecs() lasttick=ms While Not KeyHit(KEY_ESCAPE) oldms=ms ms=MilliSecs() delta#=(ms-oldms)/20.0 maincog.turn(delta*2) For c:cog=EachIn cogs c.draw() Next For b:shot=EachIn shots b.update(delta) b.draw() Next Flip Cls Wend