Code archives/Algorithms/2D turret firing algorhytms
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| From article: Forestalling (rus) | |||||
'Turret firing algorhytms including forestalling and self-training AI by Matt Merkulov
Graphics3D 800, 600
PositionEntity CreateCamera(), 0, 0, -20
RotateEntity CreateLight(), 45, 45, 45
; Type for a turret - coordinates, angle, mode of shooting, handles for 3D - objects, variables for AI
Type turret
Field x#, y#, Mode, head, barrel, ang#, dir#, dx#, dy#
End Type
; Type for a shot - coordinates, increments, handle of 3D - object,
; Distance from a turret, auxiliary variables for AI
Type shot
Field x#, y#, dx#, dy#, h, r#, tx#, ty#, dir#, t.turret
End Type
Const aimax = 200, aistp# = .2
Dim aiang# (aimax)
SetFont LoadFont("arial", 14)
SetBuffer BackBuffer()
; Constants - the period of shooting, speed of shells, speed of the player
Const frq = 200, v0# = .01, vp# = .005
; Const frq = 200, v0# = .2, vp# = .1
Const bs# = 2
Global x#, y#
; createturret 1:createturret 2:createturret 3:createturret 4
createturret 5:createturret 4:createturret 2
; Creation of the player
p = CreateSphere(16)
h = CreateSphere(8, p)
PositionEntity h, 1, 0, 0
ScaleEntity h, .4, .4, .4
Repeat
tim = MilliSecs()
For t.turret = Each turret
; Auxiliary variables + targetting on the player by default
dx# = x# - t\x
dy# = y# - t\y
cang# = ATan2(dy#, dx)
t\dx# = dx#
t\dy# = dy#
t\dir# = cang#
pr# = Sqr(dx# * dx# + dy# * dy#)
; Modes of an aiming of turrets:
Select t\Mode
Case 0; shooting in the given direction
cang = 0
Case 1; shooting with rotation
cang# = t\ang# + .05 * dt#
Case 2; exact targetting on object
Case 3; shooting by a fan
cang# = cang# + Sin(dcang#) * 30
dcang# = dcang# + 2
Case 4; shooting on an forestalling
; Calculation of factors of a quadratic
a# = v# * v# - v0# * v0#
b# = 2.0 * v# * (dx# * Cos(ang#) + dy# * Sin(ang#) -bs#)
c# = dx# * dx# + dy# * dy# - bs# * bs#
; Calculation of a discriminant
d# = b# * b# - 4.0 * a# * c#
If d# >= 0 Then
; Calculation of the moment of a meeting of a shell and the player
t1# = (-b# + Sqr(d#)) / 2.0 / a#
t2# = (-b# - Sqr(d#)) / 2.0 / a#
If t2# > 0 Then t1# = t2#
If t1# >= 0 Then
; Calculation of a angle through coordinates of object during the found moment of time
cang# = ATan2(y# + t1# * v# * Sin(ang#) - t\y#, x# + t1# * v# * Cos(ang#) - t\x#)
End If
End If
Case 5; a self - training turret (the amendment to a angle undertakes from a file)
cang# = cang# + aiang(Int(pr# * aistp#))
End Select
; Turn of a turret
rotateturret t, cang#
; Return of a barrel on former position
If EntityX(t\barrel) < .75 Then MoveEntity t\barrel, 0, - .25 / frq * dt#, 0
; A shot and displacement of a barrel inside of a turret
If nextshot <= tim Then
fire t
PositionEntity t\barrel, .5, 0, 0
End If
Next
; Delay between shots
If nextshot <= tim Then nextshot = tim + frq
For s.shot = Each shot
; Moving bullets
s\x# = s\x# + s\dx# * dt#
s\y# = s\y# + s\dy# * dt#
s\r# = s\r# + v0# * dt#
PositionEntity s\h, s\x#, s\y#, 0
; If distances from a turret up to a bullet and up to the player are equal,
If pr# <= s\r# And s\dir# < 999 Then
; The adjusting angle for the given distance is calculated
Newang# = s\t\dir# - s\dir#
; Squeezes into borders (-180, 180)
Newang# = Newang# - Floor((Newang# + 180.0) / 360.0) * 360.0
; Also storing it in a file,
aiang(Int(pr# * aistp#)) = Newang#
;(A next line - for not to store this bullet in a file once again)
s\dir# = 999
End If
If(s\x# - x#) ^ 2 + (s\y# - y#) ^ 2 < 1 Then
FreeEntity s\h: Delete s
red = 255
hits# = hits# + 1
Else
; Removing the bullets which have overstepped the bounds of the screen
If Abs(s\x#) + Abs(s\y#) > 40 Then FreeEntity s\h:Delete s
End If
Next
; Indication of hit
If red > 0 Then
red = red - Int(dt / 3)
Else
red = 0
End If
EntityColor p, 255, 255 - red, 255 - red
; Moving and turn of the player (speed is calculated depending on last time)
PositionEntity p, x#, y#, 0
RotateEntity p, 0, 0, ang#
v# = (KeyDown(200) - KeyDown(208)) * vp#
ang# = ang# + .3 * dt# * (KeyDown(203) - KeyDown(205))
x# = x# + v# * Cos(ang#) * dt#
y# = y# + v# * Sin(ang#) * dt#
RenderWorld
; Counter
Text 0, 0, "Hits / sec:" + (hits# / sec#)
Flip
; Time, spent for this cycle (fractional as it is multiplied by fractional values)
dt# = MilliSecs() - tim
sec# = sec# + 0.001 * dt#
Until KeyHit(1)
Function createturret(Mode)
; Creation of a head part
t.turret = New turret
t\head = CreateCylinder(6)
ScaleMesh t\head, 1, .5, 1
RotateMesh t\head, 90, 0, 0
; A barrel created separately, but to adhere to a head part
t\barrel = CreateCylinder(16, False)
RotateEntity t\barrel, 0, 0, 90
ScaleEntity t\barrel, .2, 1, .2
PositionEntity t\barrel, .75, 0, 0
h = CreateCylinder(16, True)
ScaleEntity h, .3, .3, .3
RotateEntity h, 0, 0, 90
PositionEntity h, 2, 0, 0
EntityParent t\barrel, t\head
EntityParent h, t\barrel
; Setting random coordinates of a turret
t\x# = Rnd(-20, 20)
t\y# = Rnd(-20, 20)
PositionEntity t\head, t\x#, t\y#, 0
t\Mode = Mode
End Function
Function rotateturret(t.turret, ang#)
t\ang# = ang#
RotateEntity t\head, 0, 0, ang#
End Function
Function fire(t.turret)
ang# = t\ang#
s.shot = New shot
s\x# = t\x# + Cos(ang#) * r
s\y# = t\y# + Sin(ang#) * r
s\r# = r
s\dx# = Cos(ang#) * v0#
s\dy# = Sin(ang#) * v0#
s\h = CreateSphere(2)
ScaleEntity s\h, .15, .15, .15
EntityColor s\h, 255, 255, 0
; Auxiliary variables(for AI)
s\tx# = t\x#
s\ty# = t\y#
s\dir = t\dir#
s\t = t
End Function |
Comments
None.
Code Archives Forum