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 |