要做成九個一組的水果盤控制項,首先要把捲動功能做成單一的控制項(Control),然後再用九個拼成新的控制項。
接下來就先把前文的「拉霸遊戲機2」發展成獨立的控制項:
先考量對外至少需要有哪些屬性、方法、事件:
屬性:
1.[停止] 唯寫屬性,設為 True 時可將停止轉動。
2.[忙碌中] 唯讀屬性,控制項轉動中為 True,停止時為 False。
3.[播放速度]讀寫屬性,提供可設定每二次畫格移動的間隔毫秒數。
4.[畫格總數]唯讀屬性,提共外部取得所有圖片的總高度。
5.[結果圖號]唯讀屬性,傳回轉動停止時所在的圖片編號。
6.[捲動方向]讀寫屬性,供讀取或設定轉動的方向。
方法:
1.[啟動]開起始一次畫好的轉動。
2.[停止]停止轉動。
3.[圖片變色]當圖片成為三連線之一時,或其他特定條件下(例如有設 luckey number)用來強化圖片呈現效果。
要做成九個一組的水果盤控制項,首先要把捲動功能做成單一的控制項(Control),然後再用九個拼成新的控制項。
接下來就先把前文的「拉霸遊戲機2」發展成獨立的控制項:
先考量對外至少需要有哪些屬性、方法、事件:
-
屬性:
- [停止] 唯寫屬性,設為 True 時可將停止轉動。
- [忙碌中] 唯讀屬性,控制項轉動中為 True,停止時為 False。
- [播放速度]讀寫屬性,提供可設定每二次畫格移動的間隔毫秒數。
- [畫格總數]唯讀屬性,提共外部取得所有圖片的總高度。
- [結果圖號]唯讀屬性,傳回轉動停止時所在的圖片編號。
- [捲動方向]讀寫屬性,供讀取或設定轉動的方向。
-
方法:
- [啟動]開起始一次畫好的轉動。
- [停止]停止轉動。
- [圖片變色]當圖片成為三連線之一時,或其他特定條件下(例如有設 luckey number)用來強化圖片呈現效果。
-
事件:
- [產生結果了]當轉動完全停止時觸發此一事件,回給呼叫端。
開始建立程式碼:
- 這個控制項完全以圖片為基礎所以不必繼承 UserControl,採用直繼承 PictureBox。
-
類別的變數定義區如下:
#Region "---定義區---" Public Enum 捲動方向列舉常數 向上捲動 向下捲動 End Enum '---這些預備在未來多個 Control 協同工作時共用,所以規劃成靜態--- Private Shared _圖片總數 As Integer = 1 Private Shared _基本暫停毫秒數 As Single = 20 Private Shared _捲動方向 As 捲動方向列舉常數 = 捲動方向列舉常數.向下捲動 Private Shared _播放速度 As Single = 0 Private Shared _現用圖片集合(1) As List(Of Bitmap) '---當下使用中的圖片(0=一般圖片,1=加強圖片)--- Private Shared _客戶圖片集合(1) As List(Of Bitmap) '---使用者指定的圖片(0=一般圖片,1=加強圖片)--- '---這些是自己獨自擁有的內部變數--- Private _停止 As Boolean = False Private _畫格總數 As Integer = 0 Private _現用底圖 As Bitmap Private _忙碌中 As Boolean = False Private _擷取大小 As Size = Me.Size Private _當下畫格指標 As Integer = 0 Private _當下圖號 As Integer = 0 Private _結果圖號 As Integer = 0 Private _希望值 As Integer Private 加速階段終點列數 As Integer = 0 Private 減速階段起點列數 As Integer = 0 Dim 亂數產生器 As Random = New Random Dim 畫格寬 As Integer Dim 畫格高 As Integer '---當轉動停時叵呼的事件--- Event 產生結果了(ByVal sender As ku_ScrollImage, ByVal n As Integer) #End Region
-
接著是屬性區的程式碼:
#Region "---屬性---" Public WriteOnly Property 停止() As Boolean Set(ByVal value As Boolean) _停止 = value End Set End Property Public ReadOnly Property 忙碌中() As Boolean Get Return _忙碌中 End Get End Property <Description("設定播放速度 0-50ms"), Browsable(True), Category("行為")> _ Public Property 播放速度() As Single Get Return _基本暫停毫秒數 End Get Set(value As Single) value = If(value < 0, 0, If(value > 50, 50, _基本暫停毫秒數)) _基本暫停毫秒數 = value End Set End Property <Description("取得播放畫格總數"), Browsable(True), Category("行為")> _ Public ReadOnly Property 畫格總數() As Integer Get Return _畫格總數 End Get End Property <Description("取得圖片集合"), Browsable(True), Category("行為")> _ Public ReadOnly Property 圖片集合() As List(Of Bitmap) Get Return _現用圖片集合(0) End Get End Property <Description("取得圖片總數"), Browsable(True), Category("行為")> _ Public Shared ReadOnly Property 圖片總數() As Integer Get Return _圖片總數 End Get End Property <Description("取得目前圖片編號"), Browsable(True), Category("行為")> _ Public ReadOnly Property 當下圖號() As Integer Get Return _當下圖號 End Get End Property <Description("取得將產生的結果值"), Browsable(True), Category("行為")> _ Public ReadOnly Property 結果圖號() As Integer Get Return _結果圖號 End Get End Property <Description("設定捲動方向"), Browsable(True), Category("行為")> _ Public Shared Property 捲動方向() As 捲動方向列舉常數 Get Return _捲動方向 End Get Set(ByVal value As 捲動方向列舉常數) _捲動方向 = value End Set End Property #End Region
- 至於方法部分,基本上和前篇貼文的原始碼相同不需更動。
-
只有[捲動圖片]的函式改變較大,因為支援了轉動中[停止]功能和送出事件部分:
''' <summary> ''' 捲動圖片 ''' </summary> ''' <param name="希望值">預設捲動結果(0 to n-1)</param> ''' <remarks></remarks> Private Sub 捲動圖片(希望值 As Integer) _停止 = False Dim 已捲動列數 As Integer = 0 Dim 應捲動總列數 = 算出應捲動多少格數(希望值, 3, 9) '---根據「當下圖片、期望圖片、捲動方向」算出應捲動格數--- Dim 擷圖起點位置 As Integer = 0 '---記錄每次捲動後擷取圖像的 Top 位置--- Dim 位移 = 0 '---記錄每次捲動的位移量--- Dim id As Integer = 0 Dim 當下暫停毫秒數 As Single = 0 加速階段終點列數 = 畫格高 * 2 '---定義由慢至快的範圍(最前2張圖片)--- 減速階段起點列數 = 應捲動總列數 - 畫格高 * 9 '---定義由快至慢的範圍(最後9張圖片)--- Try Dim 目的框 As New Rectangle(New Point(0, 0), Me.Size) Using ee As Graphics = Me.CreateGraphics Do If _停止 Then '---讓轉動直接跳至一個新位置--- Dim 新位置 = 應捲動總列數 - CInt(畫格高 * (Rnd(1) * 20 + 6) / 4) '---根據已捲動列數修飾位移量,使捲動的格數正確銜接不會跳格--- If 已捲動列數 < 新位置 Then Dim 差值 = 新位置 - 已捲動列數 位移 = 差值 End If _停止 = False End If id = 畫格高 * _當下圖號 + 已捲動列數 Select Case _捲動方向 Case 捲動方向列舉常數.向上捲動 : 擷圖起點位置 = id Mod _畫格總數 Case 捲動方向列舉常數.向下捲動 : 擷圖起點位置 = _畫格總數 - (id Mod _畫格總數) End Select ee.CompositingQuality = Drawing2D.CompositingQuality.HighSpeed ee.DrawImage(_現用底圖, 目的框, 0, 擷圖起點位置, 畫格寬, 畫格高, GraphicsUnit.Pixel) ee.ReleaseHdc(ee.GetHdc) 已捲動列數 += 位移 Select Case 已捲動列數 Case Is >= 減速階段起點列數 '---停止前減速階段--- 位移 = 2 + (畫格高 / 4) * ((應捲動總列數 - 已捲動列數) / (應捲動總列數 - 減速階段起點列數)) ^ 3 當下暫停毫秒數 = _基本暫停毫秒數 / 2 Case Is < 加速階段終點列數 '---啟動後加速階段--- 位移 = 2 + (畫格高 / 4) * (已捲動列數 / 加速階段終點列數) ^ 1.2 當下暫停毫秒數 = _基本暫停毫秒數 Case Else '---極速階段--- 位移 = 畫格高 / 2 當下暫停毫秒數 = _基本暫停毫秒數 End Select Thread.Sleep(當下暫停毫秒數) Application.DoEvents() id += 位移 Loop While 已捲動列數 < 應捲動總列數 End Using Catch ex As Exception Finally Me.Image = _現用圖片集合(0)(希望值) '---更新控制項的圖片為最後停駐的圖片--- _當下圖號 = 希望值 '---更新當下圖號--- _結果圖號 = 希望值 Me.Update() GC.Collect() '---清理垃圾--- RaiseEvent 產生結果了(Me, 希望值) '---發出事件--- _忙碌中 = False '---清除忙碌旗號--- End Try End Sub
-
這個控制項的資源裡加入了另一組加強效果的圖片,可以在[圖片變色]時取用。
-
編輯階段的樣子:
-
用一個表單寫一個測試用的 demo 程式:
Public Class Form2 Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load pic_幸運圖.SizeMode = PictureBoxSizeMode.StretchImage cbx_幸運圖號.SelectedIndex = 5 '---預設幸運數字為5--- cbx_目的圖號.SelectedIndex = 10 '---預設目的圖號為亂數產生--- End Sub '---用一個按鈕做[啟動]和[停止]兩種動作--- Private Sub 按一下(sender As System.Object, e As System.EventArgs) Handles Button1.Click If sender.text = "啟動" Then Dim 目的 = CInt(cbx_目的圖號.SelectedIndex) Ku_ScrollImage1.啟動(If(目的 = 10, -1, 目的)) sender.text = "停止" Else Ku_ScrollImage1.stop() sender.text = "啟動" End If End Sub '---使用者設定幸運數字--- Private Sub 幸運數字改變了(sender As Object, e As System.EventArgs) Handles _ cbx_幸運圖號.SelectedIndexChanged, cbx_目的圖號.SelectedIndexChanged pic_幸運圖.Image = Ku_ScrollImage1.圖片集合(cbx_幸運圖號.SelectedIndex) lbl_提示.Visible = (cbx_目的圖號.SelectedIndex = cbx_幸運圖號.SelectedIndex) End Sub '---從控制項發出的事件--- Private Sub 產生結果了(sender As ku_ScrollImage, n As Integer) Handles Ku_ScrollImage1.產生結果了 Label2.Text = "結果圖號 = " & n Button1.Text = "啟動" If n = cbx_幸運圖號.SelectedIndex Then Ku_ScrollImage1.圖片變色() End Sub End Class
-
程式執行畫面:
-
影片:
下載[拉霸控制項(三)demo.rar]
下載[圖片捲動(三)專案原始碼.rar]