[bb] YawToEntity function (plus smart missile code). by Zethrax [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : YawToEntity function (plus smart missile code).
Author : Zethrax
Posted : 1+ years ago

Description : The YawToEntity function turns the specified source entity to point at the specified target entity at the rate specified. Turning is performed on the Y (yaw) axis. The rate value  is applied each time the function is called, so the rate of change will depend on how frequently the function is called.

In addition to the 2D-in-3D homing missile code used as an example below, the function could also be used to turn a bot to face a waypoint, or some other objective.

---

Here's the code for the YawToEntity function. It includes example code showing a smart missile homing in on a target.

Note that, a problem that I encountered with homing missiles, is that they can easily get locked into an orbit around the object they are targetting - particularly if that object is stationary. The smart missile code below deals with that by preventing the missile from turning if the missile is within a certain distance, and angle, relative to the target. The missile is prevented from turning until it has reached a certain distance from the target. The version of the code intended for ground based combat will allow the missile to turn, until it is pointing upwards, to reduce the chance that it will impact against a ground plane.

This code is for a space based game, where there's no ground plane for the missile to worry about.
; The number of logic updates per second.
Const C_LOGIC_FREQUENCY = 50

; The interval (in milliseconds) between logic updates.
Const C_LOGIC_INTERVAL# = 1000.0 / C_LOGIC_FREQUENCY ; Unused.

Const C_SMART_MISSILE_TEST_DISTANCE# = 10.0
Const C_SMART_MISSILE_TEST_ANGLE# = 60.0
Const C_SMART_MISSILE_NO_TURN_DISTANCE# = 15.0

Global timer = CreateTimer( C_LOGIC_FREQUENCY )

Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()

SeedRnd MilliSecs()

Global cam = CreateCamera()
CameraZoom cam, 1.6
MoveEntity cam, 0.0, 60.0, 0.0
TurnEntity cam, 90.0, 0.0, 0.0

Global light = CreateLight()

Global cone = CreateCone()
RotateMesh cone, 90.0, 0.0, 0.0
UpdateNormals cone
PositionEntity cone, 0.0, 0.0, -20.0

Global cube = CreateCube()
UpdateNormals cube
;PositionEntity cube, 40.0, 0.0, 20.0
PositionEntity cube, Rnd( -5.0, 5.0 ), 0.0, Rnd( -5.0, 5.0 )

Global dist#

While Not KeyHit( 1 )

dist# = EntityDistance( cone, cube )

If allow_turn
If dist# < C_SMART_MISSILE_TEST_DISTANCE#
If Abs( DeltaYaw( cone, cube ) ) > C_SMART_MISSILE_TEST_ANGLE#
allow_turn = False
EndIf
EndIf
Else
If dist# > C_SMART_MISSILE_NO_TURN_DISTANCE# Then allow_turn = True
EndIf

If allow_turn Then YawToEntity cone, cube, 3.0

MoveEntity cone, 0.0, 0.0, 0.5

If dist# < 2.0
PositionEntity cube, Rnd( -5.0, 5.0 ), 0.0, Rnd( -5.0, 5.0 )
EndIf

UpdateWorld
RenderWorld
Flip

WaitTimer( timer )

Wend

End


Function YawToEntity( src_entity, dest_entity, rate# )
; Turns 'src_entity' to point at 'dest_entity' at the rotation rate specified by 'rate#'.

Local target_yaw# = DeltaYaw( src_entity, dest_entity )

; If the required correction amount is less than the correction amount to be applied...
If Abs( target_yaw# ) < rate#
; Point 'src_entity' directly at 'dest_entity' to prevent jittering.
TurnEntity src_entity, 0.0, target_yaw#, 0.0
Else
; Turn 'src_entity' gradually towards 'dest_entity'.
TurnEntity src_entity, 0.0, rate# * Sgn( target_yaw# ), 0.0
EndIf
End Function

This code is for a ground based game, where there's a ground plane for the missile to worry about.

; The number of logic updates per second.
Const C_LOGIC_FREQUENCY = 50

; The interval (in milliseconds) between logic updates.
Const C_LOGIC_INTERVAL# = 1000.0 / C_LOGIC_FREQUENCY ; Unused.

Const C_SMART_MISSILE_TEST_DISTANCE# = 10.0
Const C_SMART_MISSILE_TEST_ANGLE# = 60.0
Const C_SMART_MISSILE_NO_TURN_DISTANCE# = 20.0

Global timer = CreateTimer( C_LOGIC_FREQUENCY )

Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()

SeedRnd MilliSecs()

Global cam = CreateCamera()
CameraZoom cam, 1.6
MoveEntity cam, 0.0, 60.0, 0.0
TurnEntity cam, 90.0, 0.0, 0.0

Global light = CreateLight()

Global cone = CreateCone()
RotateMesh cone, 90.0, 0.0, 0.0
UpdateNormals cone
PositionEntity cone, 0.0, 0.0, -20.0

Global cube = CreateCube()
UpdateNormals cube
PositionEntity cube, Rnd( -5.0, 5.0 ), 0.0, Rnd( -5.0, 5.0 )

Global dist#, allow_turn = True, disable_allow_turn_when_pointing_up = False

While Not KeyHit( 1 )

dist# = EntityDistance( cone, cube )

If allow_turn
If dist# < C_SMART_MISSILE_TEST_DISTANCE#
If Abs( DeltaYaw( cone, cube ) ) > C_SMART_MISSILE_TEST_ANGLE#
disable_allow_turn_when_pointing_up = True
EndIf
EndIf
Else
If dist# > C_SMART_MISSILE_NO_TURN_DISTANCE# Then allow_turn = True
EndIf

If disable_allow_turn_when_pointing_up
If Abs( EntityYaw( cone ) ) < 89.0 ; Note: 89 degrees is used so that the missile will turn upwards.
allow_turn = False
disable_allow_turn_when_pointing_up = False
EndIf
EndIf

If allow_turn Then YawToEntity cone, cube, 3.0

MoveEntity cone, 0.0, 0.0, 0.5

If dist# < 2.0
PositionEntity cube, Rnd( -5.0, 5.0 ), 0.0, Rnd( -5.0, 5.0 )
EndIf

UpdateWorld
RenderWorld
Flip

WaitTimer( timer )

Wend

End


Function YawToEntity( src_entity, dest_entity, rate# )
; Turns 'src_entity' to point at 'dest_entity' at the rotation rate specified by 'rate#'.

Local target_yaw# = DeltaYaw( src_entity, dest_entity )

; If the required correction amount is less than the correction amount to be applied...
If Abs( target_yaw# ) < rate#
; Point 'src_entity' directly at 'dest_entity' to prevent jittering.
TurnEntity src_entity, 0.0, target_yaw#, 0.0
Else
; Turn 'src_entity' gradually towards 'dest_entity'.
TurnEntity src_entity, 0.0, rate# * Sgn( target_yaw# ), 0.0
EndIf
End Function


Code :
Code (blitzbasic) Select
No code here, sorry. I prefer using a codebox.

Code is at: http://www.blitzbasic.com/codearcs/codearcs.php?code=2258


Comments :


Nate the Great(Posted 1+ years ago)

 Cool!I added an avoid entity function in the code archives!