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

使用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)为对称轴翻转
算法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
'正方形数据交换
    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使用了面相交边的参数来控制队列的进出,实现比较复杂,但是可以节省很多控件,如果大家有好的方法,欢迎分享

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    ''' <summary>
    ''' 初始化各个面对应的边
    ''' </summary>
    ''' <remarks></remarks>
    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
 
    ''' <summary>
    ''' 边数据交换
    ''' </summary>
    ''' <param name="id"></param>
    ''' <remarks></remarks>
    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,绘制菱形,简单的点到点数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    ''' <summary>
    ''' 增加菱形,用于魔方侧面
    ''' </summary>
    ''' <remarks></remarks>
    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
 
    ''' <summary>
    ''' 绘制横向菱形,通过起点参数,获取菱形四个定点坐标
    ''' </summary>
    ''' <remarks></remarks>
    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
 
    ''' <summary>
    ''' 绘制在竖向菱形,通过起点参数,获取菱形四个定点坐标
    ''' </summary>
    ''' <param name="pt"></param>
    ''' <remarks></remarks>
    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

下面是演示效果
3D魔方游戏

Categories: 语言编程 Tags: , ,
  1. No comments yet.
  1. No trackbacks yet.