' ________________________________________________________________________ ' TRUEVISION8 (web: http://www.truevision3d.com) ' ???????????????????????????????????? ' Tutorial 12 : Get a landscape position ' ?????? ' Description : In this 12th tutorial, we go back to a basic landscape ' ?????? loading and we add a collision check to get the impact ' point with the mouse. '
' Force explicit declarations Option Explicit
' We declare TVEngine. Private TV8 As TVEngine
' New : to get the mouse pointer position, we have to check if ' there was a collision with the mouse position and the landscape. ' For this, we use the TV8 collision detection object. Private CollisionResult As TVCollisionResult
' We declare the landscape Private Land As TVLandscape
' 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 are going to use camera (point of view) angles, as well as the ' camera position and look at vectors. Private sngPositionX As Single Private sngPositionY As Single Private sngPositionZ As Single Private snglookatX As Single Private snglookatY As Single Private snglookatZ 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
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 TV8 object before anything else. Set TV8 = New TVEngine
' Set the search directory of Textures, Objects, ... TV8.SetSearchDirectory App.Path ' We initialize TV8 in the picture box of the form. TV8.Init3DWindowedMode Picture1.hWnd
' We want to see the FPS. TV8.DisplayFPS = True
' We create the input object. Set InputEngine = New TVInputEngine
' We create the scene (the world). Set Scene = New TVScene
' New : we load a mouse pointer texture. The cursor you ' are seeing normally is the Windows cursor and it's ' position is NOT the game's mouse pointer position. '为场景加载光标 Scene.LoadCursor "..\..\..\Media\pointer.bmp", TV_COLORKEY_BLACK, 32, 16
' Set background color Scene.SetSceneBackGround 0.7, 0.7, 0.3
' Create the texture factory Set TextureFactory = New TVTextureFactory
' Land generation Set Land = New TVLandscape ' Generate the height of the land from the grayscale of the image. Land.GenerateHugeTerrain "..\..\..\Media\heightmap.jpg", TV_PRECISION_LOW, 8, 8, 0, 0, True ' Then, we load the land texture. TextureFactory.LoadTexture "..\..\..\Media\sand.jpg", "LandTexture" ' We assign a texture to that land. Land.SetTexture GetTex("LandTexture") ' We set the camera vectors (the position will be automatically ' updated in the checks) snglookatX = 150 snglookatZ = 550 ' 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 ' Check the input Check_Input ' check and update the movement Check_Movement
' Clear the the last frame. TV8.Clear ' We render the landscape. Land.Render True ' We display everything that we have rendered TV8.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 ' If we are not walking forward, maybe we are walking backward ' by using the DOWN arrow? If so, set walk speed to negative. ElseIf InputEngine.IsKeyPressed(TV_KEY_DOWN) = True Then sngWalk = -1 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
' New : we check the mouse by using an other method. We ' are going to get the absolute mouse status. '获得鼠标绝对坐标值 Dim tmpMouseX As Long, tmpMouseY As Long InputEngine.GetAbsMouseState tmpMouseX, tmpMouseY ' New : we set the collision object which will be ' used for the mouse pick on the scene's landscape '设置撞击对象,使用鼠标拾取地面坐标值 Set CollisionResult = Scene.MousePicking(tmpMouseX, tmpMouseY, TV_COLLIDE_LANDSCAPE, TV_TESTTYPE_ACCURATETESTING)
' Check if we did have a collision with the landscape. ' If so, pass the collision point to the list box ' on the form. '判断如果鼠标碰到地面的话,则显示其坐标值 If CollisionResult.IsCollision Then txtCollision(0) = "X:" & CollisionResult.GetImpactPoint.x txtCollision(1) = "Y:" & Land.GetHeight(CollisionResult.GetImpactPoint.x, CollisionResult.GetImpactPoint.z) txtCollision(2) = "Z:" & CollisionResult.GetImpactPoint.z End If 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 - 0.005 * TV8.TimeElapsed If sngWalk < 0 Then sngWalk = 0 Case Is < 0 sngWalk = sngWalk + 0.005 * TV8.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.005 * TV8.TimeElapsed If sngStrafe < 0 Then sngStrafe = 0 Case Is < 0 sngStrafe = sngStrafe + 0.005 * TV8.TimeElapsed If sngStrafe > 0 Then sngStrafe = 0 End Select ' Update the vectors using the angles and positions. snglookatX = snglookatX + sngWalk * 5 snglookatZ = snglookatZ + sngStrafe * 5 snglookatY = Land.GetHeight(snglookatX, snglookatZ) ' We update the look at position. sngPositionX = snglookatX - 150 sngPositionZ = snglookatZ sngPositionY = Land.GetHeight(sngPositionX, sngPositionZ) + 50
' With the new values of the camera vectors (position and ' look at), we update the scene's camera. Scene.SetCamera sngPositionX, sngPositionY, sngPositionZ, snglookatX, snglookatY, snglookatZ
End Sub
Private Sub Main_Quit() ' We want to quit the project, so we start by destroyng ' the texture factory. Set TextureFactory = Nothing ' We destroy the collision object Set CollisionResult = 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 TV8 object. Set TV8 = Nothing ' We end the application. End
End Sub
|