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

下面是演示效果

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。