标签:全局变量 cap 图片 int att oss 信息 光标移动 code
游戏分析:
——初期分析
——几大模块
一 ,初始化模块(init.h):
功能分析:
初始化欢迎界面:
初始化地图
初始化蛇身
具体实现:
初始化欢迎界面:定位好坐标并打印相关欢迎信息即可;
初始化地图:定位好坐标并依次打印出方块即可;
初始化蛇身:先生成一个节点,再自左向右依次设置剩下的节点,最后遍历打印出节点(方块);
二:判断模块(judge.h):
功能分析:
判断是否碰墙
判断是否碰到自己
判断游戏是否结束(通过标志位)
具体实现:
判断是否碰墙:如果蛇头坐标超出地图范围,判定为撞墙,修改游戏结束标志位;
判断是否碰到自己:从头部开始遍历蛇,如果哪个节点坐标和头部节点坐标重合,就判断撞到自己;
判断游戏是否结束(通过标志位):根据标志位的状态判断游戏是否结束;
三:游戏模块(snake.cpp):
功能分析:
随机出现食物
玩家操作蛇移动,每次响应一个输入事件
游戏结束
具体实现:
随机出现食物:每次通过rand函数生成一个随机坐标,把x转化为偶数坐标,y不变,然后把光标移动到对应位置打印出食物;
玩家操作蛇移动,每次响应一个键盘输入事件:游戏核心,每次响应移动事件后判断是否吃到食物:
游戏结束:结束游戏。
代码如下:
1 // 定义蛇身节点 2 typedef struct SNAKE{ 3 int x; 4 int y; 5 struct SNAKE*next; 6 }snake; 7 snake *head; //头指针 8 //设置光标位置 9 void Pos(int x, int y) 10 { 11 //坐标类型结构体 12 COORD pos; 13 pos.X = x; 14 pos.Y = y; 15 //定义并初始化句柄 16 HANDLE Houtput = GetStdHandle(STD_OUTPUT_HANDLE); 17 //设置光标位置 18 SetConsoleCursorPosition(Houtput, pos); 19 } 20 21 void SetColor(int color_num) //需包含头文件windows.h 22 { 23 using namespace std; 24 HANDLE color; //声明一个句柄 25 color = GetStdHandle(STD_OUTPUT_HANDLE); //取得标准输出句柄 26 SetConsoleTextAttribute(color, color_num); 27 //设置颜色函数SetConsoleTextAttribute有两个参数,第一个为句柄,第二个为颜色代表值 28 //可以使用「|」在第二个参数所填颜色间隔开,实现混色 29 } 30 31 //欢迎界面 32 void welcomepage() 33 { 34 Pos(40, 12); 35 SetColor(6); 36 printf("~~欢迎来到贪吃蛇游戏~~"); 37 Pos(40, 25); 38 printf("用↑,↓,←,→控制蛇的移动\n"); 39 system("pause"); 40 system("cls"); 41 } 42 //初始化地图58/2=29列26行 43 void Map_create() 44 { 45 int i; 46 //■占两个字符的位置(光标移动一位对应一个字符,两个字符光标每次移动两位,也就是坐标值每次加2,一个坐标值对应一个字符位) 47 //上下 48 for (i = 0; i < 58; i += 2) 49 { 50 //移动光标 51 Pos(i, 0); 52 SetColor(4); 53 printf("■"); 54 Pos(i, 26); 55 SetColor(6); 56 printf("■"); 57 } 58 //左右 y取1,2,3...25 59 for (i = 0; i < 26; i++) 60 { 61 //移动光标 62 Pos(0, i); 63 SetColor(4); 64 printf("■"); 65 Pos(56, i); 66 SetColor(6); 67 printf("■"); 68 } 69 printf("\n"); 70 } 71 72 //初始化蛇身,x,y坐标的取值范围57和25 73 void Snakeinit() 74 { 75 snake *tail; //尾指针 76 int i; 77 tail = (snake*)malloc(sizeof(snake)); //初始化尾指针,采用头插法 78 tail->x = 24; //这个设定注定头节点的x坐标只能是偶数 79 tail->y = 5; //y坐标任意 80 tail->next = NULL; 81 //生成五节长的小蛇 82 for (i = 1; i <= 4; i++) 83 { 84 //生成头指针,每次将头指针赋值给尾指针,使蛇增加一节,前面的节已经链在了链表中 85 head = (snake*)malloc(sizeof(snake)); 86 head->next = tail; 87 head->x = 24 + 2 * i; 88 head->y = 5; 89 tail = head; 90 } 91 //从头部开始打印小蛇 92 while (tail != NULL) 93 { 94 //修改光标 95 Pos(tail->x, tail->y); 96 SetColor(2); 97 printf("■"); 98 tail = tail->next; 99 } 100 101 102 }
1 int gameoverflag = 0; //游戏分三种情况,1:撞到墙;2:咬到自己;3:主动退出游戏。 2 int score = 0, point = 10;//总得分与每次吃食物得分。 3 4 int biteself()//判断是否咬到了自己 5 { 6 snake *self; 7 self = head->next; 8 while (self != NULL) 9 { 10 if (self->x == head->x && self->y == head->y) 11 { 12 return 1; 13 } 14 self = self->next; 15 } 16 return 0; 17 } 18 19 20 void endgame()//结束游戏 21 { 22 23 system("cls"); 24 Pos(24, 12); 25 if (gameoverflag== 1) 26 { 27 printf("对不起,您撞到墙了。游戏结束."); 28 } 29 else if (gameoverflag == 2) 30 { 31 printf("对不起,您咬到自己了。游戏结束."); 32 } 33 else if (gameoverflag== 3) 34 { 35 printf("您的已经结束了游戏。"); 36 } 37 Pos(24, 13); 38 printf("您的得分是%d\n", score); 39 exit(0); 40 } 41 42 43 void cantcrosswall()//不能穿墙 44 { 45 if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26) 46 { 47 gameoverflag = 1; 48 endgame(); 49 } 50 } 51 52 void game_pause()//暂停 53 { 54 while (1) 55 { 56 Sleep(300); 57 if (GetAsyncKeyState(VK_SPACE)) 58 { 59 break; 60 } 61 62 } 63 }
1 #include<stdio.h> 2 #include<time.h> 3 #include<windows.h> 4 #include<stdlib.h> 5 #include "init.h" 6 #include "judge.h" 7 8 #define U 1 9 #define D 2 10 #define L 3 11 #define R 4 //蛇的状态,U:上 ;D:下;L:左 R:右 12 13 14 15 //全局变量// 16 int status, sleeptime = 200;//蛇每次移动的时间间隔200ms 17 snake *food;//食物指针 18 snake *q;//遍历蛇的时候用到的指针 19 20 21 22 void createfood()//随机出现食物 23 { 24 snake *food_1; 25 srand((unsigned)time(NULL)); 26 //初始化x坐标 27 food_1 = (snake*)malloc(sizeof(snake)); 28 while ((food_1->x % 2) != 0) //保证其为偶数,使得食物能与蛇头对其 29 { 30 food_1->x = rand() % 52 + 2; 31 } 32 food_1->y = rand() % 24 + 1; 33 q = head; 34 while (q->next == NULL) 35 { 36 if (q->x == food_1->x && q->y == food_1->y) //判断蛇身是否与食物重合 37 { 38 free(food_1); 39 createfood(); 40 } 41 q = q->next; 42 } 43 Pos(food_1->x, food_1->y); 44 food = food_1; 45 SetColor(4); 46 printf("■"); 47 } 48 49 50 51 void snakemove()//蛇前进,上U,下D,左L,右R 52 { 53 snake * nexthead; 54 cantcrosswall(); 55 56 nexthead = (snake*)malloc(sizeof(snake)); 57 if (status == U) 58 { 59 nexthead->x = head->x; 60 nexthead->y = head->y - 1; 61 if (nexthead->x == food->x && nexthead->y == food->y)//如果下一个有食物// 62 { 63 nexthead->next = head; 64 head = nexthead; 65 q = head; 66 while (q != NULL) 67 { 68 Pos(q->x, q->y); 69 SetColor(6); 70 printf("■"); 71 q = q->next; 72 } 73 score = score + point; 74 createfood(); 75 } 76 else //如果没有食物// 77 { 78 nexthead->next = head; 79 head = nexthead; 80 q = head; 81 while (q->next->next != NULL) 82 { 83 Pos(q->x, q->y); 84 SetColor(9); 85 printf("■"); 86 q = q->next; 87 } 88 Pos(q->next->x, q->next->y); 89 printf(" "); 90 free(q->next); 91 q->next = NULL; 92 } 93 } 94 if (status == D) 95 { 96 nexthead->x = head->x; 97 nexthead->y = head->y + 1; 98 if (nexthead->x == food->x && nexthead->y == food->y) //有食物 99 { 100 nexthead->next = head; 101 head = nexthead; 102 q = head; 103 while (q != NULL) 104 { 105 Pos(q->x, q->y); 106 SetColor(6); 107 printf("■"); 108 q = q->next; 109 } 110 score = score + point; 111 createfood(); 112 } 113 else //没有食物 114 { 115 nexthead->next = head; 116 head = nexthead; 117 q = head; 118 while (q->next->next != NULL) 119 { 120 Pos(q->x, q->y); 121 SetColor(12); 122 printf("■"); 123 q = q->next; 124 } 125 Pos(q->next->x, q->next->y); 126 printf(" "); 127 free(q->next); 128 q->next = NULL; 129 } 130 } 131 if (status == L) 132 { 133 nexthead->x = head->x - 2; 134 nexthead->y = head->y; 135 if (nexthead->x == food->x && nexthead->y == food->y)//有食物 136 { 137 nexthead->next = head; 138 head = nexthead; 139 q = head; 140 while (q != NULL) 141 { 142 Pos(q->x, q->y); 143 SetColor(6); 144 printf("■"); 145 q = q->next; 146 } 147 score = score + point; 148 createfood(); 149 } 150 else //没有食物 151 { 152 nexthead->next = head; 153 head = nexthead; 154 q = head; 155 while (q->next->next != NULL) 156 { 157 Pos(q->x, q->y); 158 SetColor(14); 159 printf("■"); 160 q = q->next; 161 } 162 Pos(q->next->x, q->next->y); 163 printf(" "); 164 free(q->next); 165 q->next = NULL; 166 } 167 } 168 if (status == R) 169 { 170 nexthead->x = head->x + 2; 171 nexthead->y = head->y; 172 if (nexthead->x == food->x && nexthead->y == food->y)//有食物 173 { 174 nexthead->next = head; 175 head = nexthead; 176 q = head; 177 while (q != NULL) 178 { 179 Pos(q->x, q->y); 180 SetColor(6); 181 printf("■"); 182 q = q->next; 183 } 184 score = score + point; 185 createfood(); 186 } 187 else //没有食物 188 { 189 nexthead->next = head; 190 head = nexthead; 191 q = head; 192 while (q->next->next != NULL) 193 { 194 Pos(q->x, q->y); 195 SetColor(6); 196 printf("■"); 197 q = q->next; 198 } 199 Pos(q->next->x, q->next->y); 200 printf(" "); 201 free(q->next); 202 q->next = NULL; 203 } 204 } 205 if (biteself() == 1) //判断是否会咬到自己 206 { 207 gameoverflag = 2; 208 endgame(); 209 } 210 } 211 212 213 //玩游戏 214 void gameplay() 215 { 216 217 Pos(64, 15); 218 SetColor(6); 219 printf("不能穿墙,不能咬到自己\n"); 220 Pos(64, 16); 221 SetColor(7); 222 printf("用↑.↓.←.→分别控制蛇的移动."); 223 Pos(64, 17); 224 SetColor(8); 225 printf("F1 为加速,F2 为减速\n"); 226 Pos(64, 18); 227 SetColor(9); 228 printf("ESC :退出游戏.space:暂停游戏."); 229 Pos(64, 20); 230 SetColor(10); 231 printf("~~**~~"); 232 status = R; 233 while (1) 234 { 235 Pos(64, 10); 236 printf("得分:%d ", score); 237 Pos(64, 11); 238 printf("每个食物得分:%d分", point); 239 if (GetAsyncKeyState(VK_UP) && status != D) 240 { 241 status = U; 242 } 243 else if (GetAsyncKeyState(VK_DOWN) && status != U) 244 { 245 status = D; 246 } 247 else if (GetAsyncKeyState(VK_LEFT) && status != R) 248 { 249 status = L; 250 } 251 else if (GetAsyncKeyState(VK_RIGHT) && status != L) 252 { 253 status = R; 254 } 255 else if (GetAsyncKeyState(VK_SPACE)) 256 { 257 game_pause(); 258 } 259 else if (GetAsyncKeyState(VK_ESCAPE)) 260 { 261 gameoverflag = 3; 262 endgame(); 263 } 264 //加速,就是缩小两次移动事件之间的响应速度(反应时间) 265 else if (GetAsyncKeyState(VK_F1)) 266 { 267 if (sleeptime >= 50) 268 { 269 //每次减去30ms 270 sleeptime = sleeptime - 30; 271 //加速奖励分,以后吃到食物多加分 272 point = point + 2; 273 } 274 } 275 //减速,就是增加两次移动事件之间的响应速度(反应时间) 276 else if (GetAsyncKeyState(VK_F2)) 277 { 278 if (sleeptime<350) 279 { 280 sleeptime = sleeptime + 30; 281 //减速难度下降,以后吃到食物分减少 282 point= point- 2; 283 if (sleeptime == 350) 284 { 285 point= 1; //保证最低分为1 286 } 287 } 288 } 289 //刷新事件,两次事件之间间隔sleeptime的毫秒 290 Sleep(sleeptime); 291 snakemove(); 292 } 293 } 294 295 296 297 void game_init()//游戏初始化 298 { 299 system("mode con cols=100 lines=30"); 300 welcomepage(); 301 Map_create(); 302 Snakeinit(); 303 createfood(); 304 } 305 306 int main() 307 { 308 //初始化游戏 309 game_init(); 310 //开始玩游戏 311 gameplay(); 312 return 0; 313 }
Ps:我用了字体颜色变换函数皮了一下,不喜欢的可以去掉这个功能。
标签:全局变量 cap 图片 int att oss 信息 光标移动 code
原文地址:https://www.cnblogs.com/lh2018/p/9221050.html