贪吃蛇单机版
首先我们需要食物,蛇的节点,一条蛇三个结构
蛇做的有点抽象...
部分代码取自 http://www.cppblog.com/menjitianya/archive/2011/05/26/147205.html
所有代码打包下载
1
class
Food
2 {
3 public :
4 Food(){}
5 Food(COORD _cd) : cd(_cd){}
6
7 COORD cd;
8 };
9
10 class SnakeNode
11 {
12 public :
13 SnakeNode() : Prev( 0 ),Next( 0 )
14 {
15 cd.X = cd.Y = 0 ;
16 }
17
18 SnakeNode(COORD _cd) : cd(_cd),Prev( 0 ),Next( 0 ){}
19 SnakeNode( int x, int y) : Prev( 0 ),Next( 0 )
20 {
21 cd.X = x;
22 cd.Y = y;
23 }
24
25 COORD cd;
26 SnakeNode * Prev;
27 SnakeNode * Next;
28 };
29
30 class Snake
31 {
32 public :
33 Snake()
34 {
35 Initialize();
36 }
37
38 ~ Snake()
39 {
40 Destroy();
41 }
42
43 void Initialize()
44 {
45 Score = 0 ;
46 Length = 3 ;
47 Type = dtLeft;
48 Speed = 1000 ;
49 Score = 0 ;
50 SnakeNode * pNode1 = new SnakeNode(GAME_WIDTH / 2 ,GAME_HEIGHT / 2 );
51 SnakeNode * pNode2 = new SnakeNode(pNode1 -> cd.X + 1 ,pNode1 -> cd.Y);
52 SnakeNode * pNode3 = new SnakeNode(pNode1 -> cd.X + 2 ,pNode1 -> cd.Y);
53 pNode1 -> Next = pNode2;
54 pNode2 -> Next = pNode3;
55 pNode3 -> Prev = pNode2;
56 pNode2 -> Prev = pNode1;
57 Head = pNode1;
58 Tail = pNode3;
59 }
60
61 void Destroy()
62 {
63 SnakeNode * pNode = Head -> Next;
64 while (pNode)
65 {
66 SnakeNode * Next = pNode -> Next;
67 delete pNode;
68 pNode = Next;
69 }
70 if (Head)
71 {
72 delete Head;
73 Head = Tail = 0 ;
74 }
75 }
76
77 int Insert( int x, int y)
78 {
79 SnakeNode * pNode = new SnakeNode(x,y);
80 pNode -> Next = Head;
81 Head -> Prev = pNode;
82 Head = pNode;
83 return ++ Length;
84 }
85
86 COORD Pop()
87 {
88 COORD cd = Tail -> cd;
89 Tail = Tail -> Prev;
90 delete Tail -> Next;
91 Tail -> Next = 0 ;
92 return cd;
93 }
94
95 int Length; // 长度,无用
96 DIRECTIONTYPE Type; // 方向
97 SnakeNode * Head; // 蛇头节点
98 SnakeNode * Tail; // 蛇尾节点
99 int Speed; // 速度
100 Food food; // 食物位置
101 int Score; // 分数
102 };
然后我们需要一个函数表示蛇向蛇头方向移动了一格
2 {
3 public :
4 Food(){}
5 Food(COORD _cd) : cd(_cd){}
6
7 COORD cd;
8 };
9
10 class SnakeNode
11 {
12 public :
13 SnakeNode() : Prev( 0 ),Next( 0 )
14 {
15 cd.X = cd.Y = 0 ;
16 }
17
18 SnakeNode(COORD _cd) : cd(_cd),Prev( 0 ),Next( 0 ){}
19 SnakeNode( int x, int y) : Prev( 0 ),Next( 0 )
20 {
21 cd.X = x;
22 cd.Y = y;
23 }
24
25 COORD cd;
26 SnakeNode * Prev;
27 SnakeNode * Next;
28 };
29
30 class Snake
31 {
32 public :
33 Snake()
34 {
35 Initialize();
36 }
37
38 ~ Snake()
39 {
40 Destroy();
41 }
42
43 void Initialize()
44 {
45 Score = 0 ;
46 Length = 3 ;
47 Type = dtLeft;
48 Speed = 1000 ;
49 Score = 0 ;
50 SnakeNode * pNode1 = new SnakeNode(GAME_WIDTH / 2 ,GAME_HEIGHT / 2 );
51 SnakeNode * pNode2 = new SnakeNode(pNode1 -> cd.X + 1 ,pNode1 -> cd.Y);
52 SnakeNode * pNode3 = new SnakeNode(pNode1 -> cd.X + 2 ,pNode1 -> cd.Y);
53 pNode1 -> Next = pNode2;
54 pNode2 -> Next = pNode3;
55 pNode3 -> Prev = pNode2;
56 pNode2 -> Prev = pNode1;
57 Head = pNode1;
58 Tail = pNode3;
59 }
60
61 void Destroy()
62 {
63 SnakeNode * pNode = Head -> Next;
64 while (pNode)
65 {
66 SnakeNode * Next = pNode -> Next;
67 delete pNode;
68 pNode = Next;
69 }
70 if (Head)
71 {
72 delete Head;
73 Head = Tail = 0 ;
74 }
75 }
76
77 int Insert( int x, int y)
78 {
79 SnakeNode * pNode = new SnakeNode(x,y);
80 pNode -> Next = Head;
81 Head -> Prev = pNode;
82 Head = pNode;
83 return ++ Length;
84 }
85
86 COORD Pop()
87 {
88 COORD cd = Tail -> cd;
89 Tail = Tail -> Prev;
90 delete Tail -> Next;
91 Tail -> Next = 0 ;
92 return cd;
93 }
94
95 int Length; // 长度,无用
96 DIRECTIONTYPE Type; // 方向
97 SnakeNode * Head; // 蛇头节点
98 SnakeNode * Tail; // 蛇尾节点
99 int Speed; // 速度
100 Food food; // 食物位置
101 int Score; // 分数
102 };
1
static
void
SnakeMove(Snake
&
sn)
2 {
3 COORD cdNew;
4 switch (sn.Type)
5 {
6 case dtTop:
7 cdNew = sn.Head -> cd;
8 cdNew.Y -- ;
9 break ;
10 case dtRight:
11 cdNew = sn.Head -> cd;
12 cdNew.X ++ ;
13 break ;
14 case dtBottom:
15 cdNew = sn.Head -> cd;
16 cdNew.Y ++ ;
17 break ;
18 case dtLeft:
19 cdNew = sn.Head -> cd;
20 cdNew.X -- ;
21 break ;
22 }
23 if (cdNew.X < 0 || cdNew.X >= GAME_WIDTH || cdNew.Y < 0 || cdNew.Y >= GAME_HEIGHT) throw " GameOver " ;
24 sn.Insert(cdNew.X,cdNew.Y);
25 if (cdNew.X != sn.food.cd.X || cdNew.Y != sn.food.cd.Y)
26 {
27 COORD cd = sn.Pop();
28 Check(sn);
29 DrawBack(cd);
30 }
31 else
32 {
33 sn.food = GetFood();
34 sn.Score ++ ;
35 sn.Speed = 1000 - (( int )(sn.Score / 10 )) * 100 ;
36 Check(sn);
37 }
38 }
我们需要一个延时函数和等待用户按键的函数
2 {
3 COORD cdNew;
4 switch (sn.Type)
5 {
6 case dtTop:
7 cdNew = sn.Head -> cd;
8 cdNew.Y -- ;
9 break ;
10 case dtRight:
11 cdNew = sn.Head -> cd;
12 cdNew.X ++ ;
13 break ;
14 case dtBottom:
15 cdNew = sn.Head -> cd;
16 cdNew.Y ++ ;
17 break ;
18 case dtLeft:
19 cdNew = sn.Head -> cd;
20 cdNew.X -- ;
21 break ;
22 }
23 if (cdNew.X < 0 || cdNew.X >= GAME_WIDTH || cdNew.Y < 0 || cdNew.Y >= GAME_HEIGHT) throw " GameOver " ;
24 sn.Insert(cdNew.X,cdNew.Y);
25 if (cdNew.X != sn.food.cd.X || cdNew.Y != sn.food.cd.Y)
26 {
27 COORD cd = sn.Pop();
28 Check(sn);
29 DrawBack(cd);
30 }
31 else
32 {
33 sn.food = GetFood();
34 sn.Score ++ ;
35 sn.Speed = 1000 - (( int )(sn.Score / 10 )) * 100 ;
36 Check(sn);
37 }
38 }
1
static
void
Delay(Snake
&
sn)
2 {
3 DWORD dwStart = GetTickCount();
4 while (GetTickCount() - dwStart <= sn.Speed)
5 {
6 int Key = GetKey();
7 if (Key != - 1 )
8 {
9 switch (Key)
10 {
11 case VK_UP:
12 sn.Type = dtTop;
13 break ;
14 case VK_RIGHT:
15 sn.Type = dtRight;
16 break ;
17 case VK_DOWN:
18 sn.Type = dtBottom;
19 break ;
20 case VK_LEFT:
21 sn.Type = dtLeft;
22 break ;
23 }
24 Sleep(sn.Speed - GetTickCount() + dwStart);
25 return ;
26 }
27 Sleep( 1 );
28 }
29 }
30
31 static int GetKey()
32 {
33 int KeyList[] = {VK_UP,VK_RIGHT,VK_DOWN,VK_LEFT,VK_ESCAPE, 0x52 };
34 for ( int i = 0 ;i < 6 ;i ++ )
35 {
36 if (GetAsyncKeyState(KeyList[i]))
37 return KeyList[i];
38 }
39 return - 1 ;
40 }
当然我们也需要一个生成食物的函数(当然食物不能生成在蛇身上)
2 {
3 DWORD dwStart = GetTickCount();
4 while (GetTickCount() - dwStart <= sn.Speed)
5 {
6 int Key = GetKey();
7 if (Key != - 1 )
8 {
9 switch (Key)
10 {
11 case VK_UP:
12 sn.Type = dtTop;
13 break ;
14 case VK_RIGHT:
15 sn.Type = dtRight;
16 break ;
17 case VK_DOWN:
18 sn.Type = dtBottom;
19 break ;
20 case VK_LEFT:
21 sn.Type = dtLeft;
22 break ;
23 }
24 Sleep(sn.Speed - GetTickCount() + dwStart);
25 return ;
26 }
27 Sleep( 1 );
28 }
29 }
30
31 static int GetKey()
32 {
33 int KeyList[] = {VK_UP,VK_RIGHT,VK_DOWN,VK_LEFT,VK_ESCAPE, 0x52 };
34 for ( int i = 0 ;i < 6 ;i ++ )
35 {
36 if (GetAsyncKeyState(KeyList[i]))
37 return KeyList[i];
38 }
39 return - 1 ;
40 }
1
static
Food GetFood()
2 {
3 COORD cd;
4 BOOL bIn = TRUE;
5 while (bIn)
6 {
7 bIn = FALSE;
8 int n = rand() % (GAME_WIDTH * GAME_HEIGHT);
9 cd.X = n % GAME_WIDTH;
10 cd.Y = n / GAME_WIDTH;
11 for (SnakeNode * pNode = g_Snake.Head;pNode != g_Snake.Tail;pNode = pNode -> Next)
12 {
13 if (cd.X == pNode -> cd.X && cd.Y == pNode -> cd.Y)
14 {
15 bIn = TRUE;
16 break ;
17 }
18 }
19 }
20 Food Result(cd);
21 return Result;
22 }
最后是整体框架
2 {
3 COORD cd;
4 BOOL bIn = TRUE;
5 while (bIn)
6 {
7 bIn = FALSE;
8 int n = rand() % (GAME_WIDTH * GAME_HEIGHT);
9 cd.X = n % GAME_WIDTH;
10 cd.Y = n / GAME_WIDTH;
11 for (SnakeNode * pNode = g_Snake.Head;pNode != g_Snake.Tail;pNode = pNode -> Next)
12 {
13 if (cd.X == pNode -> cd.X && cd.Y == pNode -> cd.Y)
14 {
15 bIn = TRUE;
16 break ;
17 }
18 }
19 }
20 Food Result(cd);
21 return Result;
22 }
1
static
void
Loop()
2 {
3 try
4 {
5 while (TRUE)
6 {
7 DrawSnake(g_Snake);
8 DrawFood(g_Snake);
9 DrawInformation(g_Snake);
10 Delay(g_Snake);
11 SnakeMove(g_Snake);
12 }
13 }
14 catch (LPTSTR str)
15 {
16 system( " cls " );
17 SetCursor( 0 , 0 );
18 printf(str);
19 printf( " \n1.Press R For Restart\n2.Press ESC For Exit " );
20 while (TRUE)
21 {
22 int Key = GetKey();
23 switch (Key)
24 {
25 case VK_ESCAPE:
26 return ;
27 case 0x52 : // Press R
28 g_Snake.Destroy();
29 Initlize();
30 Loop();
31 return ;
32 }
33 Sleep( 100 );
34 }
35 }
36 }
运行结果
2 {
3 try
4 {
5 while (TRUE)
6 {
7 DrawSnake(g_Snake);
8 DrawFood(g_Snake);
9 DrawInformation(g_Snake);
10 Delay(g_Snake);
11 SnakeMove(g_Snake);
12 }
13 }
14 catch (LPTSTR str)
15 {
16 system( " cls " );
17 SetCursor( 0 , 0 );
18 printf(str);
19 printf( " \n1.Press R For Restart\n2.Press ESC For Exit " );
20 while (TRUE)
21 {
22 int Key = GetKey();
23 switch (Key)
24 {
25 case VK_ESCAPE:
26 return ;
27 case 0x52 : // Press R
28 g_Snake.Destroy();
29 Initlize();
30 Loop();
31 return ;
32 }
33 Sleep( 100 );
34 }
35 }
36 }
蛇做的有点抽象...
部分代码取自 http://www.cppblog.com/menjitianya/archive/2011/05/26/147205.html
所有代码打包下载