vb.net使用GDI+實現掃雷小遊戲

York1996發表於2018-08-09

先說一下掃雷的規則:左鍵點開,右鍵用旗子標記(取消標記),一個方塊上的數字代表周圍九個格里有幾顆雷! 比如,1,周圍九個格里只有一顆雷,2 周圍九個格里就有兩顆雷,以此類推。通過單擊即可挖開方塊。 如果挖開的是地雷,則您輸掉遊戲。 如果方塊上出現數字,則表示在其周圍的八個方塊中共有多少顆地雷。 

程式碼質量不是很好,懶得修改了,下面是程式碼


'Option Strict Off '關閉嚴格檢查變數轉換
Imports System.Media

Public Class 掃雷
    '基於座標系統
    Dim MySpaceNumbers As Integer '空的位置
    Dim one As Integer
    Dim cubes(0, 0) As cube '定義二維陣列
    Dim FirstClick As Boolean = True
    Dim tick As Long
    Public Sub CubeOnMouseUp(sender As Object, e As MouseEventArgs) '如果點選的是
        If e IsNot Nothing AndAlso e.Button = MouseButtons.Right Then '如果是第一次點選方塊而且是用右擊

            If CType(sender, cube).state = cube.CubeStates.flag Then '如果說
                Play_Music(New SoundPlayer(My.Resources.拔旗))
                CType(sender, cube).state = cube.CubeStates.unClicked
            ElseIf CType(sender, cube).state = cube.CubeStates.unClicked Then
                CType(sender, cube).state = cube.CubeStates.flag
                Play_Music(New SoundPlayer(My.Resources.插旗))
            End If
        ElseIf CType(sender, cube).state <> cube.CubeStates.flag And CType(sender, cube).state <> cube.CubeStates.space Then '如果沒有旗子插上的話就會
            If e IsNot Nothing Then '這個e是使用者點選的時候e是不是nothing
                '如果僅作遞迴用,就是nothing傳值
                If FirstClick OrElse My.Computer.Clock.TickCount - tick < 5000 Then
                    kill = kill + 1
                    Select Case kill '顯示連殺的聲音
                        Case 1
                            If FirstClick = True Then
                                Play_Music(New SoundPlayer(My.Resources.第一滴血))
                                tick = My.Computer.Clock.TickCount
                            End If
                        Case 2
                            Play_Music(New SoundPlayer(My.Resources.雙殺))
                        Case 3
                            Play_Music(New SoundPlayer(My.Resources.三殺))
                        Case 4
                            Play_Music(New SoundPlayer(My.Resources.四殺))
                        Case 5
                            Play_Music(New SoundPlayer(My.Resources.五殺))
                        Case 6
                            Play_Music(New SoundPlayer(My.Resources.六殺))
                        Case 7
                            Play_Music(New SoundPlayer(My.Resources.接近神了))
                        Case 8
                            Play_Music(New SoundPlayer(My.Resources.超神1))
                        Case 9
                            Play_Music(New SoundPlayer(My.Resources.無人可擋))
                        Case 10
                            Play_Music(New SoundPlayer(My.Resources.大殺特殺))
                    End Select
                Else
                    If kill > 1 Then '如果空格的掃除小於5秒就會shut down
                        Play_Music(New SoundPlayer(My.Resources.終結))
                    End If
                    kill = 0
                    tick = My.Computer.Clock.TickCount
                End If
                tick = My.Computer.Clock.TickCount
            End If
            'Play_Music("排雷成功")
            Dim i As Integer = CType(sender, cube).x
            Dim j As Integer = CType(sender, cube).y 'ij是代表點選了哪個方塊
            If CType(sender, cube).state = cube.CubeStates.space Then '如果當前方塊是空的
                showCubeNumber(sender)                                        '就顯示它的周圍雷的個數
            End If
            If CType(sender, cube).LandMine = True Then '
                If e IsNot Nothing Then                                       ''說明是人點到了地雷
                    CType(sender, cube).state = cube.CubeStates.bomp
                    CType(sender, cube).ForeColor = Color.Red

                    Play_Music(New SoundPlayer(My.Resources.你已被擊殺))
                    ShowAllBompAndAllCubeDisabeled()
                    MessageBox.Show("BOMP! " & vbCrLf & "GAME OVER!")
                End If 'GAME OVER!
            Else                                                             '如果觸發到了沒有地雷的方塊
                CType(sender, cube).state = cube.CubeStates.space     '狀態從未點到無雷.出現空白白色
                If FindBompNumber(FindNearby(sender)) <> 0 Then
                    showCubeNumber(cubes(i, j)) '如果這個方塊的周圍有雷'就顯示數字'就不參與遞迴了
                    GoTo 100
                End If
                For k As Integer = 1 To FindNearby(sender).GetUpperBound(0) '遍歷3*3周圍的方塊,
                    If cubes(FindNearby(sender)(k).X, FindNearby(sender)(k).Y).checked = False And cubes(FindNearby(sender)(k).X, FindNearby(sender)(k).Y).LandMine = False Then
                        cubes(FindNearby(sender)(k).X, FindNearby(sender)(k).Y).checked = True

                        CubeOnMouseUp(cubes(FindNearby(sender)(k).X, FindNearby(sender)(k).Y), CType(Nothing, MouseEventArgs))
                        Continue For
                    End If
                Next
            End If
        End If

100:

        '當遞迴結束後執行下面的'判斷結果
        ' Play_Music("蹦")
        If e IsNot Nothing Then
            MySpaceNumbers = 0
            For Each item As cube In cubes
                If item IsNot Nothing AndAlso item.state = cube.CubeStates.space Then
                    MySpaceNumbers += 1
                End If
            Next

            If MySpaceNumbers = one * one - cube.BompCount Then
                ShowAllBompAndAllCubeDisabeled()
                Play_Music(New SoundPlayer(My.Resources.團滅))

                MessageBox.Show("VICTORY!")
            End If
        End If
        FirstClick = False
    End Sub
    ''' <summary>
    ''' '把圖片顯示到響應的方塊中,引數是要顯示的是哪個方塊
    ''' </summary>
    ''' <param name="sender"></param>
    Sub showCubeNumber(sender As Object)
        Dim sum As Integer = FindBompNumber(FindNearby(sender))
        Dim image() As Image = {My.Resources._1, My.Resources.two, My.Resources.three, My.Resources.four, My.Resources.five, My.Resources.six, My.Resources.seven, My.Resources.eight}
        If sum > 0 Then
            CType(sender, cube).Image = image(sum - 1)
        End If
    End Sub
    ''' <summary>
    '''  '找到一個方塊周圍的地雷總數,引數是座標
    ''' </summary>
    ''' <param name="xys"></param>
    ''' <returns></returns>
    Function FindBompNumber(xys() As Point) As Integer '找到一個方塊周圍的地雷總數,引數是座標
        Dim i As Integer
        Dim sum As Integer = 0
        For i = 1 To UBound(xys)
            If cubes(xys(i).X, xys(i).Y).LandMine = True Then
                sum += 1
            End If
        Next
        Return sum
    End Function
    ''' <summary>
    ''' 顯示所有的炸彈並點選不可用
    ''' </summary>
    Sub ShowAllBompAndAllCubeDisabeled()
        For Each item As cube In cubes
            If item IsNot Nothing Then
                item.Enabled = False
                item.BackColor = Color.AntiqueWhite
                If item.LandMine = True Then
                    item.state = cube.CubeStates.bomp

                End If
            End If
        Next
    End Sub
    ''' <summary>
    ''' '找十字周圍的方塊位置
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <returns></returns>
    Function FindNearby(sender As Object) As Point() '找十字周圍的方塊位置'用來對遊戲進行遞迴
        Dim i As Integer = CType(sender, cube).x
        Dim j As Integer = CType(sender, cube).y
        Dim tempArr(0) As Point
        Dim xs() As Integer = {i - 1, i, i + 1, i - 1, i + 1, i - 1, i, i + 1}
        Dim ys() As Integer = {j - 1, j - 1, j - 1, j, j, j + 1, j + 1, j + 1}
        For k As Integer = 0 To 7
            If in17(xs(k)) And in17(ys(k)) Then
                ReDim Preserve tempArr(UBound(tempArr) + 1)
                tempArr(UBound(tempArr)).X = xs(k)
                tempArr(UBound(tempArr)).Y = ys(k)
            End If
        Next
        Return tempArr
    End Function
    ''' <summary>
    ''' 看看是不是在範圍之內
    ''' </summary>
    ''' <param name="number"></param>
    ''' <returns></returns>
    Function in17(number As Integer) As Boolean
        If number >= 1 And number <= one Then
            Return True
        End If
        Return False
    End Function
    ''' <summary>
    ''' 開始遊戲引數是方塊的行數量
    ''' </summary>
    ''' <param name="number"></param>
    Private Sub 開始(number As Integer) '開始遊戲
        kill = 0
        one = number
        If cubes.Length > 1 Then
            For Each item As cube In cubes
                Me.Controls.Remove(item) '再次遊戲的時候就會清除原有的方塊物件
            Next
        End If
        one = number
        ReDim cubes(one, one) '重新定義cubes陣列.
        Dim I As Integer
        Dim J As Integer
        cube.BompCount = 0 '所有的雷的數量
        For I = 1 To one
            For J = 1 To one
                cubes(I, J) = New cube '例項化陣列元素
                '定義大小
                cubes(I, J).Size = New Size With {.Height = 38 * 12 \ one, .Width = 38 * 12 \ one}
                cubes(I, J).Enabled = True '可用
                cubes(I, J).x = I '座標遊戲位置
                cubes(I, J).y = J
                cubes(I, J).SizeMode = PictureBoxSizeMode.StretchImage '拉伸圖片適應圖片框
                cubes(I, J).Location = New Point With {.X = (J - 1) * 40 * 12 \ one, .Y = (I - 1) * 40 * 12 \ one + 30}
                Me.Controls.Add(cubes(I, J)) '實際位置,並且窗體的控制元件集合增加新的cube
                AddHandler cubes(I, J).MouseUp, AddressOf CubeOnMouseUp '為新的bube物件增加事件
            Next
        Next
    End Sub
    Private Sub Play_Music(ByVal Mname As SoundPlayer)
        Mname.Play() '播放聲音
    End Sub

    Private Sub start(sender As Object, e As EventArgs) Handles 困難1616ToolStripMenuItem.Click, 簡單1010ToolStripMenuItem.Click, 高階2020ToolStripMenuItem.Click
        開始(CInt(Mid(sender.ToString, 3, 2))) '困難簡單或者高階
        FirstClick = True
        Play_Music(New SoundPlayer(My.Resources.戰爭前的寧靜))
    End Sub
    Dim kill As Integer
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load '窗體載入的時候播放音樂
        Play_Music(New SoundPlayer(My.Resources.全軍出擊))
        ' My.Computer.Audio.Play("I:\VB2010NET\vb.net學習\類和物件的學習\掃雷\掃雷\Resources\" & "背景音樂" & ".wav", AudioPlayMode.WaitToComplete)
    End Sub
End Class

''' <summary>
''' 方塊類
''' </summary>
Public Class cube
    Inherits PictureBox '繼承實體類圖片框,因為為了後面方便接收點選事件
    Private Shared m_Count As Integer
    Private Shared m_BompCount As Integer
    Public Shared ReadOnly Property Count() As Integer '總方塊數(這是一個共享過程
        Get
            Return m_Count

        End Get

    End Property

    Public Shared Property BompCount() As Integer '雷的總數量
        Get
            Return m_BompCount
        End Get
        Set(value As Integer)
            m_BompCount = value
        End Set
    End Property

    Public Enum CubeStates '方塊的所有可能的狀態
        unClicked = 0
        space = 1
        bomp = 2
        flag = 3
    End Enum
    Private m_state As CubeStates
    Public Property state() As CubeStates '根據當前的狀態來確定當前方塊的圖片
        Get
            Return m_state
        End Get
        Set(ByVal value As CubeStates)
            m_state = value
            If value = CubeStates.bomp Then
                Me.Image = My.Resources.bomp
            ElseIf value = CubeStates.space Then
                Me.BackColor = Color.LightGreen
            ElseIf value = CubeStates.flag Then
                Me.Image = My.Resources.flag
            ElseIf value = CubeStates.unClicked Then
                Me.Image = Nothing
            End If
        End Set
    End Property
    Public Event StateChange()
    ''' <summary>
    ''' 當前的是不是地雷
    ''' </summary>
    Private m_LandMine As Boolean
    Public Property LandMine() As Boolean
        Get
            Return m_LandMine
        End Get
        Set(ByVal value As Boolean)
            m_LandMine = value
        End Set
    End Property


    Sub New() '建構函式
        Randomize()
        Select Case Int(Rnd() * 1.1) '這個數越大雷就越多'隨機佈雷
            Case 0
                Me.LandMine = False
            Case 1
                Me.LandMine = True
                m_BompCount += 1
        End Select

        Me.BorderStyle = BorderStyle.FixedSingle
        m_Count += 1
    End Sub

    Private m_x As Integer '位置x
    Public Property x() As Integer
        Get
            Return m_x
        End Get
        Set(ByVal value As Integer)
            m_x = value
        End Set
    End Property

    Private m_y As Integer
    Public Property y() As Integer
        Get
            Return m_y
        End Get
        Set(ByVal value As Integer)
            m_y = value
        End Set
    End Property
    Public Property checked() As Boolean '是否已經被遍歷過了
End Class

小遊戲,vb.net,動態生成控制元件,物件導向,掃雷

相關文章