Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8700306
  • 博文数量: 1413
  • 博客积分: 11128
  • 博客等级: 上将
  • 技术积分: 14685
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-13 10:03
个人简介

follow my heart...

文章分类

全部博文(1413)

文章存档

2013年(1)

2012年(5)

2011年(45)

2010年(176)

2009年(148)

2008年(190)

2007年(293)

2006年(555)

分类:

2006-11-26 19:52:18

' ________________________________________________________________________
' 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

 

阅读(2372) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~