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. :) |