vb.net使用GDI+实现扫雷小游戏

先说一下扫雷的规则:左键点开,右键用旗子标记(取消标记),一个方块上的数字代表周围九个格里有几颗雷! 比如,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,动态生成控件,面向对象,扫雷

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章