码迷,mamicode.com
首页 > 其他好文 > 详细

贪吃蛇easyx版本

时间:2016-03-21 21:29:51      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:

这学期学了图形交互学,三个星期下来,突然意识到已经可以用c++写一个贪吃蛇了。

于是就用了两天写了这个小游戏。

其中一天写了核心代码,半天找核心代码中的bug,还有半天进行了界面及操作的优化。

但是有些代码写的依旧有些累赘,比如难度选择界面,不停用if语句,代码太杂了,但是也懒得去优化了,毕竟还有很多事情要做。

下面是游戏运行程序,建议在win10下运行,因为找了几个win7win8系统的童鞋貌似都不能运行,给了他们运行库,运行库也安装不上去。

点击这里下载游戏源程序。

下面是游戏界面截图。

技术分享

技术分享

技术分享

技术分享

好了接下来就贴出这些代码。仅供参考。

  1 #include "stdafx.h"
  2 #include <time.h>
  3 #include <conio.h>
  4 #include <graphics.h>
  5 #include <iostream>
  6 using namespace std;
  7 
  8 //bug:食物可能会生成在蛇身;撞墙不会死;方向键无效
  9 
 10 
 11 /*画窗体边框*/
 12 void drawBorder(bool i, int borderWidth)
 13 {
 14     if (i)
 15     {
 16         setfillcolor(GREEN);
 17     }
 18     else
 19     {
 20         setfillcolor(RED);
 21     }
 22     bar(0, 0, getmaxx(), borderWidth - 1 - 1);//上边框
 23     bar(0, 0, borderWidth - 1 - 1, getmaxy());//左边框
 24     bar(getmaxx() - borderWidth + 1, 0, getmaxx(), getmaxy());//右边框
 25     bar(0, getmaxy() - borderWidth + 1, getmaxx(), getmaxy());//下边框
 26 }
 27 
 28 /*贪吃蛇结构体*/
 29 struct Snake
 30 {
 31     int snakeX;
 32     int snakeY;
 33 };
 34 void drawSnake(struct Snake snakeHeadTemp, int snakeR)
 35 {
 36     setfillcolor(WHITE);
 37     solidcircle(snakeHeadTemp.snakeX, snakeHeadTemp.snakeY, snakeR);
 38 }
 39 //擦除蛇尾
 40 bool eraseSnake(struct Snake snakeHeadTemp, struct Snake snakeTail, int snakeR, struct Snake snakeFood)
 41 {
 42     if ((snakeHeadTemp.snakeX == snakeFood.snakeX) && (snakeHeadTemp.snakeY == snakeFood.snakeY))
 43     {
 44         return true;//如果相同,则返回true,说明需要重新绘制一个食物并且不擦除当前蛇尾
 45     }
 46     else
 47     {
 48         setfillcolor(BLACK);
 49         solidcircle(snakeTail.snakeX, snakeTail.snakeY, snakeR);
 50         return false;
 51     }
 52 }
 53 //检测是否和自身相撞
 54 bool checkSnake(struct Snake *snake, struct Snake snakeHeadTemp, int * snakeLenPtr)
 55 {
 56     for (int i = 0; i < *snakeLenPtr; i++)
 57     {
 58         if (((snake + i)->snakeX == snakeHeadTemp.snakeX) && ((snake + i)->snakeY == snakeHeadTemp.snakeY))
 59         {
 60             return false;
 61         }
 62     }
 63     return true;
 64 }
 65 //对数组排序
 66 void sortSnake(struct Snake *snake, struct Snake snakeHeadTemp, int * snakeLenPtr)
 67 {
 68     for (int i = *snakeLenPtr - 1; i >= 0; i--)//妈蛋,i>=0i>=0i>=0罚抄一百遍!这个bug找了整整半天啊卧槽!
 69     {
 70         (snake + i + 1)->snakeX = (snake + i)->snakeX;
 71         (snake + i + 1)->snakeY = (snake + i)->snakeY;
 72     }
 73     snake->snakeX = snakeHeadTemp.snakeX;
 74     snake->snakeY = snakeHeadTemp.snakeY;
 75 }
 76 //去除尾巴
 77 void eraseTail(struct Snake snakeTail, int snakeR)
 78 {
 79     setfillcolor(BLACK);
 80     solidcircle(snakeTail.snakeX, snakeTail.snakeY, snakeR);
 81 }
 82 //主函数
 83 int main() {
 84     int screenX = 800;//窗口宽
 85     int screenY = 600;//窗口高
 86     int borderWidth = 20;//游戏边框宽度
 87     int snakeX = 50;
 88     int snakeY = 30;
 89     int snakeR = 10;
 90     int snakeI;//声明食物的横个数
 91     int snakeJ;//声明化食物的纵个数
 92     char ch = d;
 93     int foodCount = 0;//初始化吃掉的食物个数
 94     TCHAR str[100];//用于存储提示文字
 95 
 96     initgraph(screenX, screenY);
 97     int speed = 100;
 98 
 99     char choose;
100     int hard = 1;
101 
102     restart:
103     //初始化开始界面
104     setfillcolor(BLUE);
105     bar(0, 0, getmaxx(), getmaxy());
106     setbkcolor(BLUE);
107     setcolor(WHITE);
108     settextstyle(30, 0, TEXT("黑体"));
109     outtextxy(getmaxx() / 2 - 75, getmaxy() / 2 - 200, TEXT("英雄贪吃蛇"));
110     settextstyle(15, 0, TEXT("黑体"));
111     outtextxy(getmaxx() / 2 - 80, getmaxy() / 2 - 130, TEXT("请选择难度,切勿手滑"));
112     setcolor(YELLOW);
113     outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));//200
114     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));//200
115     setcolor(WHITE);
116     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));//100
117     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));//30
118     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));//20
119     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));//退出
120     settextstyle(13, 0, TEXT("黑体"));
121     outtextxy(getmaxx() / 2 - 70, getmaxy() - 50, TEXT("版本 v1.1 made by cy"));
122 
123     //选择界面12 -32
124     while (choose = _getch())
125     {
126         if (choose == -32) { choose = _getch(); }
127         if (choose == 13)
128         {
129             if (hard == 1) { speed = 100; }
130             if (hard == 2) { speed = 80; }
131             if (hard == 3) { speed = 50; }
132             if (hard == 4) { speed = 25; }
133             if (hard == 5) { return 0; }
134             break;
135         }
136         if (choose == 72) 
137         {
138             if (hard > 1) { hard--; }
139             else{ hard = 5; }
140         }
141         if (choose == 80)
142         {
143             if (hard < 5) { hard++; }
144             else { hard = 1; }
145         }
146         if (hard == 1)
147         {
148             settextstyle(15, 0, TEXT("黑体"));
149             setcolor(BLUE);
150             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
151             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
152             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
153             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
154             setcolor(YELLOW);
155             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
156             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
157             setcolor(WHITE);
158             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
159             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
160             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
161             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
162             speed = 100;
163         }
164         if (hard == 2)
165         {
166             settextstyle(15, 0, TEXT("黑体"));
167             setcolor(BLUE);
168             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
169             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
170             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
171             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
172             setcolor(WHITE);
173             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
174             setcolor(YELLOW);
175             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
176             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
177             setcolor(WHITE);
178             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
179             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
180             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
181             speed = 80;
182         }
183         if (hard == 3)
184         {
185             settextstyle(15, 0, TEXT("黑体"));
186             setcolor(BLUE);
187             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
188             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
189             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
190             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
191             setcolor(WHITE);
192             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
193             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
194             setcolor(YELLOW);
195             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
196             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
197             setcolor(WHITE);
198             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
199             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
200             speed = 50;
201         }
202         if (hard == 4)
203         {
204             settextstyle(15, 0, TEXT("黑体"));
205             setcolor(BLUE);
206             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
207             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
208             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
209             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
210             setcolor(WHITE);
211             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
212             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
213             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
214             setcolor(YELLOW);
215             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
216             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
217             setcolor(WHITE);
218             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
219             speed = 25;
220         }
221         if (hard == 5)
222         {
223             settextstyle(15, 0, TEXT("黑体"));
224             setcolor(BLUE);
225             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
226             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
227             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
228             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
229             setcolor(WHITE);
230             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
231             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
232             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
233             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
234             setcolor(YELLOW);
235             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
236             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
237         }
238     }
239 
240 
241 
242     setfillcolor(BLACK);
243     settextstyle(20, 0, TEXT("黑体"));
244     bar(0, 0, getmaxx(), getmaxy());
245     setcolor(WHITE);
246     setbkcolor(BLACK);
247     outtextxy(getmaxx() / 2 - 135, getmaxy()/2-50, TEXT("食物还有5秒到达战场,碾碎它们!"));
248     settextstyle(15, 0, TEXT("黑体"));
249     outtextxy(getmaxx() / 2 - 175, getmaxy() / 2, TEXT("小提示:除了方向键,还可以用wasd键来控制方向哦~"));
250     Sleep(5000);
251     bar(0, 0, getmaxx(), getmaxy());
252 
253     drawBorder(true, borderWidth);
254     //初始化贪吃蛇
255     setfillcolor(YELLOW);
256     int snakeLen = 1; int * snakeLenPtr = &snakeLen;//蛇的节点数,默认为1,即游戏一开始就有一个蛇头
257     struct Snake snake[1064];
258     snake->snakeX = borderWidth + 9; snake->snakeY = borderWidth + 9;//初始化蛇头
259     solidcircle(snake->snakeX, snake->snakeY, snakeR);//初始化蛇头
260     struct Snake snakeTail;//定义蛇尾snakeTail以及一个暂存蛇头的变量
261     struct Snake snakeHeadTemp;//snakeHeadTemp用于在进行数组向后移动的时候保证蛇头不被覆盖
262     struct Snake snakeFood;//snake的食物,随机产生
263     //整个游戏思路是,如果蛇头遇到了新的食物,那么不擦除蛇尾,反之则擦除蛇尾
264 
265     //随机产生一个食物
266     srand(time(NULL));
267     snakeI = rand() % 38 + 1;
268     snakeJ = rand() % 28 + 1;
269     snakeFood.snakeX = borderWidth - 11 + 20 * snakeI;
270     snakeFood.snakeY = borderWidth - 11 + 20 * snakeJ;
271     setfillcolor(LIGHTRED);
272     solidcircle(snakeFood.snakeX, snakeFood.snakeY, snakeR);
273 
274     char c;//用于处理方向键控制和wasd键的冲突
275     while (1)
276     {
277         if (_kbhit())
278         {
279             c = _getch();
280             if (c == a || c == d || c == w || c == s) { ch = c; }
281             else {
282                 ch = _getch();
283                 if (ch == 75) { ch = a; }
284                 if (ch == 77) { ch = d; }
285                 if (ch == 72) { ch = w; }
286                 if (ch == 80) { ch = s; }
287             }
288         }
289         //存储蛇尾以及待添加的位置的值
290         snakeTail.snakeX = snake[snakeLen - 1].snakeX;
291         snakeTail.snakeY = snake[snakeLen - 1].snakeY;
292 
293         switch (ch)
294         {
295         case a://
296             snakeHeadTemp.snakeX = snake->snakeX - 20;
297             snakeHeadTemp.snakeY = snake->snakeY;
298             break;
299         case d://
300             snakeHeadTemp.snakeX = snake->snakeX + 20;
301             snakeHeadTemp.snakeY = snake->snakeY;
302             break;
303         case w://
304             snakeHeadTemp.snakeY = snake->snakeY - 20;
305             snakeHeadTemp.snakeX = snake->snakeX;
306             break;
307         case s://
308             snakeHeadTemp.snakeY = snake->snakeY + 20;
309             snakeHeadTemp.snakeX = snake->snakeX;
310             break;
311         default:
312             break;
313         }
314         //如果撞墙了
315         if (snakeHeadTemp.snakeX > 769 || snakeHeadTemp.snakeX < 19 || snakeHeadTemp.snakeY < 19 || snakeHeadTemp.snakeY > 569)
316         {
317             drawBorder(false, borderWidth);
318             setfillcolor(LIGHTGRAY);
319             bar(0, getmaxy() / 2 - 30, getmaxx(), getmaxy() / 2 + 40);//提示框
320             setbkcolor(LIGHTGRAY);
321             _stprintf_s(str, _T("你撞墙啦!总共吃了%d个食物,5秒后自动重新开始游戏,渣渣??"), foodCount);
322             outtextxy(getmaxx() / 2 - 210, getmaxy() / 2, str);
323             Sleep(5000);
324             ch=d;
325             hard = 1;
326             foodCount = 0;
327             goto restart;
328         }
329         if (checkSnake(snake, snakeHeadTemp, snakeLenPtr))
330         {
331             drawSnake(snakeHeadTemp, snakeR);
332             sortSnake(snake, snakeHeadTemp, snakeLenPtr);//更新蛇身体内的数据
333             //如果为真,说明吃到了食物,则需要重新分配一个食物。并且要把snakeTail推入数组
334             if (eraseSnake(snakeHeadTemp, snakeTail, snakeR, snakeFood))
335             {
336                 foodCount++;
337                 snake[snakeLen].snakeX = snakeTail.snakeX;
338                 snake[snakeLen].snakeY = snakeTail.snakeY;
339                 snakeLen++;
340                 eraseTail(snakeTail, snakeR);
341                 sortSnake(snake, snakeHeadTemp, snakeLenPtr);//更新蛇身体内的数据
342                                                              //随机产生一个食物
343                 snakeI = rand() % 38 + 1;
344                 snakeJ = rand() % 28 + 1;
345                 snakeFood.snakeX = borderWidth - 11 + 20 * snakeI;
346                 snakeFood.snakeY = borderWidth - 11 + 20 * snakeJ;
347             }
348             //每一步都刷新一下食物,因为有时会生成在蛇的身体上,如果不刷新就会被蛇的身体遮挡掉
349             setfillcolor(LIGHTRED);
350             solidcircle(snakeFood.snakeX, snakeFood.snakeY, snakeR);
351         }
352         else
353         {
354             drawBorder(false, borderWidth);
355             setfillcolor(LIGHTGRAY);
356             bar(0, getmaxy() / 2 - 30, getmaxx(), getmaxy() / 2 + 40);//提示框
357             setbkcolor(LIGHTGRAY);
358             _stprintf_s(str, _T("居然会有人撞到自己!噗笑尿!总共吃了%d个食物,5秒后自动重新开始游戏,渣渣??"), foodCount);
359             outtextxy(getmaxx() / 2 - 310, getmaxy() / 2, str);
360             Sleep(5000);
361             ch = d;
362             hard = 1;
363             foodCount = 0;
364             goto restart;
365         }
366         Sleep(speed);
367     }
368     closegraph();
369     return 0;
370 }

 

贪吃蛇easyx版本

标签:

原文地址:http://www.cnblogs.com/chenyangsocool/p/5303771.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!