贪吃蛇easyx版本
这学期学了图形交互学,三个星期下来,突然意识到已经可以用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:运行游戏开始后不能按除方向键和wasd键外的其它键,不然会提示撞墙 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 }
** Then I looked up at the sky and saw the sun **
posted on 2016-03-21 21:17 chenyangsocool 阅读(883) 评论(0) 编辑 收藏 举报