I had the same problem in my current project. My ship has completely free 360 degree movement and I wanted the camera to smoothly follow behind the ship and look kind of dynamic rather than a camera fixed at a set point. But, every time the ship rolled or climbed past vertical the camera jumped and caused some wacky effects. I've now got it workin' sweeeeeet. Check out the following code. Just change the code to point to your own mesh and a texture for the plane and it should work as is.
Graphics3D 1024,768,16,1
SetBuffer BackBuffer()
Const climbspeed# = 1, rollspeed# = 2
Global xrotation#,zrotation#,speed#
Global camera% = CreateCamera()
Global plane% = CreatePlane()
Global planetex% = LoadTexture("planettextures/ground4.bmp");Replace with your own texture
ScaleTexture planetex,10,10
EntityTexture plane,planetex
Global ship = LoadMesh("fighter5.3ds");replace with your own mesh
PositionEntity ship,0,100,0
While Not KeyDown(1)
speed# = 1
FlightControls()
MoveShip(xrotation,zrotation)
MoveCamera()
RenderWorld
Flip
Wend
End
Function MoveShip(xrotate#,zrotate#)
roll#=rollspeed*Sin(zrotate#)
pitch#=climbspeed*Sin(xrotate)
TurnEntity ship,pitch#,0,roll#
MoveEntity ship,0,0,speed#
End Function
Function MoveCamera()
;I believe there may be a better way to write the following code using TFORMPOINT, but
;this works really well.
EntityParent(camera,ship,True)
dx#=EntityX(camera)
dy#=EntityY(camera)
dz#=EntityZ(camera)
r#=EntityRoll(camera)
p#=EntityPitch(camera)
y#=EntityYaw(camera)
;The following 4 lines cause the camera to follow just behind the ship(30 behind, 2 up).
;Pitch roll and yaw are also just behind the ship giving your camera a super smooth action.
If r# => 180 Then r# = r# - 360
If r# =< -180 Then r# = r# + 360
TurnEntity camera,-p#,-y#,-r#*(.06)
TranslateEntity camera,-dx*.1,(-dy*.1)+2,(-dz)-30
EntityParent(camera,0)
End Function
Function FlightControls()
;The xrotation and yrotation values are passed to the MoveShip function which
;use the sine wave to give you smooth movement. It is very important these
;values never exceed 90. But 70 is sufficient.
If KeyDown(200);x rotation(pitch)
If xrotation < 70 Then
xrotation = xrotation + climbspeed#
If xrotation < 0 Then
xrotation = xrotation / 1.1
;If you use Delta timing then the above line should
;read "xrotation = xrotation / 1.1 ^ FL\SpeedFactor"
;note the (^) not (*)
End If
End If
Else
If KeyDown(208)
If xrotation > -70
xrotation = xrotation -climbspeed#
If xrotation > 0 Then
xrotation = xrotation / 1.1
End If
End If
Else
If xrotation <> 0 Then
xrotation = xrotation / 1.1
End If
End If
EndIf
If KeyDown(203);z rotation(roll)
If zrotation < 70 Then
zrotation = zrotation + rollspeed#
If zrotation < 0 Then
zrotation = zrotation / 1.1
End If
End If
Else
If KeyDown(205)
If zrotation > -70
zrotation = zrotation - rollspeed#
If zrotation > 0 Then
zrotation = zrotation / 1.1
End If
End If
Else
If zrotation <> 0 Then
zrotation = zrotation / 1.1
End If
End If
EndIf
End Function
|