Code archives/Miscellaneous/7 AI steering behaviors

This code has been declared by its author to be Public Domain code.

Download source code

7 AI steering behaviors by RustyKristi2016
This is Drak's AI Steering Behavior which never made its way here in code archives and is buried in the forums so I'd be glad to upload it here for posterity.
;Originally coded 10/2010 by Drak
;Drak's STEERING BEHAVIOR RELEASED 11/30/2012
;----------------------------------------------------------------------------------------
AppTitle "Botz Steering Examples v.0a ","Close the program?"
Graphics3D 800,600,16,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()

MoveMouse 400,300

Global trebuchet_small = LoadFont ("trebuchet MS",16)	;and this is for the messagebox
SetFont trebuchet_small					;set the font to the loaded copperplate

;-------------------------------------------------
;CONSTANTS
;-------------------------------------------------
Const max_bots = 40 		;maximum # of bots in simulation


;-------------------------------------------------
;GLOBALS
;-------------------------------------------------
Global new_message = 0		;Do NOT change, this is for the message box function 
Global startup = 0			;leave at 0
Global action = 1			;this refers to an action selection for each demonstration action

;-------------------------------------------------
;STARTUP
;-------------------------------------------------

;LIGHTS AND CAMERA
Global light = CreateLight()
RotateEntity light, 90,0,0
Global camerapivot = CreatePivot
Global camera = CreateCamera(camerapivot)
RotateEntity camera, 90,0,0
PositionEntity camera, 0,100,0
						

;BOT MESH
Global bot_mesh = CreateSphere()
Global bot_nose = CreateSphere(8,bot_mesh)
ScaleEntity bot_nose,.3,.3,.3
MoveEntity bot_nose,0,0,1
EntityColor bot_nose, 100,0,0
EntityColor bot_mesh, 175,0,0
HideEntity bot_mesh

Global center = CreateSphere()

;-------------------------------------------------
;TYPES
;-------------------------------------------------
Type bot
	Field mesh		;holds the actual model of the bot
	Field target	;holds the bot's target entity #
	Field mass#
	Field velocity#
	Field max_velocity#
	Field acceleration#
	Field max_acc#
	Field turn#
	Field max_turn#
	Field status
	Field steer_ball
	Field steer_pivot
	Field steer_setup 
	Field steer_angle#
End Type

;-------------------------------------------------
;COLLISIONS
;-------------------------------------------------



;-------------------------------------------------
;MESSAGE BOX, Create a 7 line message box
;-------------------------------------------------
Dim mb_box$(7)						;create a 7 dimention array
									;whatever is typed in here will be displayed at program launch
	mb_box$(0) = ""  					;give them all nothing by using ""
	mb_box$(1) = "" 					;
	mb_box$(2) = "" 					;
	mb_box$(3) = "" 					;	
	mb_box$(4) = "" 					;
	mb_box$(5) = "" 					;
	mb_box$(6) = "Steering Demonstration. Keys 1-5 change bot status.  Starting in mode #2, which is Flee." ;This is the starting message that appears in the message box
	
Global old1$=0						;DO NOT alter any of these lines
Global old2$=0						;DO NOT alter any of these lines
Global old3$=0						;DO NOT alter any of these lines
Global old4$=0						;DO NOT alter any of these lines
Global old5$=0						;DO NOT alter any of these lines
Global old6$=0						;DO NOT alter any of these lines
Global old7$=0						;DO NOT alter any of these lines

;-------------------------------------------------
;MAINLOOP!
;-------------------------------------------------
While Not KeyHit(1)

startup()
get_input()
update_bots()
UpdateWorld
RenderWorld

mb_scroll()


Flip False


Wend	

;-----------------------------------------------------------------------------------------------------
;MESSAGE BOX
;-----------------------------------------------------------------------------------------------------
	
Function mb_scroll()
		SetFont trebuchet_small
		If new_message = 1				;if we have a new message in que
				mb_box(5) = old6$		;box 5 will now equal what box 6 was before
				mb_box(4) = old5$		;and so on...
				mb_box(3) = old4$
				mb_box(2) = old3$
				mb_box(1) = old2$
				mb_box(0) = old1$		;till the end
			new_message = 0				;reset the new message flag
		End If 
				
		Text 10, 525, mb_box(0)		;1
		Text 10, 535, mb_box(1)		;2
		Text 10, 545, mb_box(2)		;3
		Text 10, 555, mb_box(3)		;4
		Text 10, 565, mb_box(4)		;5
		Text 10, 575, mb_box(5)		;6
		Text 10, 585, mb_box(6)		;7th and new line
		
		old1$ = mb_box(1)				;store these strings in another variable for the next loop
		old2$ = mb_box(2)				
		old3$ = mb_box(3)
		old4$ = mb_box(4)
		old5$ = mb_box(5)
		old6$ = mb_box(6)

End Function

;-----------------------------------------------------------------------------------------------------
;STARTUP
;-----------------------------------------------------------------------------------------------------
Function startup()
	If startup = 0											;if flagged as 0
	For num = 1 To max_bots									;do this the (max_bots) times
		b.bot = New bot										;create a new bot
		b\mesh = CopyEntity(bot_mesh)						;copy the predefined mesh for the body
		EntityColor b\mesh, Rand(175),Rand(175),Rand(175)	;pick a lovely color
		b\mass = .5											;set it's mass
		b\velocity = Rnd(.01,.015)							;give it a random velocity
		b\max_velocity = Rnd(.8,1.2)						;and set it's max velocity
		b\acceleration = 0									;acceleration is at 0
		b\max_acc = Rnd(.008,.013)							;max acceleration is set here
		b\turn = 0											;turn is 0
		b\max_turn = Rnd(.08,.12)							;max turn angle
		b\status = 2										;set the status as #2
		b\steer_setup = 0									;
		PositionEntity b\mesh,Rand(-50,50),0,Rand(-50,50)	;set the position randomly
	Next
	startup = 1												;then flip the startup flag to 1 so we don't repeat this code
	End If 
End Function 

;-----------------------------------------------------------------------------------------------------
;UPDATE BOTS
;-----------------------------------------------------------------------------------------------------
;We will only act upon the selected status and steering selection.  No other
;factors will affect the bots in this simulation.
Function update_bots()
For b.bot = Each bot
	Select b\status 
		
	;CASE 1 IS SEEK STEERING
	Case 1
		;we'll use the central object for the target
		;so, first get the delta yaw to turn the bot to the center object
			
			Local deltay# = DeltaYaw(b\mesh,center)	;store this in a floating point variable
			Local dist#	= EntityDistance(b\mesh,center) ;get the distance also, and store it
			
				If deltay > .1  	;if the angle is > 0
					b\turn = b\turn + .001
					If b\turn > b\max_turn Then b\turn = b\max_turn
				ElseIf deltay < -.1 	;if the angle is < 0
					b\turn = b\turn - .001
					If b\turn < -b\max_turn Then b\turn = -b\max_turn
				End If
				
				;turn the entity the desired direction 
				TurnEntity b\mesh, 0,b\turn,0
				
				If dist >= 10
					b\acceleration = b\acceleration + .00001
						If b\acceleration > b\max_acc Then b\acceleration = b\max_acc
					b\velocity = b\acceleration
					;BY ADDING THE NEXT ELSE IFs, WE CAN DECELERATE (3=ARRIVE) SLOWLY
				Else If dist < 10 And dist > 2
					b\acceleration = b\acceleration - .00001
						If b\acceleration < .001 Then b\acceleration = .001
					b\velocity = b\acceleration
				Else If dist <= 2
					b\acceleration = b\acceleration - .00001
					If b\acceleration <= 0 Then b\acceleration = 0
					b\velocity = b\acceleration
				End If
				
				MoveEntity b\mesh, 0,0,b\velocity
	
	;CASE 2 IS FLEEING
	Case 2
		;this is essentially the same as seek, only backwards
			
			Local deltay2# = DeltaYaw(b\mesh,center)	;store this in a floating point variable
			Local dist2#	= EntityDistance(b\mesh,center) ;get the distance also, and store it
			
				If deltay2 < 0 				;if the angle is > 0
					b\turn = b\turn + .001
					If b\turn > b\max_turn Then b\turn = b\max_turn
				ElseIf deltay2 > 0			;if the angle is < 0
					b\turn = b\turn - .001
					If b\turn < -b\max_turn Then b\turn = -b\max_turn
				End If
				
				;turn the entity the desired direction 
				TurnEntity b\mesh, 0,b\turn,0
				
				If dist2 < 50
					b\acceleration = b\acceleration + .00001
						If b\acceleration > b\max_acc Then b\acceleration = b\max_acc
					b\velocity = b\acceleration
					;BY ADDING THE NEXT ELSE IFs, WE CAN DECELERATE (3=ARRIVE) SLOWLY
				Else If dist2 > 50
					b\acceleration = b\acceleration - .00001
						If b\acceleration < .001 Then b\acceleration = .001
					b\velocity = b\acceleration
				End If
				
				MoveEntity b\mesh, 0,0,b\velocity
	
	;CASE 3 IS WANDERING
	Case 3
	;This can be easily overcomplicated, so lets keep it simple
	
	b\steer_angle = b\steer_angle + Rnd(-.01,.01)			;simply adjust the steering angle slightly
		If b\steer_angle > .1 Then b\steer_angle = .1		;and keep it within a reasonalble amount
		If b\steer_angle < -.1 Then b\steer_angle =  -.1	;same...
	TurnEntity b\mesh,0,b\steer_angle,0						;then turn it...
	MoveEntity b\mesh,0,0,b\max_acc							;and move it! Easy!
	

	;CASE 4 IS COHESION
	Case 4
		Local closest# = 1000	;start at 1000
	
	;Here we get the Nearest bot
	For n.bot = Each bot
		If b\mesh <> n\mesh
		Local dist_n# = EntityDistance(b\mesh, n\mesh)	;get distance to each bot
			If dist_n < closest	;if the distance is smaller than the previous smallest
				closest = dist_n
				b\target = n\mesh			
			End If
		End If
	Next	
		
		;And move it towards that nearest bot
		;HERE IS THE #7 SEPERATION VALUE, (3 UNITS)
		If closest > 3
		Local d3# = DeltaYaw(b\mesh,b\target)	;store this in a floating point variable
			
			
				If d3 > .1  	;if the angle is > 0
					b\turn = b\turn + .001
					If b\turn > b\max_turn Then b\turn = b\max_turn
				ElseIf d3 < -.1 	;if the angle is < 0
					b\turn = b\turn - .001
					If b\turn < -b\max_turn Then b\turn = -b\max_turn
				End If
				
				;turn the entity the desired direction 
				TurnEntity b\mesh, 0,b\turn,0
				
				If closest >= 7
				b\acceleration = b\acceleration + .00001
					If b\acceleration > b\max_acc Then b\acceleration = b\max_acc
				Else If closest < 7
				b\acceleration = b\acceleration - .00001
					If b\acceleration < 0 Then b\acceleration = 0
				End If
				
				
				b\velocity = b\acceleration 	
				MoveEntity b\mesh,0,0,b\velocity
			 	
		End If  
	
	;HERE IS #6 ALIGNMENT WITH NEIGHBORS	
	;(this only works correctly AFTER using case 4, cohesion)
	Case 5
		If b\target <> 0
			Local vector# = EntityYaw(b\target,1)
				Local my_vector# = EntityYaw(b\mesh,1)
				
				If my_vector > vector  	;if more
					b\turn = b\turn - .001
					If b\turn > b\max_turn Then b\turn = b\max_turn
				ElseIf my_vector < vector 	;if less
					b\turn = b\turn + .001
					If b\turn < -b\max_turn Then b\turn = -b\max_turn
				End If
				
				;turn the entity the desired direction 
				TurnEntity b\mesh, 0,b\turn,0
		End If 
	
	End Select




Next
End Function 
				
;-----------------------------------------------------------------------------------------------------				
;GET INPUTS
;-----------------------------------------------------------------------------------------------------
Function get_input()
If KeyHit(2)
	new_message = 1
	mb_box(6) = "Steering set to SEEK. Bots will SEEk to the center sphere."
	For b.bot = Each bot
		b\status = 1
	Next
End If

If KeyHit(3)
	new_message = 1
	mb_box(6) = "Steering set to FLEE. Bots will FLEE from the center sphere."
	For b.bot = Each bot
		b\status = 2
	Next
End If 

If KeyHit(4)
	new_message = 1
	mb_box(6) = "Steering set to WANDER. Bots will wander aimlessly."
	For b.bot = Each bot
		b\status = 3
	Next
End If 

If KeyHit(5) ;4
	new_message = 1
	mb_box(6) = "Steering set to COHESION WITH SEPERATION. Bots will move to the center of mass with it's neighbors."
	For b.bot = Each bot
		b\status = 4
	Next
End If 

If KeyHit(6) ;5
	new_message = 1
	mb_box(6) = "Steering set to ALIGNMENT WITH NEIGHBORS. Bots will attempt to align themsleves with their neighbors."
	For b.bot = Each bot
		b\status = 5
	Next
End If 

End Function

Comments

BlitzplotterMay
Awesome code, I like the smooth feel of it all. Thanks for sharing.


Rick NasherMay
Very nice and usable in combo with other stuff so thanks, but why is it called "7 AI steering behaviors" when I see only 5?


BlitzplotterMay
You've inspired me rick, adding a couple of more AI modes to Draks code ;)


Code Archives Forum