Rotation Problem

BlitzMax Forums/BlitzMax Beginners Area/Rotation Problem

Matt Vinyl(Posted 2010) [#1]
Hi all,

The player in my game is always centred in the middle of the screen (centred at 400x300). I want them to be able to face in 8 directions (the usual up, down, left, right and at 45 degree angles).

The snippet of code below I thought would work (it's only for some directions) but it's messy and doesn't feel right when tested - particularly the 45 degree test.

If KeyDown(KEY_UP) Then
		If PlayerRotate>0 And PlayerRotate<=180
			PlayerRotate:-5
		End If
		If PlayerRotate>180 And PlayerRotate<360
			PlayerRotate:+5
		End If
	End If
	
	If KeyDown(KEY_RIGHT) And KeyDown(KEY_UP) Then
		If PlayerRotate>45 And PlayerRotate<=225
			PlayerRotate:-5
		End If
		If PlayerRotate>225 Or PlayerRotate<45
			PlayerRotate:+5
		End If
	End If
	
	If KeyDown(KEY_RIGHT) Then
		If PlayerRotate>90 And PlayerRotate<=270
			PlayerRotate:-5
		End If
		If PlayerRotate>270 Or PlayerRotate<90
			PlayerRotate:+5
		End If
	End If


Could anyone advise of a 'clean' way to rotate my player using the 4 arrow keys (holding 2 for diagonals)?

Please let me know if you need me to explain further.


Czar Flavius(Posted 2010) [#2]
Do you want the right key to always rotate clockwise, or always rotate to the right-hand side direction?


Matt Vinyl(Posted 2010) [#3]
Always to the right. So if the player is facing top-left, they will rotate clockwise to face right. If they were facing bottom-left, they will rotate anti-clockwise to face right.

Hope that makes sense!


Jesse(Posted 2010) [#4]
the problem with doing a 45 degree turn is that you can never release both keys at the same time. you will almost always release either one first so
you will "almost" always end up in 0, 90,180, or 270 degrees. I was doing something similar but I didn't quite find it useful for my needs. here is a stripped down version of what I was doing:
SuperStrict
Local angle# = 0
Local turnSpeed# = 5
Local targetAngle# = 0
Local keystate% = 0
Local difference#

Const MASK:Int			= %1111
Const cUP:Int 			= %1000
Const cUPRIGHT:Int 	= %1001
Const cRIGHT:Int		= %0001
Const cRIGHTDOWN:Int= %0011
Const cDOWN:Int 		= %0010
Const cDOWNLEFT:Int = %0110
Const cLEFT:Int		= %0100
Const cLEFTUP:Int		= %1100 
Graphics 800,600

Repeat
	Cls
	If KeyDown(KEY_RIGHT) 	KeyState :| cRIGHT Else keystate :& ~cRight & MASK
	If KeyDown(KEY_DOWN) 	keyState :| cDOWN  Else keystate :& ~cDOWN  & MASK
	If KeyDown(KEY_LEFT) 	keyState :| cLEFT  Else keystate :& ~cLEFT  & MASK
	If KeyDown(KEY_UP) 		keystate :| cUP    Else keystate :& ~cUP   & MASK

	Select keyState
		Case cUP 			TargetAngle = 270
		Case cUPRIGHT		TargetAngle = 315
		Case cRIGHT			TargetAngle = 0
		Case cRIGHTDOWN	TargetAngle = 45
		Case cDOWN	 		TargetAngle = 90
		Case cDOWNLEFT 	TargetAngle = 135
		Case cLEFT			TargetAngle = 180
		Case cLEFTUP		TargetAngle = 225
	End Select
	difference# = Abs(targetAngle-angle)
	If TargetAngle > Angle				
		If difference > 180.0 Angle :- TurnSpeed Else angle :+ TurnSpeed
	ElseIf TargetAngle < angle
		If difference > 180.0 angle :+ TurnSpeed Else angle :- TurnSpeed
	EndIf
	angle = (angle+360.0) Mod 360.0 
	
	Local dx# = Cos(angle) * 30
	Local dy# = Sin(angle) * 30
	DrawText Bin(keystate), 10,10
	DrawText "target Angle = " + targetAngle,10,30
	DrawText "angle = "+ angle,10,50
	DrawLine 400,300, 400+dx,300+dy
	Flip()

Until KeyDown(key_escape)

maybe you find some use and can adopt it


Matt Vinyl(Posted 2010) [#5]
Cheers - you are indeed correct, it was very rare for my sprite to remain in the 45-degree position.

I'll grab that code and have a play if you don't mind? I 'might' just go with a different approach and have the 'up' key for acceleration along with the right and left for rotation.

It's funny how different you have to programme for a keyboard over an 'old fashioned' joystick!

Been considering what would be the best way to do 8-way movement via a keyboard and probably my first idea wasn't the best...