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