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 |