Character controlling, 8 directions

Blitz3D Forums/Blitz3D Programming/Character controlling, 8 directions

Jeroen(Posted 2003) [#1]
Hi guys,

Because I'm on a tight deadline for my schoolproject, and that I'm not progessing on the code below, it would be great if someone could help me with this. Afterwards I can post this in the code archives.

The code below turns a cube in 8 direction using a "smooth" transition. Only: the rotation values from blitz are not from 0 to 360 degrees. Result is that the circle sometimes does not take the shortest route available.

Can someone help me out on how I can choose the shortest path? I'm almost "there", but this is keeping me away from implementing it into the game.

Thanks,

Jeroen


Graphics3D 800,600,32
SetBuffer BackBuffer()

Const KEY_UP 	 = 200
Const KEY_DOWN   = 208
Const KEY_LEFT   = 203
Const KEY_RIGHT  = 205
Global targetang#, angoffset,thisang#, ang



Global entity = CreateCube()
Global Cam = CreateCamera()

light = CreateLight()

MoveEntity (Cam, 0, 9, -30)
CameraRange (Cam, 0.2, 2000)
PointEntity (cam,entity)

sphere=CreateSphere(8,entity)
MoveEntity sphere,0,0,3

ref#=1

direction$ = "left"


While Not KeyHit (1)
	repondToKeys()
	
	thisang# = EntityYaw(entity)
	ConvAng = convertAng(thisang)
	
	
	If direction$ = "left" TurnEntity(entity, 0, 0.25*(targetang - ConvAng ), 0)
	If direction$ = "right" TurnEntity(entity, 0, -0.25*(targetang - ConvAng ), 0)
	
	If Abs(targetang-ConvAng )<8 readyToWalk=True Else readyToWalk=False
	
	
	RenderWorld
	
	; THIS CODE IS THE PROBLEM
	; ---------------------------------------------------
	If (targetang - ConvAng)<-180
		; probably we are taking a wrong direction now
		Text 0,180,"not a good idea"
		targetang = 360 - targetang
	Else If (targetang - ConvAng)>180
		; probably we are taking a wrong direction now
		Text 0,180,"not a good idea"
		targetang = targetang + 360

	End If
	; ---------------------------------------------------


	Text 0,100,"target angle:"+targetang 
	Text 0,120,"This angle:"+ConvAng 
	Text 0,140,"Ready to walk:"+readyToWalk
	Text 0,160,"TargetAng - ConvAng = "+(targetang - ConvAng)
	Delay(40)
	Flip
Wend

End

; ------------------------------------------------------------------------------------

Function convertAng(ta)
	If ta<0 ta=360+ta
	Return ta
End Function

; ------------------------------------------------------------------------------------

Function repondToKeys()
	
	If KeyDown(KEY_UP) And KeyDown(KEY_LEFT)	
		targetang = 45
		
	Else If KeyDown(KEY_DOWN) And KeyDown(KEY_LEFT)
		targetang = 135

	Else If KeyDown(KEY_DOWN) And KeyDown(KEY_RIGHT)
		targetang = 225
	
	Else If KeyDown(KEY_UP) And KeyDown(KEY_RIGHT)
		targetang = 315
	
	Else If KeyDown(KEY_UP)	
		targetang = 0
	
	Else If KeyDown(KEY_DOWN)
		targetang = 180
	
	Else If KeyDown(KEY_LEFT)
		targetang = 90
	
	Else If KeyDown(KEY_RIGHT)
		targetang = 270
	End If
	
End Function


; ------------------------------------------------------------------------------------


Edit: adjusted to 0-360 coordinates


IPete2(Posted 2003) [#2]
Jeroen,

There is a turn through the shortest path/direction code in the archives.

IPete2.

In fact here is the code ----



;=================================================
Function where_to_turn(source_pivot,target_pivot)
;=================================================
;parameters:
; source_pivot: is the source pivot that we want to turn toward a target pivot
; target_pivot: is a target pivot where we want the source pivot to rotate to

;Returned values:
; 0 : no turn needed
; 1 : turn left
; -1 : turn right

temp = Createpivot() ;first, create a temp entity on the source pivot

;position the temp pivot at the source pivot position
PositionEntity temp,EntityX(source_pivot),EntityY(source_pivot),EntityZ(source_pivot)

PointEntity temp,target_pivot ;turns the temp pivot to the target pivot
;now temp pivot has the yaw that the source should have

;memo start angle and end angle, I just consider the integer parts of it, using Floor
s = Floor(EntityYaw(source_pivot)) ;this is the start yaw angle, that is, the current yaw orientation of the source
t = Floor(EntityYaw(temp)) ;this is the end angle, that is, the angle we should reach

FreeEntity (temp) ;release the temp entity, we do not need it from now

If s = t Then ;if the two angles are the same we do not need any rotation !
Return 0
EndIf

;the angle goes from 0,180 and 0,-180; now I normalize to 0-360
If s < 0 Then s = 360 + s
If t < 0 Then t = 360 + t

;now we found the right direction where to turn, in order to choose the shortest path:

;check if the difference is greather than 180
If Abs(s-t) > 180 Then

;check if the start angle is greater than the target angle
If s > t Then
Return 1 ;turn left
Else
Return -1 ;turn right
EndIf
Else
;check if the start angle is greater than the target angle
If s > t Then
Return -1 ;turn right
Else
Return 1 ;turn left
EndIf

EndIf

End Function


Jeroen(Posted 2003) [#3]
As you can see in my code I have a different approach where I do not need a pivot. The code you supplied is cool, but conflicts with the approach I took.

The code at the comment "THIS CODE IS THE PROBLEM" detects if the total angle is >180, which means that it takes a too big route towards the destination.
Okay, the IF/THEN is okay, but what do I need to enter to fix the targetangle?