' ________________________________________________________________________ ' TrueVision3D (web: http://www.truevision3d.com) ' ???????????????????????????????????? ' Tutorial 11 : A moving and dynamic camera ' ?????? ' Description : In this 11th tutorial, we take everything from the ' ?????? 9th tutorial and we make the camera follow the tank by ' using the dynamic camera object.
' Force explicit declarations Option Explicit
' We declare TrueVision3D. Private TV3D As TVEngine
' We declare the tank as an mesh8 object Private Tank As TVMesh
' We declare the camera Private Camera As TVCamera
' We declare the landscape Private Land As TVLandscape
' We declare the texture factory Private TextureFactory As TVTextureFactory
' We the declare the scene Private Scene As TVScene
' We declare the input engine. Private InputEngine As TVInputEngine
' The loop. Private DoLoop As Boolean
' We need a position for the tank Private TankPosition As D3DVECTOR
' We need angles for the tank. Private sngAngleX As Single Private sngAngleY As Single
' We could have done this in many ways, but we added some smoothing to ' the movement se we need to declare two additional variables. Private sngWalk As Single Private sngStrafe As Single
' We declare here the brake factor needed to make the tank break. Private sngBrake As Single
Private Sub cmdQuit_Click()
' We have clicked on the "Quit" button, so we change the DoLoop. DoLoop = False
End Sub
Private Sub Form_Load()
' We have to create the TV3D object before anything else. Set TV3D = New TVEngine
' Set search directory for textures, objects, ... TV3D.SetSearchDirectory App.Path
' We initialize TV3D in the picture box of the form. TV3D.Init3DWindowedMode Picture1.hWnd
' We want to see the FPS. TV3D.DisplayFPS = True ' Set the AngleSystem to degree TV3D.SetAngleSystem TV_ANGLE_DEGREE
' We create the input object. Set InputEngine = New TVInputEngine
' We create the scene (the world). Set Scene = New TVScene
' We create the camera object Set Camera = New TVCamera
' New : We are not going to use the sky boxes to save some weight ' on the tutorial zipfiles. Instead, we will use a background color. Scene.SetSceneBackGround 0, 0.3, 0.9
' We need to create a new texture factory Set TextureFactory = New TVTextureFactory
' The land generation Set Land = New TVLandscape ' Generate the height of the land from the grayscale of the image. Land.GenerateHugeTerrain "..\..\..\Media\Heightmaps\Track.jpg", TV_PRECISION_LOW, 8, 8, -700, -1024, True ' Then, we load the land texture. TextureFactory.LoadTexture "..\..\..\Media\sand.jpg", "LandTexture" ' We assign a texture to that land. Land.SetTexture GetTex("LandTexture") ' New : we ceate a mesh by loading an external model (no, not a ' teapot). We are going to load the tank model. Let's start by ' creating the object that will hold our model. Set Tank = New TVMesh ' Now, load our model. Set Tank = Scene.CreateMeshBuilder Tank.Load3DSMesh "..\..\..\Media\tank.3ds", False ' Load the texture and assign it. TextureFactory.LoadTexture "..\..\..\Media\tank.bmp", "TankTexture", , , TV_COLORKEY_NO Tank.SetTexture GetTex("TankTexture") ' Let set the initial position of the tank TankPosition.x = 50 TankPosition.z = 50 TankPosition.y = Land.GetHeight(TankPosition.x, TankPosition.z) ' We set the camera vectors to be on the tank. To have a cool zoom in ' effect when we start the game, we set the camera really far away ' from the tank. '设置镜头位置,为了进行一个特殊效果 Camera.SetPosition TankPosition.x, TankPosition.y + 500, TankPosition.z ' We set the initial values of movement sngWalk = 0 sngStrafe = 0 ' We pop the form over everything else. Form1.Show ' We start the main loop. DoLoop = True Main_Loop
End Sub
Private Sub Form_Unload(Cancel As Integer)
' The user asked to quit but clicked on the 'X' button at up right. DoLoop = False ' And ask to quit. Main_Quit
End Sub
Private Sub Main_Loop()
' The main loop Do ' Let us the capacity to use buttons of the form. DoEvents ' We check the input Check_Input ' We check and update the movement Check_Movement
' Clear the the last frame. TV3D.Clear ' Render the mesh Scene.RenderAllMeshes ' New : we have to render the landscape. Land.Render True ' We display everything that we have rendered TV3D.RenderToScreen 'We loop all of this until the DoLoop isn't True. Loop Until DoLoop = False ' We ask to quit. Main_Quit
End Sub
Private Sub Check_Input() ' Check if we pressed the UP arrow key, if so, then we are ' walking forward. If InputEngine.IsKeyPressed(TV_KEY_UP) = True Then sngWalk = 1 End If ' Check if we pressed the DOWN arrow key, if so, then we are ' pressing the breaks. If InputEngine.IsKeyPressed(TV_KEY_DOWN) = True Then sngBrake = 0.002 Else ' We are not pressing the brakes, let the tank float. sngBrake = 0.0005 End If
' Check if we pressed the LEFT arrow key, if so, then strafe ' on the left. If InputEngine.IsKeyPressed(TV_KEY_LEFT) = True Then sngStrafe = 1 ' If we are not strafing left, maybe we want to strafe to the ' right, using the RIGHT arrow? If so, set strafe to negative. ElseIf InputEngine.IsKeyPressed(TV_KEY_RIGHT) = True Then sngStrafe = -1 End If
' Now, for the mouse input... Dim tmpMouseX As Long, tmpMouseY As Long
' Get the movement of the mouse. InputEngine.GetMouseState tmpMouseX, tmpMouseY
' Update the tank angle. sngAngleY = sngAngleY - (tmpMouseX / 100)
End Sub
Private Sub Check_Movement()
' Okay, now for the smothing of the movement... Update ' the forward and backward (walk) movement. Select Case sngWalk Case Is > 0 sngWalk = sngWalk - sngBrake * TV3D.TimeElapsed If sngWalk < 0 Then sngWalk = 0 End Select ' Now, we update the left and right (strafe) movement. Select Case sngStrafe Case Is > 0 sngStrafe = sngStrafe - 0.001 * TV3D.TimeElapsed If sngStrafe < 0 Then sngStrafe = 0 Case Is < 0 sngStrafe = sngStrafe + 0.001 * TV3D.TimeElapsed If sngStrafe > 0 Then sngStrafe = 0 End Select ' Update the vectors using the angles and positions. But this ' time, we don't update the camera position but the tank ' vector position. TankPosition.x = TankPosition.x + (Cos(sngAngleY) * sngWalk / 5 * TV3D.TimeElapsed) + (Cos(sngAngleY + 3.141596 / 2) * sngStrafe / 5 * TV3D.TimeElapsed) TankPosition.z = TankPosition.z + (Sin(sngAngleY) * sngWalk / 5 * TV3D.TimeElapsed) + (Sin(sngAngleY + 3.141596 / 2) * sngStrafe / 5 * TV3D.TimeElapsed) TankPosition.y = Land.GetHeight(TankPosition.x, TankPosition.z) + 10 ' From the tank position vector, we update the mesh position. '设置坦克位置 Tank.SetPosition TankPosition.x, TankPosition.y, TankPosition.z ' From the angle variable, we update the tank rotation '设置坦克旋转角度 Tank.SetRotation 0, (sngAngleY * -57.295) + 90, 0 ' With the new values of the tank vector, we update the camera, ' by using a dynamic camera that will follow the mesh. '设置视角,使摄像机跟踪坦克 Camera.ChaseCamera Tank, Vector(0, 25, -50), Vector(0, 0, 0), 75, True, 150, True
End Sub
Private Sub Main_Quit() ' We want to quit the project, so we start by desroyng ' the texture factory. Set TextureFactory = Nothing ' We destroy the camera object Set Camera = Nothing ' We destroy the tank object Set Tank = Nothing ' We destroy the land object. Set Land = Nothing ' Don't forget to destroy the inputengine object... Set InputEngine = Nothing ' Then, we destroy the scene object. Set Scene = Nothing ' We finish the frenetic destroy with the TV3D object. Set TV3D = Nothing ' We end the application. End
End Sub
|