' ________________________________________________________________________ ' TrueVision3D (web: http://www.truevision3d.com) ' ???????????????????????????????????? ' Tutorial 6 : Move in the room. ' ????? ' Description : In this 6th tutorial, we take the previous tutorial, ' ?????? we add a sky box to the scene and add the code to ' allow us to move in this room.
' Force explicit declarations Option Explicit
' We declare TVEngine. Private TV3D As TVEngine
' We have to delare the room that we will use for this tutorial. Private Room As TVMesh
' We declare the scene Private Scene As TVScene
' We declare the texture factory in order to load textures. Private TextureFactory As TVTextureFactory
' We declare the input engine. Private InputEngine As TVInputEngine
' We declare the Atmosphere class for the sky '设定天空大气 Private Atmos As TVAtmosphere
' 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 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 '射击
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 the objects, textures, ... 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
' We create the input object. Set InputEngine = New TVInputEngine
' We create the scene (the world). Set Scene = New TVScene ' And the texture factory Set TextureFactory = New TVTextureFactory
' We create the atmosphere (for sky) '为天空设置大气 Set Atmos = New TVAtmosphere ' We load the sky textures. ' One for each face of the cube. '加载材质 TextureFactory.LoadTexture "..\..\..\Media\top.bmp", "SkyTop" TextureFactory.LoadTexture "..\..\..\Media\bottom.bmp", "SkyBottom" TextureFactory.LoadTexture "..\..\..\Media\left.bmp", "SkyLeft" TextureFactory.LoadTexture "..\..\..\Media\right.bmp", "SkyRight" TextureFactory.LoadTexture "..\..\..\Media\front.bmp", "SkyFront" TextureFactory.LoadTexture "..\..\..\Media\back.bmp", "SkyBack" ' New : here is an other truth about 3D games : the sky ain't ' a real It's just an immense box that surrounds the map ' and stand still, so when we turn around, it looks like ' if there was a sky, but no,it's only a box. Also, know that ' the TV3D sky boxe is inversed so you have to inverse the order ' you set your textures. '设置天空材质 Atmos.SkyBox_SetTexture GetTex("SkyFront"), GetTex("SkyBack"), GetTex("SkyLeft"), GetTex("SkyRight"), GetTex("SkyTop"), GetTex("SkyBottom") Atmos.SkyBox_Enable True ' We load the floor texture and wall texture into the texture factory. TextureFactory.LoadTexture "..\..\..\Media\fieldstone.tga", "FloorTexture" TextureFactory.LoadTexture "..\..\..\Media\roof1.bmp", "WallTexture" ' We tell the scene... Note that the mesh object ' is directly created by the CreateMeshBuilder function ' so you don't need to do Set Mesh = New TVMesh '设置墙 Set Room = Scene.CreateMeshBuilder ' We create the room's walls. Room.AddWall GetTex("WallTexture"), 500, -500, -500, -500, 100, 0, 3, 1 Room.AddWall GetTex("WallTexture"), -500, -500, -500, 500, 100, 0, 3, 1 Room.AddWall GetTex("WallTexture"), -500, 500, 500, 500, 100, 0, 3, 1 Room.AddWall GetTex("WallTexture"), 500, 500, 500, -500, 100, 0, 3, 1 ' Like the "add wall" method, we will add a floor to this room. Room.AddFloor GetTex("FloorTexture"), -500, -500, 500, 500, 0, 10, 10 ' We set the camera vectors (position and look at) and angles. '设置视图矢量值 sngPositionX = 0 sngPositionY = 20 sngPositionZ = 0 snglookatX = 0 snglookatY = 20 snglookatZ = 50 sngAngleX = 0 sngAngleY = 0 ' We set the initial values of movement sngWalk = 0 sngStrafe = 0 ' We pop the form over everything else. Form1.Show ' Set The View distance '设置场景可视距离 Scene.SetViewFrustum 60, 10000 ' 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 ' Just like in tutorial 4, where we moved the teapot by using ' the keyboard and mouse input, we will move the camera vectors ' (position and look at) with the keyboard and mouse. But this ' time, we will get hard core with the math. But, don't be too ' scared, once you created the right movement code, you don't ' need to recreate it : you use CUT and PASTE. ' 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
' Now, for the mouse input... Dim tmpMouseX As Long, tmpMouseY As Long Dim tmpMouseB1 As Integer, tmpMouseB2 As Integer, tmpMouseB3 As Integer Dim tmpMouseScrollOld As Long, tmpMouseScrollNew As Long
' We pass the actual value of the mouse scroller to the variable ' that holds the old mouse scroller value. tmpMouseScrollOld = tmpMouseScrollNew
' By using GetMouseState, we get the movement of the mouse ' with the speed of the movement. The fastest the mouse movement ' will be, the higher will be the return. '获取鼠标状态 InputEngine.GetMouseState tmpMouseX, tmpMouseY, tmpMouseB1, tmpMouseB2, tmpMouseB3, tmpMouseScrollNew
' From the mouse return values, we update the camera angles ' by adding or substracting the mouse return value. '通过加减鼠标返回值,来更新视图角度 sngAngleX = sngAngleX - (tmpMouseY / 100) sngAngleY = sngAngleY - (tmpMouseX / 100)
' We will add a simple check, so we can't look up at more ' than 80 degrees nor down than -80 degrees. If sngAngleX > 1.3 Then sngAngleX = 1.3 If sngAngleX < -1.3 Then sngAngleX = -1.3
' Okay, now for the smothing of the movement... We checked ' above if we were pressing a key. If so, then we updated the ' movement variable to 1 (positive or negative). Here, we ' lower this value until it get to 0. This method give us a ' smoother camera movement. We start by updating the forward ' and backward (walk) movement. '前后 Select Case sngWalk Case Is > 0 sngWalk = sngWalk - 0.05 If sngWalk < 0 Then sngWalk = 0 Case Is < 0 sngWalk = sngWalk + 0.05 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.05 If sngStrafe < 0 Then sngStrafe = 0 Case Is < 0 sngStrafe = sngStrafe + 0.05 If sngStrafe > 0 Then sngStrafe = 0 End Select ' Update the vectors using the angles and positions. ' If you don't understand the trigonometry behind this ' you can look up quickly the trigonometry in triangles ' cosinus, sinus and tangent. sngPositionX = sngPositionX + (Cos(sngAngleY) * sngWalk * TV3D.TimeElapsed) + (Cos(sngAngleY + 3.141596 / 2) * sngStrafe * TV3D.TimeElapsed) sngPositionZ = sngPositionZ + (Sin(sngAngleY) * sngWalk * TV3D.TimeElapsed) + (Sin(sngAngleY + 3.141596 / 2) * sngStrafe * TV3D.TimeElapsed) snglookatX = sngPositionX + Cos(sngAngleY) snglookatY = sngPositionY + Tan(sngAngleX) snglookatZ = sngPositionZ + Sin(sngAngleY) ' or use the easier functions of the TVCamera class. ' Camera.MoveRelative ' Camera.SetRotation ' Camera.RotateX|Y|Z
' 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
' Clear the the last frame. TV3D.Clear ' New : we have to render the sky. We do this before everything ' else. As mentionned before, objects in the 3D digitalized world ' needs to be rendered. Because they are not rendered all ' together, at the same instant, we have to decide what we render ' before then what we render after. If we render the sky after ' rendering our room, we wont see the room. ' The sky rendering is done in the global atmosphere rendering '渲染大气 Atmos.Atmosphere_Render ' We render all the 3D objects contained in the scene. Scene.RenderAllMeshes ' 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 Main_Quit() ' We want to quit the project, so we destroy the room object. Set Room = 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
|