' ________________________________________________________________________ ' TrueVision3D (web: http://www.truevision3d.com) ' ???????????????????????????????????? ' Tutorial 9 : Controling a tank. ' ????? ' Description : In this 9th tutorial, we go back to the 7th tutorial ' ?????? (a land without all the eye candy) and we load a simple ' mesh that we will control via the keyboard.
' Force explicit declarations Option Explicit
' We declare TrueVision3D. Private TV3D As TVEngine
' No so new : we declare the tank as an mesh8 object Private Tank As TVMesh
' 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
' New : we need a position for the tank. Just like the camera, ' the position of a mesh is set with a vector. ut instead of declaring ' 3 different variables, we will use a simple directX variable that ' holds a vector. Private TankPosition As D3DVECTOR
' We are going to use camera (point of view) angles, as well as the ' camera position Private sngPositionX As Single Private sngPositionY As Single Private sngPositionZ As Single 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 the search directory of texture, 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
' 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.3, 0.6, 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 '加载3ds模型 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 (position and look at) and angles. sngPositionX = 0 sngPositionY = 20 sngPositionZ = 0 sngAngleX = 0 sngAngleY = 0 ' 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 ' position and look at. Scene.SetCamera 100, 200, 100, TankPosition.x, TankPosition.y, TankPosition.z
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 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
|