Code: Select all
EnableExplicit
#ScreenWidth = 1024 : #ScreenHeight = 768
Structure Tank
X.f
Y.f
Facing_Angle.f
Angle_Of_Sight.f
Turn_Speed.f
Move_Speed.f
To_Mouse_Angle.f
EndStructure
Global NewList Tank.Tank()
Define MyLoop.i, Number_Of_Tanks.i, Event.i, OurMouse.POINT, Diff_Angle.f, Control_Speed.f
Number_Of_Tanks.i = 10
;/ Randomize the tanks
For MyLoop = 1 To Number_Of_Tanks
AddElement(Tank())
Tank()\X = Random(#ScreenWidth)
Tank()\Y = Random(#ScreenHeight)
Tank()\Facing_Angle = Random(360)
Tank()\Angle_Of_Sight = 20 + Random(45)
Tank()\Move_Speed = 0.5 + (Random(100)/50.0)
Tank()\Turn_Speed = Tank()\Move_Speed + (Random(100)/20.0)
Next
InitSprite()
OpenWindow(1,20,20,#ScreenWidth,#ScreenHeight,"Tank Test",#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(1),0,0,#ScreenWidth,#ScreenHeight,0,0,0)
Repeat
Event = WindowEvent()
OurMouse\X = WindowMouseX(1) : OurMouse\Y = WindowMouseY(1)
If OurMouse\X > -1 And OurMouse\Y > -1 ;/ mouse within screen area?
ForEach Tank()
;/ Find angle between mouse and tank
Tank()\To_Mouse_Angle.f = Degree(ACos((OurMouse\X-Tank()\X) / Sqr((OurMouse\X-Tank()\X)*(OurMouse\X-Tank()\X)+(OurMouse\Y-Tank()\Y)*(OurMouse\Y-Tank()\Y))))
If Tank()\Y < OurMouse\Y : Tank()\To_Mouse_Angle = 360 - Tank()\To_Mouse_Angle : EndIf
Tank()\To_Mouse_Angle + 90
;/ 'fudge' the angles to get correct calculations
Diff_Angle.f = Tank()\Facing_Angle - Tank()\To_Mouse_Angle
If Tank()\Facing_Angle - Tank()\To_Mouse_Angle < -180 : Diff_Angle + 360 : EndIf
If Tank()\Facing_Angle - Tank()\To_Mouse_Angle > 180 : Diff_Angle - 360 : EndIf
;/ If diff falls within tolerance, rotate & move tank
If Abs(Diff_Angle) <= Tank()\Angle_Of_Sight
;/ change tank angle - using control speed to get exact turning
Control_Speed = Tank()\Turn_Speed
If Control_Speed > Abs(Diff_Angle) : Control_Speed = Abs(Diff_Angle) : EndIf
If Diff_Angle < 0 : Tank()\Facing_Angle + Control_Speed : EndIf
If Diff_Angle > 0 : Tank()\Facing_Angle - Control_Speed : EndIf
;/ Wrap angle around if required
If Tank()\Facing_Angle < 0 : Tank()\Facing_Angle + 360 : EndIf
If Tank()\Facing_Angle > 360 : Tank()\Facing_Angle - 360 : EndIf
;/ move tank based on the tanks angle
Tank()\X + Tank()\Move_Speed * Sin(Radian(Tank()\Facing_Angle))
Tank()\Y + Tank()\Move_Speed * Cos(Radian(Tank()\Facing_Angle))
EndIf
Next
;/ Draw to screen
ClearScreen(RGB(150,150,150))
StartDrawing(ScreenOutput())
Circle(OurMouse\X,OurMouse\Y,5,255)
ForEach Tank()
Circle(Tank()\X,Tank()\Y,5,RGB(0,0,255)) ;/ tank
Diff_Angle = Radian(Tank()\Facing_Angle - Tank()\Angle_Of_Sight)
LineXY(Tank()\X,Tank()\Y,Tank()\X+(12*Sin(Diff_Angle)),Tank()\Y+(15*Cos(Diff_Angle)),RGB(0,255,0)) ;/ angle of turn 'pickup' -
Diff_Angle = Radian(Tank()\Facing_Angle + Tank()\Angle_Of_Sight)
LineXY(Tank()\X,Tank()\Y,Tank()\X+(12*Sin(Diff_Angle)),Tank()\Y+(15*Cos(Diff_Angle)),RGB(0,255,0)) ;/ angle of turn 'pickup' +
LineXY(Tank()\X,Tank()\Y,Tank()\X+(10*Sin(Radian(Tank()\To_Mouse_Angle))),Tank()\Y+(10*Cos(Radian(Tank()\To_Mouse_Angle))),0) ;/ angle towards mouse
LineXY(Tank()\X,Tank()\Y,Tank()\X+(15*Sin(Radian(Tank()\Facing_Angle))),Tank()\Y+(15*Cos(Radian(Tank()\Facing_Angle))),RGB(255,255,255)) ;/ tank angle
Next
StopDrawing()
FlipBuffers()
EndIf
Until Event = #PB_Event_CloseWindow