space ship movement simulate roll
BlitzMax Forums/BlitzMax Programming/space ship movement simulate roll
| ||
Hi ! i'm searching a method to simulate a ship roll with an imagestrip image (see my picture). Some ideas or formulae to do this ? note : i've already the code to move the ship along the spline and orient the image to the direction. But i don't know how to determine and simulate the roll. Thanks for your help ! |
| ||
I would measure the difference in degrees that it changed direction since the last frame and tie that in with the animation frame. So you just have to think about how many degrees represents which frame, so if it turned 1-10 degrees it should show frame 1, 11-20 frame 2 etc. something like frame=int(change_in_degrees/40*number_of_turning_frames) if frame> number_of_turning_frames frame=number_of_turning_frames 40 is just a number plucked out of the air but it should be the maximum number of degrees that represents the last frame of the turning animation. Something along those lines anyway. |
| ||
There's (almost) nothing in deep space. With no atmosphere there's no need for a ship to roll. Of course, there's no sound either, but my project still has lasers that scream like demons from hell. :-D Pete's suggestion sounds solid. Just calculate the difference between the object's heading at the current and last update. This code should make it easy. Function FAngleDifference:Double(ActorA:TActor, ActorB:TActor) Local AngleLessAngle:Double = ActorB.Angle - ActorA.Angle If AngleLessAngle > 180 Return(AngleLessAngle - 360) End If If AngleLessAngle < - 180 Return(AngleLessAngle + 360) End If Return(AngleLessAngle) End Function I hope that helps. Good luck with your game. |
| ||
Thanks for your help. Could you help me again. I've written this piece of code (spline code is not mine) ... not work at this time because i don't know how to use the computed roll value. So i need some help to write the Display_ship function ! Note that it should work with any spline !Graphics 1024,768,0 Global himage = LoadAnimImage ("imagestrip_ennemi1.png",106,80,0,13) If himage = Null Notify "load image bug !" MidHandleImage hImage '-------------- ' functions '------------- Function bezier(ax#,ay#,bx#,by#,cx#,cy#,dx#,dy#) SetColor 255,0,0 DrawLine ax,ay,bx,by DrawLine cx,cy,dx,dy ox#=ax oy#=ay SetColor 100,100,100 For t#=0 To 1 Step .01 a#=t b#=1-t x#=ax*b*b*b + 3*bx*b*b*a + 3*cx*b*a*a + dx*a*a*a y#=ay*b*b*b + 3*by*b*b*a + 3*cy*b*a*a + dy*a*a*a DrawRect x-1,y-1,3,3 DrawLine ox,oy,x,y ox=x oy=y Next End Function Function Display_ship (x#,y#,roll#) If Roll <= -0.6 Then f = 0 If Roll <= -0.5 And Roll > -0.6 Then f = 1 If Roll <= -0.4 And Roll > -0.5 Then f = 2 If Roll <= -0.3 And Roll > -0.4 Then f = 3 If Roll <= -0.2 And Roll > -0.3 Then f = 4 If Roll <= -0.1 And Roll > -0.2 Then f = 5 If Roll = 0.0 Then f = 6 If Roll >= 0.1 And Roll < 0.2 Then f = 7 If Roll >= 0.2 And Roll < 0.3 Then f = 8 If Roll >= 0.3 And Roll < 0.4 Then f = 9 If Roll >= 0.4 And Roll < 0.5 Then f = 10 If Roll >= 0.5 And Roll < 0.6 Then f = 11 If Roll >= 0.6 Then f = 12 DrawImage hImage, x#,y#, f End Function '-------------- ' main program '------------- ' spline points and control points here : ' ************************************************************** Local ax=200, ay=50, bx=600, by=40, cx=300, cy=700, dx=800, dy=588 ' ************************************************************** t1#=0 t2#=0 speed#=0 x1#=ax y1#=ay x2#=ax y2#=ay SetClsColor 255,255,255 While Not KeyHit(KEY_ESCAPE) ' display the spline bezier(ax,ay,bx,by,cx,cy,dx,dy) 'compute classic spline movement. ox1#=x1 oy1#=y1 ox2#=x2 oy2#=y2 t1:+speed If t1>1 Then t1=0 a#=t1 b#=1-t1 old_x1# = x1# old_y1# = y1# old_rot1# = rot1# x1#=ax*b^3 + 3*bx*b^2*a + 3*cx*b*a^2 + dx * a^3 y1#=ay*b^3 + 3*by*b^2*a + 3*cy*b*a^2 + dy * a^3 rot1 = 360 - ATan2 (x1# - old_x1#, y1# - old_y1#) 'determine roll1 '**************************** roll1# = old_rot1# - rot1 '**************************** 'compute equidistant point spline movement. SetRotation rot1 Display_ship (x1-3,y1-3, roll1#) SetRotation 0 SetColor 255,0,0 DrawRect x1-3,y1-3,7,7 DrawText "roll1=" + roll1#,x1,y1 SetColor 255,255,255 vx#=-3*ax*b*b + 3*bx*b*(b-2*a) + 3*cx*a*(2*b-a) + dx*3*a*a vy#=-3*ay*b*b + 3*by*b*(b-2*a) + 3*cy*a*(2*b-a) + dy*3*a*a d#=Sqr(vx*vx+vy*vy) speed#=10/d t2:+.001 If t2>1 Then t2=0 a#=t2 b#=1-t2 old_x2# = x2# old_y2# = y2# old_rot2# = rot2# x2#=ax*b*b*b + 3*bx*b*b*a + 3*cx*b*a*a + dx*a*a*a y2#=ay*b*b*b + 3*by*b*b*a + 3*cy*b*a*a + dy*a*a*a rot2 = 360 - ATan2 (x2# - old_x2#, y2# - old_y2#) ' determine roll2 '**************************** roll2# = old_rot2# - rot2 '**************************** SetRotation rot2 Display_ship (x2-3,y2-3, roll2#) SetRotation 0 SetColor 0,0,255 DrawRect x2-3,y2-3,7,7 DrawText "roll2=" + roll2#, x2,y2 SetColor 255,255,255 Delay 30 Flip Cls Wend Download the ship graphics file here : Download the ship graphics file here : |
| ||
maybe something like this:Function Display_ship (x:Float, y:Float, roll:Float, rollfactor:Float = 4) Local f:Int = 6 If roll < - 0.1 f = Abs(roll) / rollfactor * 6 + 7 If f > 12 f = 12 ElseIf roll > 0.1 f = Abs(6 - (roll / rollfactor * 6)) If f > 5 f = 5 End If DrawImage hImage, x, y, f End Function Rollfactor determines the number of degrees that represents the last frame of roll animation. |
| ||
this works fine now, many thanks Pete for the function. Here a final code. You can drag the spline points to test... Download the ship graphics file here. Graphics 1024,768,0 Global himage = LoadAnimImage ("imagestrip_ennemi1.png",106,80,0,13) If himage = Null Notify "load image bug !" MidHandleImage hImage '-------------- ' functions '------------- Function bezier(ax#,ay#,bx#,by#,cx#,cy#,dx#,dy#) SetColor 255,0,0 DrawLine ax,ay,bx,by DrawLine cx,cy,dx,dy ox#=ax oy#=ay SetColor 100,100,100 For t#=0 To 1 Step .01 a#=t b#=1-t x#=ax*b*b*b + 3*bx*b*b*a + 3*cx*b*a*a + dx*a*a*a y#=ay*b*b*b + 3*by*b*b*a + 3*cy*b*a*a + dy*a*a*a DrawRect x-1,y-1,3,3 DrawLine ox,oy,x,y ox=x oy=y Next End Function Function Display_ship (x:Float, y:Float, roll:Float, rollfactor:Float = 4) ' Rollfactor determines the number of degrees that represents the last frame of roll animation. Local f:Int = 6 If roll < - 0.1 f = Abs(roll) / rollfactor * 6 + 7 If f > 12 f = 12 ElseIf roll > 0.1 f = Abs(6 - (roll / rollfactor * 6)) If f > 5 f = 5 End If DrawImage hImage, x, y, f End Function Function Drag_points () mx = MouseX() my = MouseY() If MouseDown (1) Or MouseDown(2) Then If mx - 30 < ax And mx + 30 > ax Then If my - 30 < ay And my + 30 > ay Then ax = mx ay = my End If End If If mx - 30 < bx And mx + 30 > bx Then If my - 30 < by And my + 30 > by Then bx = mx by = my End If End If If mx - 30 < cx And mx + 30 > cx Then If my - 30 < cy And my + 30 > cy Then cx = mx cy = my End If End If If mx - 30 < dx And mx + 30 > dx Then If my - 30 < dy And my + 30 > dy Then dx = mx dy = my End If End If End If SetColor 255,0,0 DrawOval mx-3,my-3,6,6 DrawText (mx + "," + my), mx,my + 16 SetColor 255,255,255 End Function '-------------- ' main program '------------- ' spline points and control points here : ' ************************************************************** Global ax=200, ay=50, bx=600, by=40, cx=300, cy=700, dx=800, dy=588 ' ************************************************************** t1#=0 t2#=0 speed#=0 x1#=ax y1#=ay x2#=ax y2#=ay HideMouse SetClsColor 255,255,255 While Not KeyHit(KEY_ESCAPE) ' dragpoints Drag_points () ' display the spline bezier(ax,ay,bx,by,cx,cy,dx,dy) 'compute classic spline movement. ox1#=x1 oy1#=y1 ox2#=x2 oy2#=y2 t1:+speed If t1>1 Then t1=0 f1 = 6 f2 = 6 End If a#=t1 b#=1-t1 old_x1# = x1# old_y1# = y1# old_rot1# = rot1# x1#=ax*b^3 + 3*bx*b^2*a + 3*cx*b*a^2 + dx * a^3 y1#=ay*b^3 + 3*by*b^2*a + 3*cy*b*a^2 + dy * a^3 rot1 = 360 - ATan2 (x1# - old_x1#, y1# - old_y1#) 'determine roll1 '**************************** roll1# = old_rot1# - rot1 '**************************** 'compute equidistant point spline movement. SetRotation rot1 Display_ship (x1-3,y1-3, roll1#) SetRotation 0 SetColor 255,0,0 DrawRect x1-3,y1-3,7,7 DrawText "roll1 = " + roll1# ,x1,y1 SetColor 255,255,255 vx#=-3*ax*b*b + 3*bx*b*(b-2*a) + 3*cx*a*(2*b-a) + dx*3*a*a vy#=-3*ay*b*b + 3*by*b*(b-2*a) + 3*cy*a*(2*b-a) + dy*3*a*a d#=Sqr(vx*vx+vy*vy) speed#=10/d t2:+.001 If t2>1 Then t2=0 a#=t2 b#=1-t2 old_x2# = x2# old_y2# = y2# old_rot2# = rot2# x2#=ax*b*b*b + 3*bx*b*b*a + 3*cx*b*a*a + dx*a*a*a y2#=ay*b*b*b + 3*by*b*b*a + 3*cy*b*a*a + dy*a*a*a rot2 = 360 - ATan2 (x2# - old_x2#, y2# - old_y2#) ' determine roll2 '**************************** roll2# = old_rot2# - rot2 '**************************** SetRotation rot2 Display_ship (x2-3,y2-3, roll2#) SetRotation 0 SetColor 0,0,255 DrawRect x2-3,y2-3,7,7 DrawText "roll2=" + roll2#, x2,y2 SetColor 255,255,255 Flip Cls Wend ShowMouse |
| ||
finaly after read again my code i've some problem to understand this : "Rollfactor determines the number of degrees that represents the last frame of roll animation." Could you explain me ? Thanks (now i've 16 frames imagestrip) (frame 0 : -30 degrees, frame 8 : 0 degree, frame 15 : 30 degrees) |
| ||
i just need some help to determine the rollfactor value with this imagestrip. Thanks. |
| ||
The value of roll that you pass to the function is the number of degrees that the ship is turning. The more degrees that the ship turns the more the ship tilts. So the rollfactor is the maximum number of degrees that represents the last frame number with the steepest roll. It looks like the main problem is that the animation you're using has more frames then the original, the function I wrote was hard coded for 12 frames of animation. Maybe this is more flexible:Function Display_ship (x:Float, y:Float, roll:Float, frames:int ,rollfactor:Float = 4) ' Rollfactor determines the number of degrees that represents the last frame of roll animation. Local middleframe:int=frames/2 Local f:Int = middleframe If roll < - 0.1 f = Abs(roll) / rollfactor * middleframe + middleframe+1 If f > frames-1 f = frames-1 ElseIf roll > 0.1 f = Abs(middleframe - (roll / rollfactor * middleframe)) If f > middleframe-1 f = middleframe-1 End If DrawImage hImage, x, y, f End Function Also the image strip you have there is 16 frames which means there is no middle frame. I think the previous strip you had was 13 frames, so frame 7 was the middle frame and you had 6 frames either side. The above code might need tweaking as I haven't tested it at all, but might not work properly unless you have an odd number of frames, like 17 for instance. |