vb.net实现2048小游戏

Public Class _2048 '2048窗体类
    Private MyA2048 As New a2048 '实例化有游戏类对象
    Dim highScore As Integer = My.Settings.a2048HighScore '实例化的时候读取解决方案里面的设置的该游戏的最高分

    Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
        MyA2048.OnKeyUpSub(e) '调用mya2048的键盘点击事件
        PictureBox1.Image = MyA2048.MyBitmap '然后图片框的图片应用对象的图片属性
        Label1.Text = "当前得分为: " & MyA2048.Scores '显示分数
        If MyA2048.Scores >= highScore Then '如果当前分数大于最高分就让标签显示当前分,并且把最高分保存到setting命名空间里面
            highScore = MyA2048.Scores
            Label2.Text = "最高分: " & highScore
            My.Settings.a2048HighScore = highScore
        End If
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load '窗体加载事件

        PictureBox1.Image = MyA2048.MyBitmap '显示对象的图片属性
    End Sub
End Class
Public Class a2048 'a2048游戏的类
    '绘图基于表格坐标系

    Public MyBitmap As New System.Drawing.Bitmap(400, 400) '一个变量400*400像素的位图
    Private objGraphics As Graphics = Graphics.FromImage(MyBitmap) '私有变量,绘图,来源于位图对象

    Private m_Site(4, 4) As Integer '位置属性,用来表示4*4方格的位置的数字大小,如果是0就代表是空的
    Public Property Site(x As Integer, y As Integer) As Integer
        Get
            Return m_Site(x, y)
        End Get
        Set(ByVal value As Integer)
            m_Site(x, y) = value
        End Set
    End Property
    Private m_scores As Integer = 0 '游戏当前分数属性
    Public Property Scores() As Integer
        Get
            Return m_scores
        End Get
        Set(ByVal value As Integer)
            m_scores = value
        End Set
    End Property
    Private sounder As New System.Media.SoundPlayer(My.Resources.卡片) '声音对象,主要用来播放声音
    Private Sub raiseNewCube() '私有过程
        Randomize() '初始化随机变量
        Dim TempNullNumberCubeArray As New List(Of Point) '声明一个泛型集合,元素类型是点
        For i As Integer = 1 To 4
            For j As Integer = 1 To 4
                If Site(i, j) = 0 Then
                    TempNullNumberCubeArray.Add(New Point(i, j)) '上面的集合收集空的位置
                End If
            Next
        Next
        If TempNullNumberCubeArray.Count = 0 Then
        ElseIf TempNullNumberCubeArray.Count > 16 Then
            Throw New Exception("初始化错误") '不可能大于16,用来捕获错误
        End If
        Dim rndNumber As Integer = CInt(Rnd() * (TempNullNumberCubeArray.Count - 1)) '接下来从空位置里面选择一个空的位置然后
        Dim rnd4Or2 As Integer = Int(Rnd() * 0) '让被选择的空位置随机产生2或者4
        Select Case rnd4Or2
            Case 0
                Site(TempNullNumberCubeArray(rndNumber).X, TempNullNumberCubeArray(rndNumber).Y) = 2
            Case 1
                Site(TempNullNumberCubeArray(rndNumber).X, TempNullNumberCubeArray(rndNumber).Y) = 4
            Case Else
                Throw New Exception("随机数错误") '2的概率是4的概率的2被倍,概率控制

        End Select
        objGraphics.Clear(Color.Azure) '绘图对象清空,用azure颜色,那么游戏图片的背景色就是azure
        For i As Integer = 1 To 4
            For j As Integer = 1 To 4
                If Site(i, j) <> 0 Then
                    Select Case Site(i, j) '遍历所有的空格'然后很据他们点的位置的大小确定当前点的图片
                        Case 2
                            objGraphics.DrawImage(My.Resources._2, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        '绘图对象的画图方法,重载方法之一参数是图片,位置,大小
                        Case 4
                            objGraphics.DrawImage(My.Resources._4, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        Case 8
                            objGraphics.DrawImage(My.Resources._8, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        Case 16
                            objGraphics.DrawImage(My.Resources._16, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        Case 32
                            objGraphics.DrawImage(My.Resources.a32, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        Case 64
                            objGraphics.DrawImage(My.Resources.a64, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        Case 128
                            objGraphics.DrawImage(My.Resources.a128, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        Case 256
                            objGraphics.DrawImage(My.Resources.a256, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        Case 512
                            objGraphics.DrawImage(My.Resources.a512, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        Case 1024
                            objGraphics.DrawImage(My.Resources.a1024, (j - 1) * 100, (i - 1) * 100, 95, 95)
                        Case 2048
                            objGraphics.DrawImage(My.Resources.a2048, (j - 1) * 100, (i - 1) * 100, 95, 95)

                    End Select

                End If
            Next
        Next
    End Sub
    Sub New()
        raiseNewCube() '实例化该对象的时候生成一个新的图片
    End Sub

    Private Event OnKeyUp(ByVal e As KeyEventArgs) '
    Public Sub OnKeyUpSub(e As KeyEventArgs) '按键过程,参数是e,类型是key点击事件
        Dim doCounter As Integer = 0
        If e.KeyCode = Keys.Up Then '如果是按得上键,
            For j As Integer = 1 To 4
                For i As Integer = 2 To 4
                    Dim temp As Integer = i
                    '当没降落到边界,当降落的不是空格,当(它下面是空的或者和它相同的)
                    Do While temp <> 1 AndAlso Site(temp, j) <> 0 AndAlso ((Site(temp - 1, j) = 0) OrElse Site(temp - 1, j) = Site(temp, j)) 'j=1
                        doCounter += 1 '计数器,用来累计do循环了多少次
                        If Site(temp - 1, j) = 0 Then '如果是0就下落
                            Site(temp - 1, j) = Site(temp, j)
                            Site(temp, j) = 0 '迭代替换
                            temp -= 1
                        ElseIf Site(temp - 1, j) = Site(temp, j) Then
                            Scores += Site(temp, j)
                            Site(temp - 1, j) *= 2 '如果和下面的一样就会让它数字翻倍并且下落

                            Site(temp, j) = 0
                            Continue For
                        End If
                    Loop
                Next
            Next


        ElseIf e.KeyCode = Keys.Down Then
            For j As Integer = 1 To 4
                For i As Integer = 3 To 1 Step -1
                    'If i = 1 And j = 4 Then Stop
                    Dim temp As Integer = i
                    Do While temp <> 4 AndAlso Site(temp, j) <> 0 AndAlso ((Site(temp + 1, j) = 0) OrElse Site(temp + 1, j) = Site(temp, j)) 'j=1
                        doCounter += 1

                        If Site(temp + 1, j) = 0 Then

                            Site(temp + 1, j) = Site(temp, j)
                            Site(temp, j) = 0
                            temp += 1
                        ElseIf Site(temp + 1, j) = Site(temp, j) Then
                            Scores += Site(temp, j)
                            Site(temp + 1, j) *= 2
                            Site(temp, j) = 0
                            Continue For
                        End If
                    Loop
                Next
            Next
        ElseIf e.KeyCode = Keys.Left Then
            For i As Integer = 1 To 4
                For j As Integer = 2 To 4
                    Dim temp As Integer = j
                    Do While temp <> 1 AndAlso Site(i, temp) <> 0 AndAlso ((Site(i, temp - 1) = 0) OrElse Site(i, temp - 1) = Site(i, temp)) 'j=1
                        doCounter += 1
                        If Site(i, temp - 1) = 0 Then
                            Site(i, temp - 1) = Site(i, temp)
                            Site(i, temp) = 0
                            temp -= 1
                        ElseIf Site(i, temp - 1) = Site(i, temp) Then
                            Scores += Site(i, temp)
                            Site(i, temp - 1) *= 2
                            Site(i, temp) = 0
                            Continue For
                        End If
                    Loop
                Next
            Next
        ElseIf e.KeyCode = Keys.Right Then
            For i As Integer = 1 To 4
                For j As Integer = 3 To 1 Step -1

                    Dim temp As Integer = j
                    Do While temp <> 4 AndAlso Site(i, temp) <> 0 AndAlso ((Site(i, temp + 1) = 0) OrElse Site(i, temp + 1) = Site(i, temp)) 'j=1
                        doCounter += 1
                        If Site(i, temp + 1) = 0 Then
                            Site(i, temp + 1) = Site(i, temp)
                            Site(i, temp) = 0
                            temp += 1
                        ElseIf Site(i, temp + 1) = Site(i, temp) Then
                            Scores += Site(i, temp)
                            Site(i, temp + 1) *= 2
                            Site(i, temp) = 0
                            Continue For
                        End If
                    Loop
                Next
            Next
        End If
        If doCounter >= 1 Then raiseNewCube() : sounder.Play() '如果计数器大于1说明下落成功,然后可以声音播放,生成新的图片
        If IfEnd() Then MessageBox.Show("游戏结束,您的最终得分为: " & Scores) '调用ifend方法,判断游戏是否结束
    End Sub
    Public Function IfEnd() As Boolean
        Dim i, j As Integer
        For i = 1 To 4
            For j = 1 To 4
                If Site(i, j) = 0 Then Return False
                If (i + j) Mod 2 = 0 AndAlso IfEqualNearby(i, j) = True Then

                    Return False
                End If
            Next
        Next '遍历间隔的方格,然后看有没有相邻相同,做到不重复判断
        Return True
    End Function
    Private Function IfEqualNearby(i As Integer, j As Integer) As Boolean '是否等于周围
        If Site(i, j) = 0 Then Return True
        If in14(i - 1, j) AndAlso Site(i, j) = Site(i - 1, j) Then
            Return True
        ElseIf in14(i + 1, j) AndAlso Site(i, j) = Site(i + 1, j) Then
            Return True
        ElseIf in14(i, j - 1) AndAlso Site(i, j) = Site(i, j - 1) Then
            Return True
        ElseIf in14(i, j + 1) AndAlso Site(i, j) = Site(i, j + 1) Then
            Return True
        End If

        Return False

    End Function
    Private Function in14(i As Integer, j As Integer) As Boolean '是否在1和4直接,对应4*4之内
        If i >= 1 AndAlso i <= 4 AndAlso j >= 1 AndAlso j <= 4 Then
            Return True
        End If
        Return False
    End Function
End Class

程序需要在资源文件中建立几个同名的文件用来显示图片。

使用图片资源的方法,详见我的另一篇博客: vb.net使用图片资源和图片编辑器的方法

代码中需要几个很少的控件

这是界面

欢迎评论和交流哦

猜你喜欢

转载自blog.csdn.net/york1996/article/details/81435075