VB6编程:DirectX 2D图形学习日志27图形引擎分析

VB6编程:DirectX 2D图形学习日志27图形引擎分析
一、初始化
1.设置全屏分辨率: 源码是800600,我修改成1024768

    Fullscreen_Width = 1024
    Fullscreen_Height = 768

    With frmMain
    
        .Caption = "DirectX教程19:2d游戏图形引擎"
        .ScaleMode = 3
        .Width = (1024 / 2) * Screen.TwipsPerPixelX '表示横坐标中每像素有多少缇
        .Height = (768 / 2) * Screen.TwipsPerPixelY '表示纵坐标中每像素有多少缇
    
    End With

2、 初始化DirectX和Direct3D子程序( DirectX_Initialize )
其中:

Private Scalar As D3DVECTOR2'Type D3DVECTOR2成员X,Y

当全屏时:

   Scalar.X = Fullscreen_Width / frmMain.ScaleWidth
   Scalar.Y = Fullscreen_Height / frmMain.ScaleHeight

当窗口化时:

        Scalar.X = 1
        Scalar.Y = 1

3、设置_地图 子程序(Setup_Map)
地图类型的结构定义如下:

 Private Type Map_Type
    Map() As String
    Tile() As Long
    New_Tile() As Long
    Width As Long '宽度
    Height As Long '高度
    New_Width As Long '新宽度
    New_Height As Long '新宽度
    Number_Of_Vertices_Per_Tile_Set() As Long '数量_顶点数_瓷砖数_套数
    Number_Of_Polygons_Per_Tile_Set() As Long '数量_多边形数_每_瓷砖_设置
    Number_Of_Textures As Long '_ _ _纹理的数量
    Texture_List() As Direct3DTexture8
    Number_Of_Vertices As Long

End Type

Private Map As Map_Type

这里的地图上的物体代码存在一个19*15的数组里:每个横纵位置表示一个物体编号,
0=草地:0草地
1=植物:在这里插入图片描述
2=标识牌:标识牌
3=池塘1:池塘1
4=池塘2:池塘2
5=池塘3:池塘3
6=池塘4:池塘4

    '地图数组
    Map.Width = (20) - 1
    Map.Height = (16) - 1
    ReDim Map.Map(Map.Height) As String
    '地图结构
    Map.Map(0) = "2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2"
    Map.Map(1) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(2) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(3) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(4) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(5) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(6) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(7) = "0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0"
    Map.Map(8) = "0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0"
    Map.Map(9) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(10) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(11) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(12) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(13) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(14) = "0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0"
    Map.Map(15) = "2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2"
    
    ReDim Map.Tile(Map.Width, Map.Height) As Long
    ReDim Map.New_Tile(Map.Width, Map.Height) As Long
    
    For Y = 0 To Map.Height
    
        Temp = Split(Map.Map(Y), ", ", -1)
    
        For X = 0 To Map.Width
    
            Map.Tile(X, Y) = CLng(Temp(X))
            
        Next X
        
    Next Y

4. 从文件加载纹理贴图子程序(Load_Textures )
过程同前文所述

5.创建多边形子程序: (Create_Polygons)

'顶点数
   Map.Number_Of_Vertices = ((Map.Width + 1) * (Map.Height + 1) * Number_Of_Vertices_Per_Quad)
     '主_顶点列表(顶点数-1)
       ReDim Master_Vertex_List(Map.Number_Of_Vertices - 1) As TLVERTEX
       '顶点列表(顶点数-1)
   ReDim Vertex_List(Map.Number_Of_Vertices - 1) As TLVERTEX
   '排序_顶点列表(顶点数-1)  
   ReDim Sorted_Vertex_List(Map.Number_Of_Vertices - 1) As TLVERTEX
   
   '映射_ To_顶点_列表_和_剪辑  主_顶点列表(顶点数-1),顶点列表(顶点数-1)
       Map_To_Vertex_List_And_Clip Map, Master_Vertex_List(), Vertex_List()

   '排序_多边形_依纹理  顶点列表(顶点数-1), 排序_顶点列表(顶点数-1)  
       Sort_Polygons_By_Texture Map, Vertex_List(), Sorted_Vertex_List()

   '创建顶点缓冲区。
   Set Vertex_Buffer = Direct3D_Device.CreateVertexBuffer(Len(Sorted_Vertex_List(0)) *     Map.Number_Of_Vertices, 0, FVF_TLVERTEX, D3DPOOL_MANAGED)

   D3DVertexBuffer8SetData Vertex_Buffer, 0, Len(Sorted_Vertex_List(0)) * Map.Number_Of_Vertices, 0, Sorted_Vertex_List(0)
   
   Direct3D_Device.SetStreamSource 0, Vertex_Buffer, Len(Sorted_Vertex_List(0))

创建多边形过程如下:
①顶点数=((地图的宽 + 1) * (地图的高 + 1) * 数量_顶点数_每个_四边形)
② Map_To_Vertex_List_And_Clip子程序作用:映射_ To_顶点_列表_和_剪辑
函数代码:

Private Sub Map_To_Vertex_List_And_Clip(Map As Map_Type, Old_Vertex_List() As TLVERTEX, New_Vertex_List() As TLVERTEX)

    Dim X As Long, Y As Long
    Dim X2 As Long, Y2 As Long
    Dim I As Long, J As Long
    Dim Temp As Long
    
    Temp = -1
       
    For Y = 0 To Map.Height '地图高
         For X = 0 To Map.Width '地图宽
            '先循环X轴的贴图,旧_顶点列表0-5
            Old_Vertex_List(I + 0) = Create_TLVertex(GlobalX + ((TILE_WIDTH * X) + 0) * Scalar.X, GlobalY + ((TILE_HEIGHT * Y) + 0) * Scalar.Y, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 0, 0)
            Old_Vertex_List(I + 1) = Create_TLVertex(GlobalX + ((TILE_WIDTH * X) + TILE_WIDTH) * Scalar.X, GlobalY + ((TILE_HEIGHT * Y) + 0) * Scalar.Y, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 1, 0)
            Old_Vertex_List(I + 2) = Create_TLVertex(GlobalX + ((TILE_WIDTH * X) + 0) * Scalar.X, GlobalY + ((TILE_HEIGHT * Y) + TILE_HEIGHT) * Scalar.Y, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 0, 1)
            Old_Vertex_List(I + 3) = Create_TLVertex(GlobalX + ((TILE_WIDTH * X) + TILE_WIDTH) * Scalar.X, GlobalY + ((TILE_HEIGHT * Y) + 0) * Scalar.Y, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 1, 0)
            Old_Vertex_List(I + 4) = Create_TLVertex(GlobalX + ((TILE_WIDTH * X) + TILE_WIDTH) * Scalar.X, GlobalY + ((TILE_HEIGHT * Y) + TILE_HEIGHT) * Scalar.Y, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 1, 1)
            Old_Vertex_List(I + 5) = Create_TLVertex(GlobalX + ((TILE_WIDTH * X) + 0) * Scalar.X, GlobalY + ((TILE_HEIGHT * Y) + TILE_HEIGHT) * Scalar.Y, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 0, 1)
             '如果 Clip_Polygon(剪辑_多边形的子程序)
            If Clip_Polygon(Old_Vertex_List(I + 0), Old_Vertex_List(I + 4)) = False Then

                New_Vertex_List(J + 0) = Old_Vertex_List(I + 0)
                New_Vertex_List(J + 1) = Old_Vertex_List(I + 1)
                New_Vertex_List(J + 2) = Old_Vertex_List(I + 2)
                New_Vertex_List(J + 3) = Old_Vertex_List(I + 3)
                New_Vertex_List(J + 4) = Old_Vertex_List(I + 4)
                New_Vertex_List(J + 5) = Old_Vertex_List(I + 5)

                X2 = X2 + 1
    
                If Temp <> Y Then
    
                    Temp = Y
                    X2 = 1
                    Y2 = Y2 + 1
    
                End If
                
                Map.New_Tile(X2 - 1, Y2 - 1) = Map.Tile(X, Y)
                
                J = J + Number_Of_Vertices_Per_Quad
    
            End If

            I = I + Number_Of_Vertices_Per_Quad
            
        Next X
        
    Next Y

    Map.New_Width = X2
    Map.New_Height = Y2

End Sub

③ Clip_Polygon(剪辑_多边形的子程序)

Private Function Clip_Polygon(Polygon_A As TLVERTEX, Polygon_B As TLVERTEX) As Boolean '剪辑_多边形
    
    Dim R As RECT
    Dim Border_Size As Long
    
    Border_Size = 0
    
    If Fullscreen_Enabled = False Then
    
        R.Left = Border_Size * Scalar.X
        R.Top = Border_Size * Scalar.Y
        R.Right = Me.ScaleWidth - Border_Size * Scalar.X
        R.bottom = Me.ScaleHeight - Border_Size * Scalar.Y
        
    Else

        R.Left = Border_Size * Scalar.X
        R.Top = Border_Size * Scalar.Y
        R.Right = Fullscreen_Width - Border_Size * Scalar.X
        R.bottom = Fullscreen_Height - Border_Size * Scalar.Y

    End If
    
    If (Polygon_A.X < R.Left And Polygon_B.X < R.Left) Or (Polygon_A.X > R.Right And Polygon_B.X > R.Right) Or _
           (Polygon_A.Y < R.Top And Polygon_B.Y < R.Top) Or (Polygon_A.Y > R.bottom And Polygon_B.Y > R.bottom) Then Clip_Polygon = True

End Function

④Sort_Polygons_By_Texture :排序_多边形_依纹理

Private Sub Sort_Polygons_By_Texture(Map As Map_Type, Old_Vertex_List() As TLVERTEX, New_Vertex_List() As TLVERTEX)

    Dim X As Long, Y As Long
    
    Dim I As Long, J As Long, K As Long

    For Current_Texture = 0 To Map.Number_Of_Textures
        
        I = 0
        
        For Y = 0 To Map.New_Height - 1
        
            For X = 0 To Map.New_Width - 1
                
                    If Map.New_Tile(X, Y) = Current_Texture Then
                        
                         New_Vertex_List(J + 0) = Old_Vertex_List(I + 0)
                         New_Vertex_List(J + 1) = Old_Vertex_List(I + 1)
                         New_Vertex_List(J + 2) = Old_Vertex_List(I + 2)
                         New_Vertex_List(J + 3) = Old_Vertex_List(I + 3)
                         New_Vertex_List(J + 4) = Old_Vertex_List(I + 4)
                         New_Vertex_List(J + 5) = Old_Vertex_List(I + 5)
                         
                         '对所有顶点求和,请勿重置此变量。
                         J = J + Number_Of_Vertices_Per_Quad
                         '每个纹理的顶点总数。
                         K = K + Number_Of_Vertices_Per_Quad
                         
                    End If
                    
                    I = I + Number_Of_Vertices_Per_Quad
                    
            Next X
            
        Next Y
        
        Map.Number_Of_Polygons_Per_Tile_Set(Current_Texture) = K / 3
        Map.Number_Of_Vertices_Per_Tile_Set(Current_Texture) = K
        
        K = 0 '重置此纹理,另一个纹理即将到来
            
    Next Current_Texture

End Sub

6、DirectInput _初始化_键盘子程序(DirectInput_Initialize_Keyboard)
键盘初始化

Set Direct_Input = DirectX8.DirectInputCreate
    Set Keyboard_Device = Direct_Input.CreateDevice("GUID_SysKeyboard")
    Keyboard_Device.SetCommonDataFormat DIFORMAT_KEYBOARD
    Keyboard_Device.SetCooperativeLevel Window.hWnd, DISCL_BACKGROUND Or DISCL_NONEXCLUSIVE
    Keyboard_Device.Acquire
    Keyboard_Device.GetDeviceStateKeyboard Keyboard_State

7、高精度计时器初始化子程序(Hi_Res_Timer_Initialize)
过程同前文所述

经过前边7个步骤后进入游戏循环子程序

二、游戏循环子程序:(ame_Loop)
1.键盘控制子程序:Control 前边使用Form_KeyDown来判断按键值,这里使用单独的DirectX子程序来判断, DirectInput_Key_State(DirectInput _键_状态:key(0 To 255) As Byte)
'根据按键移动画面

Private GlobalX As Single, GlobalY As Single

If DirectInput_Key_State(DIK_ESCAPE) <> 0 Then Close_Program'ESC退出程序
        '---------------------------------------------
    '左右
    '---------------------------------------------
    If DirectInput_Key_State(DIK_LEFT) <> 0 And DirectInput_Key_State(DIK_RIGHT) = 0 Then
    
        GlobalX = Initial_Global.X + Speed * Time(0) * Scalar.X
        
    ElseIf DirectInput_Key_State(DIK_LEFT) = 0 And DirectInput_Key_State(DIK_RIGHT) <> 0 Then
    
        GlobalX = Initial_Global.X - Speed * Time(1) * Scalar.X
        
    ElseIf (DirectInput_Key_State(DIK_LEFT) <> 0 And DirectInput_Key_State(DIK_RIGHT) <> 0) Or _
           (DirectInput_Key_State(DIK_LEFT) = 0 And DirectInput_Key_State(DIK_RIGHT) = 0) Then
           
        Milliseconds(0) = Elapsed_Time
        Milliseconds(1) = Elapsed_Time
        Initial_Global.X = GlobalX
        
    End If
    '---------------------------------------------
    
    '---------------------------------------------
    '上/下
    '---------------------------------------------
    If DirectInput_Key_State(DIK_UP) <> 0 And DirectInput_Key_State(DIK_DOWN) = 0 Then
    
        GlobalY = Initial_Global.Y + Speed * Time(2) * Scalar.Y
        
    ElseIf DirectInput_Key_State(DIK_UP) = 0 And DirectInput_Key_State(DIK_DOWN) <> 0 Then
    
        GlobalY = Initial_Global.Y - Speed * Time(3) * Scalar.Y
        
    ElseIf (DirectInput_Key_State(DIK_UP) <> 0 And DirectInput_Key_State(DIK_DOWN) <> 0) Or _
           (DirectInput_Key_State(DIK_UP) = 0 And DirectInput_Key_State(DIK_DOWN) = 0) Then
           
        Milliseconds(2) = Elapsed_Time
        Milliseconds(3) = Elapsed_Time
        Initial_Global.Y = GlobalY

    End If
    '---------------------------------------------

2、碰撞检测子程序 (Collision_Detection)
在移动窗口的时候,用来检测是否超过边界

Dim R As RECT
    
    R.Left = (-(Map.Width * TILE_WIDTH / 2) - TILE_WIDTH / 2) * Scalar.X
    R.Top = (-(Map.Height * TILE_HEIGHT / 2) - TILE_HEIGHT / 2) * Scalar.Y
    R.Right = 0
    R.bottom = 0
    
    If GlobalX <= R.Left Then GlobalX = R.Left
    If GlobalY <= R.Top Then GlobalY = R.Top
    If GlobalX >= R.Right Then GlobalX = R.Right
    If GlobalY >= R.bottom Then GlobalY = R.bottom

3、Create_Polygons,创建多边形 这时候根据GlobalX,GlobalY 坐标重新绘制多边形并显示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gosub60

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值