贪吃蛇游戏---项目练习终极版!秒杀!
首先声明是在TC版本的环境下完成的,不过在其他环境下也可以编译成功,只要把TC环境中用到的而且VC6.0中没有的相应的头文件添加进VC6.0的INCLUDE目录下去就行了
下面的是优化后的游戏代码,有注释,希望能帮助每一个像俺一样的菜鸟。大鸟就不要来凑热闹了,不过可以帮助身边的菜鸟。。。。
1 #include <graphics.h> 2 #include <stdlib.h> 3 #include <conio.h> 4 #include <time.h> 5 #include <stdio.h> 6 #include <bios.h> 7 #include <dos.h> 8 9 #define LEFT 0x4b00 10 #define RIGHT 0x4d00 11 #define DOWN 0x5000 12 #define UP 0x4800 13 #define ESC 0x011b 14 15 #define N 8 /*蛇的最大长度*/ 16 17 int i,key; /*声明一下,这里的key一定要是int类型,不少 */ 18 /*人把它声明为char导致类型错误,无法运行。*/ 19 int score=0; 20 int speed; /*得分*/ 21 22 struct Food 23 { 24 int x; /*食物的横坐标*/ 25 int y; /*食物的纵坐标*/ 26 int yes; /*判断是否要出现食物的变量*/ 27 }food; /*食物的结构体*/ 28 29 struct Snake 30 { 31 int x[N]; 32 int y[N]; 33 int node; /*蛇的节数*/ 34 int direction; /*蛇移动方向*/ 35 int life; /* 蛇的生命,0活着,1死亡*/ 36 }snake; 37 38 void Init(void); /*图形驱动*/ 39 void Close(void); /*图形结束*/ 40 void DrawK(void); /*开始画面*/ 41 void GameOver(void); /*结束游戏*/ 42 void GameComplete(void); /*游戏成功完成*/ 43 void GamePlay(void); /*玩游戏具体过程*/ 44 void PrScore(void); /*输出成绩*/ 45 int Speed(); 46 47 48 /*图形驱动 初始化*/ 49 void Init(void) 50 { 51 int gdriver=DETECT,gmode; 52 initgraph(&gdriver,&gmode,""); 53 speed=Speed(); 54 cleardevice(); 55 } 56 57 /*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/ 58 void DrawK(void) 59 { 60 /*setbkcolor(LIGHTGREEN);*/ 61 setcolor(LIGHTCYAN); 62 setlinestyle(SOLID_LINE,0,1); /*设置线型*/ 63 for(i=50;i<=600;i+=10) /*画围墙*/ 64 { 65 rectangle(i,40,i+10,49); /*上边*/ 66 rectangle(i,451,i+10,460); /*下边*/ 67 } 68 for(i=40;i<=450;i+=10) 69 { 70 rectangle(50,i,59,i+10); /*左边*/ 71 rectangle(601,i,610,i+10); /*右边*/ 72 } 73 } 74 75 int Speed(){ 76 int m; 77 gotoxy(20,10); 78 printf("level1\n"); 79 gotoxy(20,12); 80 printf("level2\n"); 81 gotoxy(20,14); 82 printf("level3\n\t\tplease choose:"); 83 scanf("%d",&m); 84 switch(m){ 85 case 1: 86 return 60000; 87 case 2: 88 return 40000; 89 case 3: 90 return 20000; 91 default: 92 cleardevice(); 93 Speed(); 94 } 95 96 } 97 98 /*玩游戏具体过程*/ 99 void GamePlay(void) 100 { 101 srand((unsigned long)time(0)); /*随机数发生器*/ 102 food.yes=1; /*1表示需要出现新食物,0表示已经存在食物*/ 103 snake.life=0; /*活着*/ 104 snake.direction=1; /*方向往右*/ 105 snake.x[0]=100;snake.y[0]=100; /*蛇头*/ 106 snake.x[1]=110;snake.y[1]=100; 107 snake.node=2; /*节数*/ 108 109 110 PrScore(); /*输出得分*/ 111 do /*可以重复玩游戏,压ESC键结束*/ 112 { 113 while(!kbhit()) /*在没有按键的情况下,蛇自己移动身体*/ 114 { 115 if(food.yes==1) /*需要出现新食物*/ 116 { 117 food.x=rand()%400+60; 118 food.y=rand()%350+60; 119 while(food.x%10!=0) /*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/ 120 food.x++; 121 while(food.y%10!=0) 122 food.y++; 123 food.yes=0; /*画面上有食物了*/ 124 } 125 if(food.yes==0) /*画面上有食物了就要显示*/ 126 { 127 setcolor(GREEN); 128 rectangle(food.x,food.y,food.x+10,food.y-10); 129 } 130 131 for(i=snake.node-1;i>0;i--) /*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/ 132 { 133 snake.x[i]=snake.x[i-1]; 134 snake.y[i]=snake.y[i-1]; 135 } 136 /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/ 137 switch(snake.direction) 138 { 139 case 1: snake.x[0]+=10;break; 140 case 2: snake.x[0]-=10;break; 141 case 3: snake.y[0]-=10;break; 142 case 4: snake.y[0]+=10;break; 143 } 144 /*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/ 145 for(i=3;i<snake.node;i++) 146 { 147 if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]) 148 { 149 GameOver(); /*显示失败*/ 150 snake.life=1; 151 break; 152 } 153 } 154 if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||snake.y[0]>455) /*蛇是否撞到墙壁*/ 155 { 156 GameOver(); /*本次游戏结束*/ 157 snake.life=1; /*蛇死*/ 158 } 159 if(snake.life==1) /*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/ 160 break; 161 if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/ 162 { 163 setcolor(BLACK); /*把画面上的食物东西去掉*/ 164 rectangle(food.x,food.y,food.x+10,food.y-10); 165 snake.x[snake.node]=-20;snake.y[snake.node]=-20; /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/ 166 167 snake.node++; /*蛇的身体长一节*/ 168 food.yes=1; /*画面上需要出现新的食物*/ 169 score+=10; 170 PrScore(); /*输出新得分*/ 171 } 172 if(snake.node==N){ 173 GameComplete(); 174 break; 175 } 176 177 setcolor(RED); /*画出蛇*/ 178 179 for(i=0;i<snake.node;i++) 180 rectangle(snake.x[i],snake.y[i],snake.x[i]+10,snake.y[i]-10); 181 delay(speed); 182 setcolor(BLACK); /*用黑色去除蛇的的最后一节*/ 183 rectangle(snake.x[snake.node-1],snake.y[snake.node-1], 184 snake.x[snake.node-1]+10,snake.y[snake.node-1]-10); 185 } /*endwhile(!kbhit)*/ 186 187 if(snake.life==1) /*如果蛇死就跳出循环*/ 188 break; 189 key=bioskey(0); /*接收按键*/ 190 switch(key) 191 { 192 case UP: 193 if(snake.direction!=4) /*判断是否往相反的方向移动*/ 194 snake.direction=3; 195 break; 196 case RIGHT: 197 if(snake.direction!=2) 198 snake.direction=1; 199 break; 200 case LEFT: 201 if(snake.direction!=1) 202 snake.direction=2; 203 break; 204 case DOWN: 205 if(snake.direction!=3) 206 snake.direction=4; 207 break; 208 } 209 210 211 212 } while(key!=ESC);/*endwhile(1)*/ 213 214 } 215 216 /*游戏结束*/ 217 void GameOver(void) 218 { 219 cleardevice(); 220 PrScore(); 221 setcolor(RED); 222 settextstyle(0,0,4); 223 outtextxy(200,200,"GAME OVER"); 224 getch(); 225 } 226 227 /*游戏成功完成*/ 228 void GameComplete(void) 229 { 230 cleardevice(); 231 PrScore(); 232 setcolor(RED); 233 settextstyle(0,0,4); 234 outtextxy(200,200,"Success"); 235 getch(); 236 } 237 238 /*输出成绩*/ 239 void PrScore(void) 240 { 241 char str[10]; 242 setfillstyle(SOLID_FILL,YELLOW); 243 bar(50,15,220,35); 244 setcolor(BROWN); 245 settextstyle(0,0,4); 246 sprintf(str,"score:%d",score); 247 outtextxy(55,16,str); 248 } 249 250 /*图形结束*/ 251 void Close(void) 252 { 253 closegraph(); 254 } 255 256 /*主函数*/ 257 void main(void) 258 { 259 Init(); /*图形驱动*/ 260 DrawK(); /*开始画面*/ 261 GamePlay(); /*玩游戏具体过程*/ 262 Close(); /*图形结束*/ 263 }