最稳的pk10计划iphone 北京pk10计划手机软件 北京pk10数字的规律 超神手机版pk10软件 pk10北京赛车9码技巧 pk10四期倍投计划表 pk10极速赛车论坛 北京赛车冠军怎样选5码 北京赛车系统下载安装 pk10教程视频 北京pk10选号公式 北京赛车pk10赚钱技巧 北京赛车怎么提升概率 pk10技巧北京快三 北京pk10大小计划
VB.net 2010 視頻教程 VB.net 2010 視頻教程 VB.net 2010 視頻教程
SQL Server 2008 視頻教程 c#入門經典教程 Visual Basic從門到精通視頻教程
當前位置:
首頁 > 編程開發 > VBnet >
  • vb.net教程之VB.NET實現DirectDraw9 (2) 動畫

  • 2019-06-19 15:44 來源:未知
關鍵字: VB.NET  DirectX DirectDraw 9                                    作者:董含君
轉載請注明來自 http://blog.csdn.net/a11s

===========日記================
發現最近比較懶惰,代碼稍微長那么一點,就不想看了.還是看書比較好.
考慮做游戲,但是目前所學的知識還不夠.革命尚未成功,同志們仍需努力啊
===========End 日記=============

今天是完成全屏幕動畫,1024x768,外加多層繪制(鼠標位置就不值得一提了)

先回想一下我們平時是怎樣畫圖的.(應該是做圖)
1 準備一張紙,這個要給別人看的 (PrimarySurface)        
2 一支筆   (Draw方法)
然后自由發揮就可以了 (找坐標,畫..)

這樣是可以的,你的觀眾(坐在顯示器前面的人)不但能看見你的繪制的作品,而且連你如何繪制的都能看見(也許你正在用描點法畫圖...). 很明顯,我們不希望觀眾看見我們繪圖時的“優雅姿態“.我們要的是速度以及效果,這么慢就不叫DirectDraw了

方案2
1 準備一張紙,這個是給觀眾欣賞的(PrimarySurface)
2 再準備一個成型的作品,比如達芬奇畫過的雞蛋 (Surface)
3 畫筆,尖刀,膠水
大概你知道我要做什么了吧,用粘貼的辦法自然要快于描點.但是,觀眾們依然可以知道你是粘貼上去的!當演示一幅一幅的動畫的時候,往往會粘貼的到處都是.....

方案3
1 找個工作臺,請觀眾坐下慢慢看當前的圖像(PrimarySurface)
2 自己再另外找一張或者更多的畫板 (BackSurface)
3 各種工具,只要能方便使用就好 (DrawFast DrawRect DrawText DrawCircle .....)
4 請一位助手幫忙更換工作臺的作品.(PrimarySurface.flip)
這樣您可以解放出來,再也不用擔心您的觀眾看到您繪制的過程了.雖然他們可以“猜測“您是如何繪制的.我們這樣做,在backSurface上面用任意的快速方法做圖,當然可以從其他Surface上面復制,然后粘貼到BackSurface,提交給PrimarySurface,讓他Flip,用戶看到的就是您繪制完之后的結果(PrimarySurface),當觀眾對您的作品贊不絕口的時候,您正在剛才flip之后的畫板上修改,然后把修改之后的這個畫板再flip...

這樣,兩張畫板解決了問題.同時只有1個是觀眾正在看的,另外1個是您手頭上正在畫的,您的助手(PrimarySurface)很聰明,不會搞錯,所以你只要安心畫當前的畫板(BackBuffer)就夠了

強調一下,您繪制的總是Backbuffer,flip方法會把您的backbuffer呈現到PrimaryBuffer,然后繪制,呈現,繪制,呈現...
或者您理解為復制到PrimarySurface也可(實際上是內存的塊移動)

大體步驟跟前文說得一致,僅僅是多生命了幾個Surface用于復制,源代碼不過才200行,主要代碼也就不到100行,里面有比較詳細的注釋.所以再這里就沒有必要解釋了

==================================================
Imports Microsoft.DirectX.DirectDraw
 
Public Class Form1
    Inherits System.Windows.Forms.Form
    Private Structure PointAPI
        Public x As Integer
        Public y As Integer
    End Structure
    '''API用習慣了....也就繼續用吧...
    Private Declare Function GetCursorPos Lib "user32" (ByRef lpPoint As PointAPI) As Integer
 
    Dim dev As New Device(CreateFlags.Default)
 
    Dim PS As Surface           'primarySurface
    Dim BS As Surface           'BackSurface
    Dim S1 As Surface           'Surface1  用于儲存圖像的,想象成一個BMP就行了
    Dim S2 As Surface           'Surface2  同上
    '''分別對應上面的四個Surface
    Dim desc1 As SurfaceDescription
    Dim desc2 As SurfaceDescription
    Dim desc3 As SurfaceDescription
    Dim desc4 As SurfaceDescription
    ''分別對應上面的Surface
    Dim RP As Rectangle
    Dim RB As Rectangle
    Dim R1 As Rectangle
    Dim R2 As Rectangle
 
    '''計時器相關
    Dim tLast As TimeSpan
    Dim fps As String
    Dim tfp As Integer = 0
    Dim mytime As Date = DateTime.Now
    Dim ts As New TimeSpan
    Dim qiqi As Double
    '''游戲控制
    Dim running As Boolean = False
    Dim TT As Threading.Thread
    '''鼠標位置
    Dim M As PointAPI
    '''需要讀取的圖像
    Const FN1 = "d:\nerv.bmp"
    Const FN2 = "d:\logo.bmp"
 
 
#Region " Windows 窗體設計器生成的代碼 "
 
    Public Sub New()
        MyBase.New()
 
        '該調用是 Windows 窗體設計器所必需的。
        InitializeComponent()
 
        '在 InitializeComponent() 調用之后添加任何初始化
 
    End Sub
 
    '窗體重寫 dispose 以清理組件列表。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
 
    'Windows 窗體設計器所必需的
    Private components As System.ComponentModel.IContainer
 
    '注意: 以下過程是 Windows 窗體設計器所必需的
    '可以使用 Windows 窗體設計器修改此過程。
    '不要使用代碼編輯器修改它。
    Friend WithEvents Label1 As System.Windows.Forms.Label
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Label1 = New System.Windows.Forms.Label
        Me.SuspendLayout()
        '
        'Label1
        '
        Me.Label1.Location = New System.Drawing.Point(64, 64)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(80, 24)
        Me.Label1.TabIndex = 0
        Me.Label1.Text = "init&&play"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)
        Me.ClientSize = New System.Drawing.Size(292, 273)
        Me.Controls.Add(Me.Label1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)
 
    End Sub
 
#End Region
 
    Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click
        initDDraw()                 '初始化
        LoadSurfaces()              '讀取圖像
        If TT Is Nothing Then       '用于繪制的線程
            TT = New Threading.Thread(AddressOf mainloop)
            running = True
            TT.Start()
        End If
    End Sub
 
    Sub initDDraw()
        dev.SetCooperativeLevel(Me, CooperativeLevelFlags.FullscreenExclusiveAllowModex)
        dev.SetDisplayMode(1024, 768, 16, 0, False)
 
        'Primarybuffer的設置
        desc1 = New SurfaceDescription
        desc1.SurfaceCaps.VideoMemory = True
        desc1.SurfaceCaps.PrimarySurface = True
        desc1.SurfaceCaps.Flip = True
        desc1.SurfaceCaps.Complex = True
        desc1.BackBufferCount = 1
 
        PS = New Surface(desc1, dev)
 
        desc2 = New SurfaceDescription
        desc2.SurfaceCaps.BackBuffer = True
        BS = PS.GetAttachedSurface(desc2.SurfaceCaps)
 
        BS.ForeColor = System.Drawing.Color.Blue
        BS.FontTransparency = True
        ''OK只要把PrimaryBuffer跟BackBuffer設置好就算初始化完成,其他的圖像都往上貼
 
 
    End Sub
 
    Sub LoadSurfaces()
        '''讀取其他圖層
        ''' 不要把Surface想得那么神秘,就是一個BMP附加上了更多的屬性而已,這樣理解簡單很多
        desc3 = New SurfaceDescription
        desc3.SurfaceCaps.OffScreenPlain = True             '幕后的
        desc3.Height = BS.SurfaceDescription.Height         '大小
        desc3.Width = BS.SurfaceDescription.Width
        S1 = New Surface(FN1, desc3, dev)                   '讀取
 
        desc4 = New SurfaceDescription
        desc4.SurfaceCaps.OffScreenPlain = True             '直接讀
        S2 = New Surface(FN2, desc4, dev)
 
        Dim key As ColorKey                                 '用來設置透明的
        key.ColorSpaceHighValue = 0
        key.ColorSpaceLowValue = 0
        S2.SetColorKey(ColorKeyFlags.SourceDraw, key)       '設置透明色
        '''''設置矩形位置信息
        '''
        RB.Width = BS.SurfaceDescription.Width
        RB.Height = BS.SurfaceDescription.Height
 
        R1.Width = S1.SurfaceDescription.Width
        R1.Height = S1.SurfaceDescription.Height
 
        R2.Width = S2.SurfaceDescription.Width
        R2.Height = S2.SurfaceDescription.Height
        R2.X = 100
        R2.Y = 100
 
    End Sub
 
    Sub mainloop()
        While (running = True)                                      '''如果游戲沒有結束
            blt()                                                   '''主要繪制過程
            tfp += 1                                                '''fps++
            If tfp = 200 Then                                       '''200次的時候計算時間
                tfp = 0
                ts = (DateTime.Now.Subtract(mytime))
                mytime = DateTime.Now
                If ts.TotalSeconds <> 0 Then
                    qiqi = 200 / (ts.TotalSeconds)
                    fps = qiqi.ToString("##.##") + "F c"
                End If
 
            End If
 
            TT.Sleep(10)                                            '''硬性規定休息一下,當然可以去掉發揮MAX速度
        End While
    End Sub
 
    Sub blt()
        If BS Is Nothing Then Exit Sub
        GetMousePos()       '得到鼠標位置
        '''下面的就是利用BackSurface的方法來繪制了,隨便畫,呵呵
        BS.DrawFast(0, 0, S1, R1, DrawFastFlags.Wait)
        BS.DrawText(10, 10, "1024x768 Frames per Second " + fps, False)
        BS.DrawText(10, 30, "當前位置:X=" + M.x.ToString + ",Y=" + M.y.ToString, False)
        BS.DrawText(10, 50, "ESC 退出", False)
        '''畫出貼圖
        BS.DrawFast(M.x, M.y, S2, DrawFastFlags.SourceColorKey Or DrawFastFlags.Wait)
        '''順便在鼠標的位置打出它的坐標
        BS.DrawText(M.x + 50, M.y, "(" + M.x.ToString + "," + M.y.ToString + ")", False)
        '''關鍵一步,翻轉,而且不要使用wait,這樣可能會丟幀,但是不影響速度
        PS.Flip(Nothing, FlipFlags.NoVSync)
 
    End Sub
 
    Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyUp
        If e.KeyCode = Keys.Escape Then End 'ESC退出
    End Sub
    Sub GetMousePos()
        GetCursorPos(M)             '調用API,得到鼠標位置
    End Sub
End Class
 
=====================================
很多代碼跟前面說得一樣,大體思路也是跟我舉的例子(方案3)一致

通過代碼.可以了解具體步驟

DirectDraw再往下就是圖像的透明度計算(這個有公式的),大小變換,旋轉.具體請參考現成的代碼以及公式,我計算機圖形學沒有學過,估計是很困難.而且DDraw還有很多內置的方法可以提供簡單的轉換方式,這個估計需要查閱英文原版的DirectDraw7才能找到相應的方法了...

OK DirectDraw到此結束,如果可能,還會寫一個應用DirectDraw的Demo,但是估計就不會這樣具體說明了,呵呵.

終于可以安心研究那個混音了
pk10赛车冠军技巧
最稳的pk10计划iphone 北京pk10计划手机软件 北京pk10数字的规律 超神手机版pk10软件 pk10北京赛车9码技巧 pk10四期倍投计划表 pk10极速赛车论坛 北京赛车冠军怎样选5码 北京赛车系统下载安装 pk10教程视频 北京pk10选号公式 北京赛车pk10赚钱技巧 北京赛车怎么提升概率 pk10技巧北京快三 北京pk10大小计划
捕鱼达人千炮版 孝感三叉做什么事一样赚钱 浙江11选5推荐码 手机解屏赚钱 空洞骑士如何赚钱 御宅屋写文赚钱 火山小视频主持人如何赚钱 有没有买基金赚钱的 魔兽厄运 赚钱