Rotate to follow player

BlitzMax Forums/BlitzMax Beginners Area/Rotate to follow player

Matt(Posted 2007) [#1]
I'm just trying to get started at this, so please bare with me.

I have an enemy sprite that sits at a specific x,y coordinate. I want that sprite to be able to rotate to follow my player as it moves around it.

The problem I am having, is that atan2 seems to only work in 180 degrees at a time. So, what happens, is when my player breaks even on the Y coordinate, the enemy stops following.

Here's my code so far:
Method TrackPlayer()
		Local DestAngle:Float =  ATan2(PlayerY-Y,PlayerX-X)
		
		If DestAngle > Angle
			Angle :+ 1
		ElseIf DestAngle < Angle
			Angle :- 1
		EndIf
	EndMethod


Then, I SetRotation(Angle). Any ideas?

Thanks!


H&K(Posted 2007) [#2]
Method TrackPlayer()
		Local DestAngle:Float =  ATan2(PlayerY-Y,PlayerX-X)
If Angle<=-180 then Angle:+360		
if Angle> 180 then Angle:-360		
                If DestAngle > Angle
			Angle :+ 1

		ElseIf DestAngle < Angle
			Angle :- 1

		EndIf
EndMethod
This might not solve your problem, but the solution is to stop thinking that the angle is between 0 and 356 but rather between -179 and 180


mothmanbr(Posted 2007) [#3]
Use ATan2(-PlayerY+Y, PlayerX-X) instead, since the Y axis is "inverted" in blitz(going down = higher Y). I don't know if this will fix your thing, but I had some problems at first with angle and doing this solved it.


TomToad(Posted 2007) [#4]
@H&K, you need to get rid of the second check. If your angle is -1, then the first check will set it to 359. Then the second check will set it back to -1.


H&K(Posted 2007) [#5]
If its -1 then it isnt lessthan or equal to -180, so no, it wont change it at all.


dmaz(Posted 2007) [#6]
unless I'm missing something...H&K's solution just moves the problem from the 0 boundary to -180/180.

SuperStrict

Local txt:String[] = ["With turnRate","with 1 degree per frame","TrackPlayer()","immediate"]
Local opt:Int
Local angle:Float

Graphics 640,480
While Not KeyHit(KEY_ESCAPE)
	Cls
	Select True
		Case opt=0 Or opt=1
			Local turnRate:Float = .05
			If opt=1 Then turnRate=0
			
			angle :- Point( angle,AngleToTarget(320,240,MouseX(),MouseY()),turnRate)
			If angle < 0 Then angle :+ 360
			If angle > 360 Then angle :- 360
		
		Case opt=2
			TrackPlayer(320,240,MouseX(),MouseY(),angle)

		Case opt=3
			angle = AngleToTarget(320,240,MouseX(),MouseY())

	End Select

	DrawTri 320,240,angle

	
	If KeyHit(KEY_SPACE) Then opt:+1 ; If opt>3 Then opt=0
	DrawText txt[opt]+" - hit space to change",10,10
	DrawText angle,10,24
	Flip
Wend

Function AngleToTarget:Float( x1:Float,y1:Float, x2:Float, y2:Float )
	Local a:Float = ATan2(y2-y1,x2-x1)
	If a < 0 Then a :+ 360	'return 0-360
	Return a
End Function

Function Point:Float( angle1:Float, angle2:Float, turnRate:Float=0 )
	Local diff:Float = angle1-angle2
	If diff > 180
		diff :- 360
	ElseIf diff < -180
		diff :+ 360
	EndIf
	If Not turnRate Return Sgn(diff)
	Return diff*turnRate
End Function

Function TrackPlayer(x1:Float,y1:Float, x2:Float, y2:Float, Angle:Float Var)
	Local DestAngle:Float =  ATan2(y2-y1,x2-x1)
	If Angle<=-180 Then Angle:+360		
	If Angle> 180 Then Angle:-360
     If DestAngle > Angle
		Angle :+ 1

	ElseIf DestAngle < Angle
		Angle :- 1

	EndIf
End Function

Function DrawTri( x:Float, y:Float, angle:Float )
	Local tri:Float[] = [ -15#,-10#, 15#,0#, -15#,10# ]
	SetOrigin x,y
	SetRotation angle
	DrawPoly tri
	SetRotation 0
	SetOrigin 0,0
End Function



H&K(Posted 2007) [#7]
H&K's solution just moves the problem from the 0 boundary to -180/180
Maybe, but as ATan2s range is -179/180 its going to be a lot easyier to fix. And the original problem was that it wasint working between 0/180 so my original statemet is still valid.
This might not solve your problem, but the solution is to stop thinking that the angle is between 0 and 356 but rather between -179 and 180
I was showing that the root of the problem was a flaw in his thinking, specificly that of 180to180 rather than 0to360.


TomToad(Posted 2007) [#8]
If its -1 then it isnt lessthan or equal to -180, so no, it wont change it at all.

Sorry, misread it. For some reason I was seeing it as <= 0. Probably need to get away from the screen for a while. :)