1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <conio.h>
5 #include <windows.h>
6 #include <time.h>
7
8 typedef int bool;
9 #define true 1
10 #define false 0
11
12 //三件套:添加音乐的函数
13 #include <Windows.h>
14 #include <mmsystem.h>
15 #pragma comment(lib,"winmm.lib")
16
17 #define DEF_SNAKE_LONG 20
18
19 //定义边框数组
20 char g_strgameback[20][48] = {
21 "■■■■■■■■■■■■■■■■■■■■■■■\n",
22 "■ ■\n",
23 "■ ■\n",
24 "■ ■\n",
25 "■ ■\n",
26 "■ ■\n",
27 "■ ■\n",
28 "■ ■\n",
29 "■ ■\n",
30 "■ ■\n",
31 "■ ■\n",
32 "■ ■\n",
33 "■ ■\n",
34 "■ ■\n",
35 "■ ■\n",
36 "■ ■\n",
37 "■ ■\n",
38 "■ ■\n",
39 "■ ■\n",
40 "■■■■■■■■■■■■■■■■■■■■■■■\n"};
41
42 //定义蛇数组
43 int g_arrSnake[DEF_SNAKE_LONG][3] = {0};
44
45 //蛇方向
46 enum {to_east = 2, to_west = -2, to_south = 1, to_north = -1};
47
48 int g_nSnakeDir = to_west;
49
50 bool g_bIsProFood = true;
51
52 int g_nRow;//定义全局横纵坐标的变量
53 int g_nCol;
54
55 //蛇长度
56 int g_nSnakelen = 2;
57
58 //计分
59 int g_nScore = 0;
60
61 void Cover();//显示首页
62 void BGM();//播放音乐
63 void ButtonTest();//显示首页
64 void ShowBack();//打印游戏边框
65 void SetSnakeRandPos();//为蛇产生随机位置
66 void DrawSnake();//将蛇显示到背景上
67 void Snakemove();//蛇动起来
68 void Clean();//销毁残留蛇身
69 void SnakeDir();//改变蛇的方向
70 bool IsSnakeDie();//蛇死亡判断
71 void ProduceFood();//产生食物
72 void SnakeGrowUp();//蛇吃食物变长
73 void Score();//计分
74
75 int main()
76 {
77 BGM();//播放音乐
78 Cover();//显示首页
79 ButtonTest();//检测按键
80 PlaySound(NULL, 0, 0);//停止播放
81 system("cls");//清屏
82
83 SetSnakeRandPos();//为蛇产生随机位置
84 ShowBack();
85
86 while(1)
87 {
88 system("cls");
89
90 ProduceFood();//产生食物
91 SnakeGrowUp();//蛇变长
92 SnakeDir();//改变蛇的方向
93
94 if(false == IsSnakeDie())//蛇死亡判断
95 {
96 printf("Game Over\n");
97 break;
98 }
99
100 Snakemove();//蛇动
101 ShowBack();//显示背景
102 Score();//计分
103 Sleep(500);
104 }
105
106 system("pause");
107 return 0;
108 }
109
110 //显示首页
111 void Cover()
112 {
113 printf("\n\n\n\t\t\t <<SNAKE>>\n\n");
114 printf("\n\n\n\t\t\t<<W,S,A,D control move>>\n\n");
115 printf("\n\n\n\t\t\t <<space begin>>\n\n\n\n");
116 }
117
118 //播放音乐
119 void BGM()
120 {
121 PlaySound("C:\\Windows\\Media\\Alarm03.wav" , NULL, SND_FILENAME | SND_ASYNC);
122 //以C盘系统文件中.wav文件为例
123 }
124
125 //检测按键
126 void ButtonTest()
127 {
128 char chinput;
129
130 //检测空格
131 while(1)
132 {
133 chinput = _getch();
134 if(' ' == chinput)
135 {
136 break;
137 }
138 }
139 }
140
141 //打印游戏边框
142 void ShowBack()
143 {
144 int i = 0;
145
146 for(; i < 20; i++)
147 {
148 printf(g_strgameback[i]);
149 }
150 }
151
152 //为蛇产生随机位置
153 void SetSnakeRandPos()
154 {
155 int nX = -1;
156 int nY = -1;
157
158 //产生随机数
159 srand((unsigned int)time(NULL));//中种子
160 nX = rand()%19 + 1;//对19取余得0~18,+1得0~19
161 nY = rand()%18 + 1;
162
163 //初始化的三个节点
164 g_arrSnake[0][0] = nY; //行
165 g_arrSnake[0][1] = nY*2; //列
166 g_arrSnake[0][2] = to_west; //方向
167
168 g_arrSnake[1][0] = nY;
169 g_arrSnake[1][1] = nY*2 + 2;
170 g_arrSnake[1][2] = to_west;
171
172 g_arrSnake[2][0] = nY;
173 g_arrSnake[2][1] = nY*2 + 4;
174 g_arrSnake[2][2] = to_west;
175
176 //将蛇显示到背景上
177 DrawSnake();
178 }
179
180 //将蛇显示到背景上
181 void DrawSnake()
182 {
183 int i = 0;
184 for(; g_arrSnake[i][0] != 0; i++)//遍历每行,遇到初始蛇的位置拷贝方块
185 {
186 strncpy(&g_strgameback[g_arrSnake[i][0]][g_arrSnake[i][1]], "■", 2);
187 }
188 }
189
190 //蛇动起来
191 void Snakemove()
192 {
193 int i = DEF_SNAKE_LONG - 1;
194
195 Clean();//销毁残留蛇身
196
197 //从后向前遍历
198 for(; i >= 1; i--)
199 {
200 //过滤掉非法蛇身
201 if(0 == g_arrSnake[i][1])
202 {
203 continue;
204 }
205 //把前面一个节点的值赋给前一个节点
206 g_arrSnake[i][0] = g_arrSnake[i-1][0];
207 g_arrSnake[i][1] = g_arrSnake[i-1][1];
208 g_arrSnake[i][2] = g_arrSnake[i-1][2];
209 }
210
211 g_arrSnake[0][2] = g_nSnakeDir;
212
213 //处理蛇头
214 if(to_west == g_arrSnake[0][2] || to_east == g_arrSnake[0][2])
215 {
216 g_arrSnake[0][1] += g_arrSnake[0][2];
217 }
218 else
219 {
220 g_arrSnake[0][0] += g_arrSnake[0][2];
221 }
222
223 //画蛇
224 DrawSnake();
225 }
226
227 //销毁残留蛇身
228 void Clean()
229 {
230 //同画蛇的代码,只不过拷贝上的是空格
231 int i = 0;
232 for(; g_arrSnake[i][0] != 0; i++)//遍历每行,遇到初始蛇的位置拷贝方块空格
233 {
234 strncpy(&g_strgameback[g_arrSnake[i][0]][g_arrSnake[i][1]], " ", 2);
235 }
236 }
237
238 //改变蛇的方向
239 void SnakeDir()
240 {
241 if(GetAsyncKeyState('W'))
242 {
243 g_nSnakeDir = to_north;
244 }
245 else if(GetAsyncKeyState('S'))
246 {
247 g_nSnakeDir = to_south;
248 }
249 else if(GetAsyncKeyState('A'))
250 {
251 g_nSnakeDir = to_west;
252 }
253 if(GetAsyncKeyState('D'))
254 {
255 g_nSnakeDir = to_east;
256 }
257 }
258
259 //蛇死亡判断
260 bool IsSnakeDie()
261 {
262 //判断蛇头方向
263 if(to_west == g_arrSnake[0][2] || to_east == g_arrSnake[0][2])
264 {
265 if(0 == strncmp(&g_strgameback[g_arrSnake[0][0]][g_arrSnake[0][1] + g_arrSnake[0][2]], "■", 2))
266 {
267 return false;
268 }
269 }
270 else
271 {
272 if(0 == strncmp(&g_strgameback[g_arrSnake[0][0] + g_arrSnake[0][2]][g_arrSnake[0][1]], "■", 2))
273 {
274 return false;
275 }
276 }
277
278 return true;
279 }
280
281 //产生食物
282 void ProduceFood()
283 {
284 int i;
285
286 //判断是否产生新的食物
287 if(false == g_bIsProFood)
288 {
289 return ;
290 }
291
292 //产生随机坐标
293 srand((unsigned int)time(NULL));
294
295 while(1)
296 {
297 bool bFlag = true;
298
299 g_nRow = rand()%18 + 1;
300 g_nCol = rand()%20 + 1;
301
302 for(i = 0; g_arrSnake[i][0] != 0; i++)
303 {
304 if(g_nRow == g_arrSnake[i][0] && g_nCol == g_arrSnake[i][0])
305 {
306 bFlag = false;
307 break ;
308 }
309 }
310
311 if(true == bFlag)
312 {
313 break;
314 }
315 }
316
317 //坐标画食物
318 strncpy(&g_strgameback[g_nRow][g_nCol*2], "★", 2);
319
320 g_bIsProFood = false;
321 }
322
323 //蛇吃食物变长
324 void SnakeGrowUp()
325 {
326 //蛇头光标跟坐标相等
327 if(g_nRow == g_arrSnake[0][0] && g_nCol*2 == g_arrSnake[0][1])
328 {
329 //蛇长大
330 if(to_east == g_arrSnake[g_nSnakelen][2])
331 {
332 g_arrSnake[g_nSnakelen+1][0] = g_arrSnake[g_nSnakelen][0];
333 g_arrSnake[g_nSnakelen+1][1] = g_arrSnake[g_nSnakelen][0] - 2;
334 g_arrSnake[g_nSnakelen+1][2] = g_arrSnake[g_nSnakelen][0];
335 }
336 else if(to_west == g_arrSnake[g_nSnakelen][2])
337 {
338 g_arrSnake[g_nSnakelen+1][0] = g_arrSnake[g_nSnakelen][0];
339 g_arrSnake[g_nSnakelen+1][1] = g_arrSnake[g_nSnakelen][0] + 2;
340 g_arrSnake[g_nSnakelen+1][2] = g_arrSnake[g_nSnakelen][0];
341 }
342 else if(to_north == g_arrSnake[g_nSnakelen][2])
343 {
344 g_arrSnake[g_nSnakelen+1][0] = g_arrSnake[g_nSnakelen][0];
345 g_arrSnake[g_nSnakelen+1][1] = g_arrSnake[g_nSnakelen][0] + 1;
346 g_arrSnake[g_nSnakelen+1][2] = g_arrSnake[g_nSnakelen][0];
347 }
348 else if(to_south == g_arrSnake[g_nSnakelen][2])
349 {
350 g_arrSnake[g_nSnakelen+1][0] = g_arrSnake[g_nSnakelen][0];
351 g_arrSnake[g_nSnakelen+1][1] = g_arrSnake[g_nSnakelen][0] - 1;
352 g_arrSnake[g_nSnakelen+1][2] = g_arrSnake[g_nSnakelen][0];
353 }
354
355 g_nSnakelen++;
356 g_bIsProFood = true;
357 g_nScore++;
358 }
359 }
360
361 //计分
362 void Score()
363 {
364 COORD rd;
365 rd.X = 55;
366 rd.Y = 8;
367 //设置光标位置
368 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),rd);
369
370 printf("Score Is : ");
371
372 rd.X = 56;
373 rd.Y = 9;
374
375 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),rd);
376
377 printf("%d",g_nScore*10);
378 }