Rotate to follow player
BlitzMax Forums/BlitzMax Beginners Area/Rotate to follow player
| ||
| 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! |
| ||
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
EndMethodThis 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 |
| ||
| 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. |
| ||
| @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. |
| ||
| If its -1 then it isnt lessthan or equal to -180, so no, it wont change it at all. |
| ||
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'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. |
| ||
| 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. :) |