Had some fun with this. Messy code, simple AI. Use RMB to detonate the projectile. Waves come every 8 seconds.
Graphics3D 640,480,32,0 SetBuffer BackBuffer() camera = CreateCamera() CameraZoom camera,.8 light = CreateLight() MoveEntity camera,0,10,-15 Global timer# = MilliSecs() Global score Type enemy Field mesh End Type CreateEnemies() ; create cannon base = CreateCylinder(12) ScaleMesh base,3,1,3 PositionMesh base,0,.5,0 s1 = CreateCube() s2 = CreateCube() ScaleMesh s1,.5,2,1 ScaleMesh s2,.5,2,1 PositionMesh s1,-1.5,3.5,0 PositionMesh s2,1.5,3.5,0 AddMesh(s1,base) AddMesh(s2,base) FreeEntity s1 FreeEntity s2 EntityColor base,100,150,200 barrel= CreateCylinder(12) RotateMesh barrel,90,0,0 b2 = CreateCylinder(12) ScaleMesh b2,.8,1,.8 RotateMesh b2,90,0,0 PositionMesh b2,0,0,2 AddMesh(b2,barrel) FreeEntity b2 Muzzle = CreatePivot(Barrel) PositionEntity Muzzle,0,0,4 PositionEntity barrel,0,4,0 EntityParent barrel,base EntityColor barrel,200,150,100 ; Make Ground Ground = CreatePlane() i = CreateImage(64,64) SetBuffer(ImageBuffer(i)) Color 0,0,255:Rect 0,0,32,32:Rect 32,32,32,32 Color 0,100,255:Rect 32,0,32,32:Rect 0,32,32,32 checker = CreateTexture(64,64) CopyRect 0,0,64,64,0,0,ImageBuffer(i),TextureBuffer(checker) FreeImage i ScaleTexture checker ,50,50 EntityTexture ground,checker xspin# = 0 yspin# = 0 Repeat xspin = xspin - (MouseXSpeed()/15) yspin = yspin - (MouseYSpeed()/15) If xspin < -45 Then xspin = -45 If xspin > 45 Then xspin = 45 If yspin > 0 Then yspin = 0 If yspin < -80 Then yspin = -80 MoveMouse 320,240 RotateEntity base,0,xspin,0 RotateEntity barrel,yspin,0,0 If MouseHit(1) Then NewGrenade(Muzzle) EndIf updategrenade updatepoof For e.enemy = Each enemy TurnEntity e\mesh,1,0,0 MoveEntity e\mesh,0,0,-.4 Next If MilliSecs() > timer + 8000 CreateEnemies() timer = MilliSecs() EndIf RenderWorld Text 10,10,"Score: "+score HidePointer() Flip Until KeyHit(1) Type Grenade Field Mesh Field Phys Field Life Field Explode End Type Type poof Field Mesh Field Phys Field Life Field Explode End Type Function NewGrenade(Launcher) C.Grenade = New Grenade C\Mesh = CreateSphere(6) EntityColor C\Mesh,Rand(100,255),Rand(100,255),Rand(100,255) C\Phys = CreatePivot() PositionEntity C\Mesh,EntityX(Launcher,True),EntityY(Launcher,True),EntityZ(Launcher,True) RotateEntity c\Phys,EntityPitch(Launcher,True),EntityYaw(Launcher,True),EntityRoll(Launcher,True) MoveEntity c\phys,0,0,1 EntityShininess c\mesh,1 c\Life = 150 c\explode = True End Function Function Clip(x) If x>255 Then x=255 Return x End Function Function NewExplode(Launcher) For n=1 To 100 C.Grenade = New Grenade C\Mesh = CreateSprite() col = Rand(100,255) ScaleSprite c\mesh,Rnd(.1,.2),Rnd(.1,.2) EntityColor C\Mesh,Clip(col*2),Clip(col),col/2 C\Phys = CreatePivot() PositionEntity C\Mesh,EntityX(Launcher,True),EntityY(Launcher,True),EntityZ(Launcher,True) ScaleEntity c\mesh,Rnd(.1,.4),Rnd(.1,.4),Rnd(.1,.4) RotateEntity c\mesh,Rand(360),Rand(360),Rand(360) PositionEntity c\Phys,Rnd(-.5,.5),Rnd(-1,1),Rnd(-.5,.5) EntityShininess c\mesh,0 EntityFX c\mesh,1 EntityBlend c\mesh,3 c\Life = Rand(5,40) c\explode = False Next End Function Function EnemyExplode(e.enemy) For n=1 To 50 p.poof = New poof p\Mesh = CreateSprite() col = Rand(100,255) ScaleSprite p\mesh,Rnd(.1,.2),Rnd(.1,.2) EntityColor p\Mesh,Clip(col*2),Clip(col),col/2 p\Phys = CreatePivot() PositionEntity p\Mesh,EntityX(e\mesh,True),EntityY(e\mesh,True),EntityZ(e\mesh,True) ScaleEntity p\mesh,Rnd(.1,.4),Rnd(.1,.4),Rnd(.1,.4) RotateEntity p\mesh,Rand(360),Rand(360),Rand(360) PositionEntity p\Phys,Rnd(-.5,.5),Rnd(-1,1),Rnd(-.5,.5) EntityShininess p\mesh,0 EntityFX p\mesh,1 EntityBlend p\mesh,3 p\Life = Rand(5,15) p\explode = False Next End Function Function UpdateGrenade() For c.Grenade = Each Grenade TranslateEntity c\Mesh,EntityX(c\phys),EntityY(c\phys),EntityZ(c\phys) TranslateEntity c\phys,0,-.01,0 If EntityY(c\mesh)<.5 Then PositionEntity c\mesh,EntityX(c\mesh),.5,EntityZ(c\mesh) TranslateEntity c\phys,0,-EntityY(c\phys)*1.5,0 EndIf TurnEntity c\mesh,5,10,15 c\life = c\life - 1 If c\life = 0 Or MouseHit(2) Then If c\explode Then NewExplode(c\mesh) CheckEnemy(c) ;time to kill? FreeEntity c\mesh FreeEntity c\phys Delete c EndIf Next End Function Function UpdatePoof() For p.poof = Each poof TranslateEntity p\Mesh,EntityX(p\phys),EntityY(p\phys),EntityZ(p\phys) TranslateEntity p\phys,0,-.01,0 If EntityY(p\mesh)<.5 Then PositionEntity p\mesh,EntityX(p\mesh),.5,EntityZ(p\mesh) TranslateEntity p\phys,0,-EntityY(p\phys)*1.5,0 EndIf TurnEntity p\mesh,5,10,15 p\life = p\life - 1 If p\life = 0 FreeEntity p\mesh FreeEntity p\phys Delete p EndIf Next End Function Function CheckEnemy(c.grenade) For e.enemy = Each enemy If EntityDistance (c\mesh,e\mesh) < 10 score = score + 10 EnemyExplode(e) FreeEntity e\mesh Delete e EndIf Next End Function Function CreateEnemies() x=-45 y=10 z=50 rcol = Rand(100,255) gcol = Rand(100,255) bcol = Rand(100,255) For i = 1 To 72 e.enemy = New enemy e\mesh = CreateCube() EntityColor e\mesh,rcol,gcol,bcol PositionEntity e\mesh,x,y,z x=x+5 If x = 45 y = y + 10 x = -45 EndIf Next End Function