Analogue controller turning

Blitz3D Forums/Blitz3D Programming/Analogue controller turning

Scribbla said i should post this, as it may help people, so here it is:

"turn_smoothing" determines how smooth the turning is.
"tolerance" determines the dead spot in the centre of the controller. Higher values result in a bigger dead spot.


; Using an analogue Controller
; left stick by Ross c

Graphics3D 1024,768,32
SetBuffer BackBuffer() 

camera=CreateCamera() 
PositionEntity camera,0,4,-40
light=CreateLight() 

cube=CreateCube( ) 
PositionEntity cube,0,0,3 

cone=CreateCone( )


PositionEntity cone,0,0,5
RotateEntity cone,90,0,0

EntityParent cone,cube

Global Joy_X#
Global Joy_Y#
Global tolerance# = 0.7
Global yaw_goto#
Global yaw#
Global turn_smoothing# = 0.8

While Not KeyHit(1) ; start main loop esc for Quit


If JoyX#() > -tolerance And JoyX#() < tolerance And JoyY#() > -tolerance And JoyY#() < tolerance Then
		Joy_Y# = 0
		Joy_X# = 0
	Else
		Joy_X# = JoyX#()
		Joy_Y# = JoyY#()

		yaw_goto = ATan2( -JoyX#(), -JoyY#() )
		If yaw_goto - yaw > 180 Then
			If yaw < 0 Then
				yaw = yaw + 360
			End If
		ElseIf yaw_goto - yaw < -180 Then
			If yaw > 0 Then
				yaw = yaw - 360
			End If
		End If

		yaw = yaw_goto - ((yaw_goto - yaw)*turn_smoothing)
End If

speed# = Sqr(Joy_Y#*Joy_Y#+ Joy_X#*Joy_X#)/2


MoveEntity cube,0,0,speed#
RotateEntity cube, 0,yaw#,0; EntityRoll(cube)
 

 RenderWorld 
Text 10,10,"JoyX()"+"  "+JoyX()+"   "+"joy_x= "+joy_x
Text 10,30,"JoyY()"+"  "+JoyY()+"   "+"joy_y= "+joy_y

Text 10,40,"yaw = "+yaw


	Flip

Wend  ; end main loop

End ; end program


Really you should be using something like this for the deadzone:

Joy_X# = GetValue( joyx() , .1 )

function GetValue#( joy# , DeadZone# )

  If Abs( joy ) < Deadzone
    joy# =0
  Else
    joy# = ( Joy - Sgn( Joy ) * DeadZone ) / ( 1.0 - DeadZone )
  EndIf

  return joy
end function


Say for example you have to use a high deadzone of .25. As soon as you hit .26 your speed will initially lurch rather than move smoothly.

You could also use deltayaw by parenting and positioning a pivot like so:


pivot = createpivot( cube )

joy_x# = GetValue( joyx(), .1 )
joy_y# = GetValue( joyy(), .1 )

if abs( joy_x ) > 0 or abs( joy_y) > 0 
  positionentity Pivot, joy_x , 0 , joy_y
  DY# = deltayaw( cube , pivot )
  turnentity cube, 0 , DY * .8 , 0
endif


Stevie

I did think about delta yaw, and i will be using it in future, because of the way the character will move in relation to the camera.

And i agree about the snappy speed up. I initially thought of getting the speed by abs((tolerance/1) * multiplier). I have totally redesigned it now, so i suppose i should update the code.

Your input is appreciated.

this is realy useful for the likes of me, with little idea about these things

Here's something else,... a bit late for the discussion, but still maybe helpful for someone.

There is only one function needed here,... the JoyEase() function. What this allows you to do is adjust the sensitivity of the stick so small movements are more accurate, but you still get the full range when you go to the far extents. This also has the benefit of dampening the center enough that you may not even need to use a deadspot anymore. (as long as you use an ease value of 1.5 - 2.0)


Graphics 640,480,0,2
Global x#,y#,JX#,JY#
Global power# = 2.0

While Not KeyHit(1)
	power = minmax( power + MouseZSpeed()*.1 , 1.0,2.0)

	;Grab the joystick values for this loop
	JX = JoyX()
	JY= JoyY()

	; this is all you need to do to use the exponential for your joypad
	x = JoyEase (JX,power)
	y = JoyEase (JY,power)

	; This just draws the stuff on screen
	x1 = FitValueToRange#(	x,	-1,1, 350, 500 )
	y1 = FitValueToRange#(	y,	-1,1, 50, 200 )
	x2 = FitValueToRange#(JX,-1,1, 350, 500 )
	y2 = FitValueToRange#(JY,-1,1, 50, 200 )
	Color 0,255,0 : Oval  x1-5,y1-5,10,10
	Text 350,235,"Green - Exponential input: " + power
	Text 350,250,"use mouse scroll wheel to change"
	Color 255,0,0 : Oval  x2-5,y2-5,10,10,0
	Text 350,220,"Red - Original input (unfiltered)"
	Color 255,255,255
	;draw exponential curve
	For x = -1 To 1 Step .01
		y =joyease(x,power);)Abs(x)^power * Sgn(x)
		Plot (x*100)+100,y*100+100
	Next
	Rect 350,50,150,150,0
	
	Flip
	Cls 
Wend
End

; Power values should range from 1.0 (no effect)  to 2.0 (Ease curve) for best results.
Function JoyEase# (Value#,power# = 2.0)
	Return Abs(value)^power * Sgn(value)
End Function

Function minmax# (value#,minval#,Maxval#)
	If value > maxval value = maxval
	If value < minval value = minval
	Return value
End Function

Function FitValueToRange#( InValue#, RangeIn_Start#, RangeIn_End#, RangeOut_Start#, RangeOut_End# )
	OldRange# = RangeIn_End#-RangeIn_Start#
	NewRange# = RangeOut_End# - RangeOut_Start#	
	OutValue# = ((InValue#-RangeIn_Start) / OldRange#) * NewRange#	+ RangeOut_Start		
	Return OutValue#
End Function




Hey nice stuff man.