banner
李大仁博客

李大仁博客

天地虽大,但有一念向善,心存良知,虽凡夫俗子,皆可为圣贤。

使用VB.Net GDI+编程编写的3D魔方游戏程序

最近学习了.net 下的 GDI + 编程,下面小秀一下成果,使用 GDI + 编写的桌面魔方程序,今天把源代码放上,欢迎大家下载,如果机器上有.net 环境的话可以直接运行 bin 目录下的 MagicCube.exe 进行游戏。

源代码下载地址 http://www.lidaren.com/code/magiccube/magiccube.zip

下面方式几个重要的算法程序 1,魔方正面九宫格 90 度翻转,这个只要细心观察翻转前和翻转后的魔方,你就可以得到答案 左转 90 度:以 (0,0)(2,2) 为对称轴翻转后,再以 (1,0)(1,2) 为对称轴翻转 右转 90 度:以 (0,2)(2,0) 为对称轴翻转后,再以 (1,0)(1,2) 为对称轴翻转 算法如下:

' 正方形数据交换
Private Sub RevertRectangleLeft(ByVal id As Integer)

    '要实现左转90度
    '先对角线转置
    Dim i, j As Integer
    For i = 1 To Me.DIMCOUNT - 1
        For j = 0 To i - 1
            '交换数据
            Dim temp As Integer
            temp = Me.Matrix3D(id)(i)(j)
            Me.Matrix3D(id)(i)(j) = Me.Matrix3D(id)(j)(i)
            Me.Matrix3D(id)(j)(i) = temp
        Next
    Next
    ''后水平翻转
    For i = 0 To Me.DIMCOUNT - 1
        '交换数据
        Dim temp As Integer
        temp = Me.Matrix3D(id)(0)(i)
        Me.Matrix3D(id)(0)(i) = Me.Matrix3D(id)(Me.DIMCOUNT - 1)(i)
        Me.Matrix3D(id)(Me.DIMCOUNT - 1)(i) = temp
    Next
End Sub

'正方形数据交换
Private Sub RevertRectangleRight(ByVal id As Integer)

    '要实现右转90度
    '先对角线转置
    Dim i, j As Integer
    For i = 0 To Me.DIMCOUNT - 1
        For j = 0 To Me.DIMCOUNT - 1 - i - 1
            '交换数据
            Dim temp As Integer
            temp = Me.Matrix3D(id)(i)(j)
            Me.Matrix3D(id)(i)(j) = Me.Matrix3D(id)(Me.DIMCOUNT - 1 - j)(Me.DIMCOUNT - 1 - i)
            Me.Matrix3D(id)(Me.DIMCOUNT - 1 - j)(Me.DIMCOUNT - 1 - i) = temp
        Next
    Next
    ''后水平翻转
    For i = 0 To Me.DIMCOUNT - 1
        '交换数据
        Dim temp As Integer
        temp = Me.Matrix3D(id)(0)(i)
        Me.Matrix3D(id)(0)(i) = Me.Matrix3D(id)(Me.DIMCOUNT - 1)(i)
        Me.Matrix3D(id)(Me.DIMCOUNT - 1)(i) = temp
    Next
End Sub

2, 魔方正面的 4 个侧面的翻转,这个实现相对较难,方法也很多,CG 这里使用了队列保存所有方块信息,然后再次存回数组的方式来实现,另外为了统一方向,CG 使用了面相交边的参数来控制队列的进出,实现比较复杂,但是可以节省很多控件,如果大家有好的方法,欢迎分享

''' ''' 初始化各个面对应的边
''' 
''' 
Private Sub InitEdge()
    '+/- 10 + 100 + 1000 + X 用于记录对应变的交换方式
    '+/- 表示交换方式,顺序和逆序
    '10 表示 x 的位置 x = 0 或 x = DIMCOUNT
    '100 表示 y 的位置 y = 0 或 y = DIMCOUNT
    '1000 表示 xy的方向 =0 y++ =1000 x++
    Edge(0) = New Integer(3) {-12, 101, 1003, -1004}
    Edge(1) = New Integer(3) {-1002, -1005, -1003, -1000}
    Edge(2) = New Integer(3) {-15, 1, 0, 4}
    Edge(3) = New Integer(3) {-10, -11, 5, -14}
    Edge(4) = New Integer(3) {1102, 1100, 1103, 1105}
    Edge(5) = New Integer(3) {-13, -1001, 2, 1104}
End Sub

''' ''' 边数据交换
''' 
''' 
''' 
Private Sub RevertEdgeRight(ByVal id As Integer)
    '获取边数据
    Dim edges() As Integer
    edges = Me.Edge(id)
    Dim x, y, z, d As Integer
    '临时队列数组
    Dim queue() As Integer
    queue = New Integer(4 \* DIMCOUNT - 1) {}

    Dim edge1 As Integer

    Dim m, i, j As Integer
    Dim count As Integer = 0

    '存入临时数组
    For m = 0 To 3

        '需要交换边
        edge1 = edges(m)

        '获取交换行号与列号
        If Math.Floor(Math.Abs(edge1 / 1000)) = 1 Then
            z = 1
            edge1 = edge1 Mod 1000
        Else
            z = 0
        End If

        If Math.Floor(Math.Abs(edge1 / 100)) = 1 Then
            y = DIMCOUNT - 1
            edge1 = edge1 Mod 100
        Else
            y = 0
        End If

        If Math.Floor(Math.Abs(edge1 / 10)) = 1 Then
            x = DIMCOUNT - 1
            edge1 = edge1 Mod 10
        Else
            x = 0
        End If

        Dim sg = Math.Sign(edge1)

        If sg = 0 Then
            sg = 1
        End If

        '获取符号
        If sg = 1 Then
            d = 0
        Else
            d = 1
        End If

        '存入临时数组
        For i = 0 To DIMCOUNT - 1
            If z = 0 Then
                queue(m \* DIMCOUNT + i) = \_
                    Me.Matrix3D(Math.Abs(edge1))(x)(d \* (DIMCOUNT - 1) + sg \* i)
            Else
                queue(m \* DIMCOUNT + i) = \_
                    Me.Matrix3D(Math.Abs(edge1))(d \* (DIMCOUNT - 1) + sg \* i)(y)
            End If
        Next
    Next
    '交换后存回
    '存入临时数组
    For m = 0 To 3
        '需要交换边
        edge1 = edges(m)
        '获取交换行号与列号
        If Math.Floor(Math.Abs(edge1 / 1000)) = 1 Then
            z = 1
            edge1 = edge1 Mod 1000
        Else
            z = 0
        End If
        If Math.Floor(Math.Abs(edge1 / 100)) = 1 Then
            y = DIMCOUNT - 1
            edge1 = edge1 Mod 100
        Else
            y = 0
        End If

        If Math.Floor(Math.Abs(edge1 / 10)) = 1 Then
            x = DIMCOUNT - 1
            edge1 = edge1 Mod 10
        Else
            x = 0
        End If
        '获取符号
        Dim sg = Math.Sign(edge1)

        If sg = 0 Then
            sg = 1
        End If
        '获取方向
        'd =  Math.Sign(edge1) == 1 ? 0 : -1
        If sg = 1 Then
            d = 0
        Else
            d = 1
        End If
        '存回
        For i = 0 To DIMCOUNT - 1
            If z = 0 Then
                Me.Matrix3D(Math.Abs(edge1))(x)(d \* (DIMCOUNT - 1) + sg \* i) = \_
                    queue(((1 + m) Mod 4) \* DIMCOUNT + i)
            Else
                Me.Matrix3D(Math.Abs(edge1))(d \* (DIMCOUNT - 1) + sg \* i)(y) = \_
                    queue(((1 + m) Mod 4) \* DIMCOUNT + i)
            End If
        Next
    Next
End Sub

3, 绘制菱形,简单的点到点数组

''' ''' 增加菱形,用于魔方侧面
''' 
''' 
Private Sub AddPolygons()

    '定义点阵数组
    Dim pts() As PointF
    '绘制上边矩形
    Dim i, j As Integer
    For i = 0 To DIMCOUNT - 1
        For j = 0 To DIMCOUNT - 1
            pts = AddPolygonPath1(New Point(POSTION.X + i \* CUBEH + j \* POLYH, \_
                                        POSTION.Y - j \* POLYH))
            '获取填充内容,并绘制
            GR.FillPolygon(Me.GetColorById(2, DIMCOUNT - 1 - j, i), pts)
            GR.DrawPolygon(OUTLINE, pts)
        Next
    Next

    '绘制左边矩形
    For i = 0 To DIMCOUNT - 1
        For j = 0 To DIMCOUNT - 1
            pts = AddPolygonPath2(New Point(POSTION.X + DIMCOUNT \* CUBEH + i \* POLYH, \_
                                    POSTION.Y + j \* CUBEH - i \* POLYH))
            '获取填充内容,并绘制
            GR.FillPolygon(Me.GetColorById(4, j, i), pts)
            GR.DrawPolygon(OUTLINE, pts)
        Next
    Next
End Sub

''' ''' 绘制横向菱形,通过起点参数,获取菱形四个定点坐标
''' 
''' 
Private Function AddPolygonPath1(ByVal pt As Point) As PointF()
    Dim pts(3) As PointF
    pts(0) = pt
    pts(1) = New Point(pt.X + POLYH, pt.Y - POLYH)
    pts(2) = New Point(pt.X + CUBEH + POLYH, pt.Y - POLYH)
    pts(3) = New Point(pt.X + CUBEH, pt.Y)
    Return pts
End Function

''' ''' 绘制在竖向菱形,通过起点参数,获取菱形四个定点坐标
''' 
''' 
''' 
Private Function AddPolygonPath2(ByVal pt As Point) As PointF()
    Dim pts(3) As PointF
    pts(0) = pt
    pts(1) = New Point(pt.X + POLYH, pt.Y - POLYH)
    pts(2) = New Point(pt.X + POLYH, pt.Y + CUBEH - POLYH)
    pts(3) = New Point(pt.X, pt.Y + CUBEH)
    Return pts
End Function

下面是演示效果

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。