最近學習了.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
下面是演示效果