need a little mathy help.
BlitzMax Forums/BlitzMax Programming/need a little mathy help.
| ||
| Did a quick google to get an image for you to use, its a gif so you will need to change the code a little, but its got the same orientation as the sprite I am using. Ok the problem, as you know blitz angles/degree's have zero at the right, and 180 at the left, and the range is -180 to 180, this always gets me all confused when trying to use these values to control the direction of travel and rotation of an image. In short I want the little sprite to go after the mouse, but I'm going wrong with the math some where and not being brilliant at math cant seem to work out where. ![]()
Strict
Framework BRL.GLMax2D
Import BRL.PNGLoader
SetGraphicsDriver GLMax2DDriver()
Global GFX_Width :Int = 500
Global GFX_Height :Int = 500
Graphics GFX_Width , GFX_Height , 0
AutoMidHandle(True)
Global ImageShip:TImage = LoadImage("ship.png")
Type TShip
Field x:float
Field y:float
Field vx:float
Field vy:float
Field fAngle:float
Field tAngle:float
Field turnrate:float
Field speed:float
End type
Global Ship:TShip = New TShip
Ship.x = 100
Ship.y = 100
Ship.fAngle = 0
Ship.tAngle = 0
Ship.turnrate = 0
Ship.speed = 1
repeat
cls
turnship()
moveship()
SetRotation -Ship.fAngle
DrawImage ImageShip,Ship.x,Ship.y
SetRotation 0
flip
Until KeyHit(KEY_ESCAPE)
Function turnship()
Ship.vx:+ Cos(Ship.fAngle)*Ship.speed
Ship.vy:+ Sin(Ship.fAngle)*Ship.speed
Ship.x:+ Ship.vx
Ship.y:+ Ship.vy
'Set Rotation
Ship.tAngle = (ATan2(Ship.y-MouseY(),Ship.x-MouseX())+180.0) Mod 360.0
Local difference:float = Abs(Ship.tAngle-Ship.fAngle)
If Ship.tAngle < Ship.fAngle
If difference > 180.0 Ship.turnrate=2 Else Ship.turnrate=-2
ElseIf Ship.tAngle > Ship.fAngle
If difference > 180.0 Ship.turnrate=-2 Else Ship.turnrate=2
EndIf
Ship.fAngle = (Ship.fAngle - Ship.turnrate +360) Mod 360
End function
Function moveship()
Ship.vx = - Cos(Ship.fAngle) * Ship.speed
Ship.vy = - Sin(Ship.fAngle) * Ship.speed
Ship.x:- Ship.vx
Ship.y:+ Ship.vy
DrawText Ship.fAngle , 1 , 1
DrawText Ship.tAngle , 1 , 30
End function
Last edited 2011 Last edited 2011 Last edited 2011 Last edited 2011 |
| ||
Solved it, although I am sure the way I fudged this to get it working is not the best way, so if anyone spots a much easier way please let me know.
Strict
Framework BRL.GLMax2D
Import BRL.PNGLoader
SetGraphicsDriver GLMax2DDriver()
Global GFX_Width :Int = 500
Global GFX_Height :Int = 500
Graphics GFX_Width , GFX_Height , 0
AutoMidHandle(True)
Global ImageShip:TImage = LoadImage("ship.png")
Type TShip
Field x:Float
Field y:Float
Field vx:Float
Field vy:Float
Field fAngle:Float
Field tAngle:Float
Field turnrate:Float
Field speed:Float
End Type
Global Ship:TShip = New TShip
Ship.x = 100
Ship.y = 100
Ship.fAngle = 0
Ship.tAngle = 0
Ship.turnrate = 0
Ship.speed = 1
Repeat
Cls
turnship()
moveship()
SetRotation Ship.fAngle-180
DrawImage ImageShip,Ship.x,Ship.y
SetRotation 0
Flip
Until KeyHit(KEY_ESCAPE)
Function turnship()
Ship.vx:+ Cos(Ship.fAngle)*Ship.speed
Ship.vy:+ Sin(Ship.fAngle)*Ship.speed
Ship.x:+ Ship.vx
Ship.y:+ Ship.vy
'Set Rotation
Ship.tAngle = (ATan2(Ship.y-MouseY(),Ship.x-MouseX())+180.0) Mod 360.0
Local difference:Float = Abs(Ship.tAngle-Ship.fAngle)
If Ship.tAngle < Ship.fAngle
If difference > 180.0 Ship.turnrate=2 Else Ship.turnrate=-2
ElseIf Ship.tAngle > Ship.fAngle
If difference > 180.0 Ship.turnrate=-2 Else Ship.turnrate=2
EndIf
Ship.fAngle = (Ship.fAngle - Ship.turnrate +360) Mod 360
End Function
Function moveship()
Ship.vx = - Cos(Ship.fAngle) * Ship.speed
Ship.vy = - Sin(Ship.fAngle) * Ship.speed
Ship.x:+ Ship.vx
Ship.y:+ Ship.vy
DrawText Ship.fAngle , 1 , 1
DrawText Ship.tAngle , 1 , 30
End Function
|
| ||
You are calculating the ship movement twice, once in TurnShip which gets overridden by the one in MoveShip. I suppose there is an optimisation to cut out all the if statements if you were bothered by them :-Function turnship() 'Set Rotation Ship.tAngle = (ATan2(Ship.y-MouseY(),Ship.x-MouseX())+180.0) Mod 360.0 Local difference:Float = Abs(Ship.tAngle-Ship.fAngle) Local sign:Int = ((Ship.tAngle<Ship.fAngle)*-1) Or Ship.tAngle>Ship.fAngle sign :* ((difference > 180)*-1) Or 1 Ship.turnrate = 2 * sign Ship.fAngle = (Ship.fAngle - Ship.turnrate +360) Mod 360 End Function other than that, looks ok enough to me :-) Last edited 2011 |
| ||
| Do yourself a favor and simply accept that angles should be in the range -180 to +180, as indicated by ATan2. Don't try to hammer them into some other form. I wrote a little function to wrap angles to the the same range as ATan2. It is used to keep fAngle and difference working consistently.
Strict
Global GFX_Width :Int = 700
Global GFX_Height :Int = 700
Graphics GFX_Width , GFX_Height , 0
AutoMidHandle (True)
Global ImageShip:TImage = LoadImage("temp.jpg")
Type TShip
Field x:Float
Field y:Float
Field vx: Float
Field vy: Float
Field fAngle: Float
Field tAngle:Float
Field turnrate:Float
Field speed:Float
End Type
Global Ship:TShip = New TShip
Ship.x = 100
Ship.y = 100
Ship.speed = 1
Repeat
Cls
turnship()
moveship()
SetRotation Ship.fAngle
DrawImage ImageShip,Ship.x,Ship.y
SetRotation 0
Flip
Until KeyHit(KEY_ESCAPE)
Function turnship()
Ship.tAngle = ATan2( MouseY() - Ship.y, MouseX() - Ship.x )
Local difference:Float = WrapAngle( Ship.tAngle - Ship.fAngle )
Ship.turnrate = 2 * Sgn( difference )
Ship.fAngle = WrapAngle( Ship.fAngle + Ship.turnrate )
End Function
Function moveship()
Ship.vx = Cos(Ship.fAngle) * Ship.speed
Ship.vy = Sin(Ship.fAngle) * Ship.speed
Ship.x:+ Ship.vx
Ship.y:+ Ship.vy
End Function
Function WrapAngle:Float( a:Float ) ' to range ( -180, +180 ] just like ATan2
a:Mod 360
If a > +180 Then Return a - 360
If a <= -180 Then Return a + 360
Return a
End Function |
| ||
| This community is simply the best I have seen for development, Iv been on a few others, c++ and PHP but this community beats the all hands down. Thanks. that helped a lot. Last edited 2011 |
