游戏截图

 
 
开始动画: 
 
游戏过程: 

游戏架构设计

该游戏的玩法简单,玩家通过键盘方向键控制蛇上下左右移动,吃到食物得分并增长,碰到墙或者自己的身体则死亡,游戏结束。 
整个游戏其实就是一个无穷的循环,直到退出游戏时退出循环。我们暂且将这个循环称为一级循环,这个循环包含游戏开始动画,游戏难度选择,游戏过程这三个子模块,其中游戏过程这个模块亦是一个循环,我们暂且将其称为二级循环。它们之间的关系大致如下图: 
 
现在我们根据上图进行细化,对各个模块的实现进行简单描述。

1.游戏开始动画

开始动画的实现主要依靠对点的操作来实现,这里我们先建立一个概念,就是将控制台界面看成一个原点在左上角的坐标系,一个点(x,y)表示坐标系中的一个格子,如下图所示: 
 
我们的开始动画是由一条蛇和一行文字从左到右移动而成,这里我们先单独讨论一下蛇,要达到移动的效果,我采取的策略是将整个过程分为三部分: 
第一部分为蛇从左边开始出现到整个身体完全出现 
第二部分为蛇身整体从左移动到接触右边界的过程 
第三部分为蛇从接触右边界到完全消失的过程
 

我们先来看一下第一部分,这一部分的实现首先是建立一个deque双端队列,用于存储点的对象,这些点就是组成蛇身的元素,然后再用一个for循环将容器中的点依次打印出来,每打印一个点停顿一会,这样就达到了移动的效果。全部打印完后就到了第二部分,这部分蛇的每次前进都是通过计算将要移动到的下一个点的坐标,然后将这个点打印出来,与此同时将蛇尾,亦即queue中的首端点去掉,并擦除屏幕上该点颜色。第三部分就直接依次从蛇尾擦除即可。 
同理,文字snake的移动也基本类似,稍微改动即可,因为无需对首尾进行操作,而是要对所以点进行移动,因此容器选用vector。 
具体请参看startinterface.h以及startinterface.cpp

2.选择难度

其实这个模块很简单,我就简单介绍一下,先将难度选择的文字信息打印在屏幕上,然后通过控制键盘方向键选择,回车键确认,为了突出选中项,需要给选中项打上背景色,然后每一次上下移动时,先将当前的背景色去掉,然后给下一个选中项打上背景色,按下回车后通过改变蛇移动的速度实现改变难度。其中读取键盘输入是通过getch()函数完成的。 

3.游戏过程

这个模块就是整个游戏最主要的部分了,首先它先绘制出地图以及侧边栏,同时初始化蛇和食物,然后通过一个无穷循环监听键盘,以此来控制蛇移动,同时又进行各种判断,来判断是否死亡、吃到食物或暂停。需要提一下,这里使用kbhit()函数来监听键盘,它用来判断在一段固定的时间内是否有键盘输入,要知道,这个函数的返回值有两个,第一个是是否有输入的返回值,第二个才是键盘输入的内容,也就是说要经过两次的读取缓冲区才能读到真正的键盘输入。 

游戏代码实现

从这里开始我们就可以真正动手来实现游戏了,在动手之前,我建议先下载游戏来玩几局,弄清整个游戏的逻辑,这样更能有一个清晰的思路。 
接着你可以将以下的代码或者github上的代码按下面几张图的流程添加进工程里,当然如果你使用其他IDE的话就按照它的方式来弄,然后进行编译试一下。

首先新建工程 

然后将文件一个一个添加进工程里

最后所有文件添加完就是这样了

记得要把编译器改成c++11标准

完成了以上几步后就可以点编译按钮进行编译,同时运行一下,看看效果。然后阅读源码或者修改一下,看看编译后有什么不同。 
这里代码.h文件是类的定义,.cpp文件是类的实现。整个程序共有七个类,分别为Tools,Point,StartInterface,Snake,Map,Food。 
因为整个游戏需要对于点的大量操作,所以建立Tools和Point两个类,Tools工具类主要是用于设置光标的位置以及输出文字的颜色,Point类设置点的对象,因为其他类都是建立在这两个类的基础上的,所以阅读代码时要先看这两个。然后才开始从main.cpp开始看,一行一行,看到出现新的类就转到该类的声明与定义文件去看,这样阅读起来比较清晰,这里简要说明一下各个类的功能,Controller类就是控制整个游戏过程的,包括游戏的各个阶段,比如更新分数,游戏难度选择等;Food类实现食物的随机出现;Map类负责绘制地图,我由于时间关系(主要是懒)没有加入地图,只有边界,但原理和边界是一模一样的,同样是将点绘制出来,然后每一次都判断蛇是否撞到地图即可;Snake类控制蛇的移动和吃到食物等。 
各个类之间的关系大致如下:

以下是实现的代码

main.cpp

#include "controller.h"int main()//程序入口
{Controller c;//声明一个Controller类c.Game();//整个游戏循环return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

controller.h

#ifndef CONTROLLER_H
#define CONTROLLER_Hclass Controller
{
public:Controller() : speed(200), key(1), score(0) {}void Start();void Select();void DrawGame();int PlayGame();void UpdateScore(const int&);void RewriteScore();int Menu();void Game();int GameOver();
private:int speed;int key;int score;
};
#endif // CONTROLLER_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

controller.cpp

#include <iostream>
#include <time.h>
#include <conio.h>
#include <windows.h>
#include "controller.h"
#include "tools.h"
#include "startinterface.h"
#include "map.h"
#include "snake.h"
#include "food.h"void Controller::Start()//开始界面
{SetWindowSize(41, 32);//设置窗口大小SetColor(2);//设置开始动画颜色StartInterface *start = new StartInterface();//动态分配一个StartInterface类startstart->Action();//开始动画delete start;//释放内存空间/*设置关标位置,并输出提示语,等待任意键输入结束*/SetCursorPosition(13, 26);std::cout << "Press any key to start... " ;SetCursorPosition(13, 27);system("pause");
}void Controller::Select()//选择界面
{/*初始化界面选项*/SetColor(3);SetCursorPosition(13, 26);std::cout << "                          " ;SetCursorPosition(13, 27);std::cout << "                          " ;SetCursorPosition(6, 21);std::cout << "请选择游戏难度:" ;SetCursorPosition(6, 22);std::cout << "(上下键选择,回车确认)" ;SetCursorPosition(27, 22);SetBackColor();//第一个选项设置背景色以表示当前选中std::cout << "简单模式" ;SetCursorPosition(27, 24);SetColor(3);std::cout << "普通模式" ;SetCursorPosition(27, 26);std::cout << "困难模式" ;SetCursorPosition(27, 28);std::cout << "炼狱模式" ;SetCursorPosition(0, 31);score = 0;/*上下方向键选择模块*/int ch;//记录键入值key = 1;//记录选中项,初始选择第一个bool flag = false;//记录是否键入Enter键标记,初始置为否while ((ch = getch())){switch (ch)//检测输入键{case 72://UP上方向键if (key > 1)//当此时选中项为第一项时,UP上方向键无效{switch (key){case 2:SetCursorPosition(27, 22);//给待选中项设置背景色SetBackColor();std::cout << "简单模式" ;SetCursorPosition(27, 24);//将已选中项取消我背景色SetColor(3);std::cout << "普通模式" ;--key;break;case 3:SetCursorPosition(27, 24);SetBackColor();std::cout << "普通模式" ;SetCursorPosition(27, 26);SetColor(3);std::cout << "困难模式" ;--key;break;case 4:SetCursorPosition(27, 26);SetBackColor();std::cout << "困难模式" ;SetCursorPosition(27, 28);SetColor(3);std::cout << "炼狱模式" ;--key;break;}}break;case 80://DOWN下方向键if (key < 4){switch (key){case 1:SetCursorPosition(27, 24);SetBackColor();std::cout << "普通模式" ;SetCursorPosition(27, 22);SetColor(3);std::cout << "简单模式" ;++key;break;case 2:SetCursorPosition(27, 26);SetBackColor();std::cout << "困难模式" ;SetCursorPosition(27, 24);SetColor(3);std::cout << "普通模式" ;++key;break;case 3:SetCursorPosition(27, 28);SetBackColor();std::cout << "炼狱模式" ;SetCursorPosition(27, 26);SetColor(3);std::cout << "困难模式" ;++key;break;}}break;case 13://Enter回车键flag = true;break;default://无效按键break;}if (flag) break;//输入Enter回车键确认,退出检查输入循环SetCursorPosition(0, 31);//将光标置于左下角,避免关标闪烁影响游戏体验}switch (key)//根据所选选项设置蛇的移动速度,speed值越小,速度越快{case 1:speed = 135;break;case 2:speed = 100;break;case 3:speed = 60;break;case 4:speed = 30;break;default:break;}
}void Controller::DrawGame()//绘制游戏界面
{system("cls");//清屏/*绘制地图*/SetColor(3);Map *init_map = new Map();init_map->PrintInitmap();delete init_map;/*绘制侧边栏*/SetColor(3);SetCursorPosition(33, 1);std::cout << "Greedy Snake" ;SetCursorPosition(34, 2);std::cout << "贪吃蛇" ;SetCursorPosition(31, 4);std::cout << "难度:" ;SetCursorPosition(36, 5);switch (key){case 1:std::cout << "简单模式" ;break;case 2:std::cout << "普通模式" ;break;case 3:std::cout << "困难模式" ;break;case 4:std::cout << "炼狱模式" ;break;default:break;}SetCursorPosition(31, 7);std::cout << "得分:" ;SetCursorPosition(37, 8);std::cout << "     0" ;SetCursorPosition(33, 13);std::cout << " 方向键移动" ;SetCursorPosition(33, 15);std::cout << " ESC键暂停" ;
}int Controller::PlayGame()//游戏二级循环
{/*初始化蛇和食物*/Snake *csnake = new Snake();Food *cfood = new Food();SetColor(6);csnake->InitSnake();srand((unsigned)time(NULL));//设置随机数种子,如果没有 食物的出现位置将会固定cfood->DrawFood(*csnake);/*游戏循环*/while (csnake->OverEdge() && csnake->HitItself()) //判断是否撞墙或撞到自身,即是否还有生命{/*调出选择菜单*/if (!csnake->ChangeDirection()) //按Esc键时{int tmp = Menu();//绘制菜单,并得到返回值switch (tmp){case 1://继续游戏break;case 2://重新开始delete csnake;delete cfood;return 1;//将1作为PlayGame函数的返回值返回到Game函数中,表示重新开始case 3://退出游戏delete csnake;delete cfood;return 2;//将2作为PlayGame函数的返回值返回到Game函数中,表示退出游戏default:break;}}if (csnake->GetFood(*cfood)) //吃到食物{csnake->Move();//蛇增长UpdateScore(1);//更新分数,1为分数权重RewriteScore();//重新绘制分数cfood->DrawFood(*csnake);//绘制新食物}else{csnake->NormalMove();//蛇正常移动}if (csnake->GetBigFood(*cfood)) //吃到限时食物{csnake->Move();UpdateScore(cfood->GetProgressBar()/5);//分数根据限时食物进度条确定RewriteScore();}if (cfood->GetBigFlag()) //如果此时有限时食物,闪烁它{cfood->FlashBigFood();}Sleep(speed);//制造蛇的移动效果}/*蛇死亡*/delete csnake;//释放分配的内存空间delete cfood;int tmp = GameOver();//绘制游戏结束界面,并返回所选项switch (tmp){case 1:return 1;//重新开始case 2:return 2;//退出游戏default:return 2;}
}void Controller::UpdateScore(const int& tmp)//更新分数
{score += key * 10 * tmp;//所得分数根据游戏难度及传人的参数tmp确定
}void Controller::RewriteScore()//重绘分数
{/*为保持分数尾部对齐,将最大分数设置为6位,计算当前分数位数,将剩余位数用空格补全,再输出分数*/SetCursorPosition(37, 8);SetColor(11);int bit = 0;int tmp = score;while (tmp != 0){++bit;tmp /= 10;}for (int i = 0; i < (6 - bit); ++i){std::cout << " " ;}std::cout << score ;
}int Controller::Menu()//选择菜单
{/*绘制菜单*/SetColor(11);SetCursorPosition(32, 19);std::cout << "菜单:" ;Sleep(100);SetCursorPosition(34, 21);SetBackColor();std::cout << "继续游戏" ;Sleep(100);SetCursorPosition(34, 23);SetColor(11);std::cout << "重新开始" ;Sleep(100);SetCursorPosition(34, 25);std::cout << "退出游戏" ;SetCursorPosition(0, 31);/*选择部分*/int ch;int tmp_key = 1;bool flag = false;while ((ch = getch())){switch (ch){case 72://UPif (tmp_key > 1){switch (tmp_key){case 2:SetCursorPosition(34, 21);SetBackColor();std::cout << "继续游戏" ;SetCursorPosition(34, 23);SetColor(11);std::cout << "重新开始" ;--tmp_key;break;case 3:SetCursorPosition(34, 23);SetBackColor();std::cout << "重新开始" ;SetCursorPosition(34, 25);SetColor(11);std::cout << "退出游戏" ;--tmp_key;break;}}break;case 80://DOWNif (tmp_key < 3){switch (tmp_key){case 1:SetCursorPosition(34, 23);SetBackColor();std::cout << "重新开始" ;SetCursorPosition(34, 21);SetColor(11);std::cout << "继续游戏" ;++tmp_key;break;case 2:SetCursorPosition(34, 25);SetBackColor();std::cout << "退出游戏" ;SetCursorPosition(34, 23);SetColor(11);std::cout << "重新开始" ;++tmp_key;break;}}break;case 13://Enterflag = true;break;default:break;}if (flag){break;}SetCursorPosition(0, 31);}if (tmp_key == 1) //选择继续游戏,则将菜单擦除{SetCursorPosition(32, 19);std::cout << "      " ;SetCursorPosition(34, 21);std::cout << "        ";SetCursorPosition(34, 23);std::cout << "        ";SetCursorPosition(34, 25);std::cout << "        ";}return tmp_key;
}void Controller::Game()//游戏一级循环
{Start();//开始界面while (true)//游戏可视为一个死循环,直到退出游戏时循环结束{Select();//选择界面DrawGame();//绘制游戏界面int tmp = PlayGame();//开启游戏循环,当重新开始或退出游戏时,结束循环并返回值给tmpif (tmp == 1) //返回值为1时重新开始游戏{system("cls");continue;}else if (tmp == 2) //返回值为2时退出游戏{break;}else{break;}}
}int Controller::GameOver()//游戏结束界面
{/*绘制游戏结束界面*/Sleep(500);SetColor(11);SetCursorPosition(10, 8);std::cout << "━━━━━━━━━━━━━━━━━━━━━━" ;Sleep(30);SetCursorPosition(9, 9);std::cout << " ┃               Game Over !!!              ┃" ;Sleep(30);SetCursorPosition(9, 10);std::cout << " ┃                                          ┃" ;Sleep(30);SetCursorPosition(9, 11);std::cout << " ┃              很遗憾!你挂了              ┃" ;Sleep(30);SetCursorPosition(9, 12);std::cout << " ┃                                          ┃" ;Sleep(30);SetCursorPosition(9, 13);std::cout << " ┃             你的分数为:                 ┃" ;SetCursorPosition(24, 13);std::cout << score ;Sleep(30);SetCursorPosition(9, 14);std::cout << " ┃                                          ┃" ;Sleep(30);SetCursorPosition(9, 15);std::cout << " ┃   是否再来一局?                         ┃" ;Sleep(30);SetCursorPosition(9, 16);std::cout << " ┃                                          ┃" ;Sleep(30);SetCursorPosition(9, 17);std::cout << " ┃                                          ┃" ;Sleep(30);SetCursorPosition(9, 18);std::cout << " ┃    嗯,好的        不了,还是学习有意思  ┃" ;Sleep(30);SetCursorPosition(9, 19);std::cout << " ┃                                          ┃" ;Sleep(30);SetCursorPosition(9, 20);std::cout << " ┃                                          ┃" ;Sleep(30);SetCursorPosition(10, 21);std::cout << "━━━━━━━━━━━━━━━━━━━━━━" ;Sleep(100);SetCursorPosition(12, 18);SetBackColor();std::cout << "嗯,好的" ;SetCursorPosition(0, 31);/*选择部分*/int ch;int tmp_key = 1;bool flag = false;while ((ch = getch())){switch (ch){case 75://LEFTif (tmp_key > 1){SetCursorPosition(12, 18);SetBackColor();std::cout << "嗯,好的" ;SetCursorPosition(20, 18);SetColor(11);std::cout << "不了,还是学习有意思" ;--tmp_key;}break;case 77://RIGHTif (tmp_key < 2){SetCursorPosition(20, 18);SetBackColor();std::cout << "不了,还是学习有意思" ;SetCursorPosition(12, 18);SetColor(11);std::cout << "嗯,好的" ;++tmp_key;}break;case 13://Enterflag = true;break;default:break;}SetCursorPosition(0, 31);if (flag) {break;}}SetColor(11);switch (tmp_key){case 1:return 1;//重新开始case 2:return 2;//退出游戏default:return 1;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571

food.h

#ifndef FOOD_H
#define FOOD_H#include "snake.h"
class Snake;
class Food
{
public:Food() : cnt(0), flash_flag(false), big_flag(false), x(0), y(0), big_x(0), big_y(0), progress_bar(0) {}void DrawFood(Snake&);void DrawBigFood(Snake&);int GetCnt();void FlashBigFood();bool GetBigFlag();int GetProgressBar();
private:int cnt;bool flash_flag;//闪烁标记bool big_flag;//是否有限时食物标记int x, y;int big_x, big_y;int progress_bar;//限时食物进度条friend class Snake;
};
#endif // FOOD_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

food.cpp

#include "food.h"
#include "tools.h"
#include <cstdlib>
#include <iostream>void Food::DrawFood(Snake& csnake)//绘制食物
{/*利用rand函数获得坐标,并将其范围限制在2-29内,即在地图内,如果获得的坐标与蛇身重叠,则重新获取。同时每5颗食物就出现一颗限时食物*/while (true){int tmp_x = rand() % 30;int tmp_y = rand() % 30;if(tmp_x < 2) tmp_x += 2;if(tmp_y < 2) tmp_y += 2;bool flag = false;for (auto& point : csnake.snake){if ((point.GetX() == tmp_x && point.GetY() == tmp_y) || (tmp_x == big_x && tmp_y == big_y)) {flag = true;break;}}if (flag)continue;x = tmp_x;y = tmp_y;SetCursorPosition(x, y);SetColor(13);std::cout << "★" ;++cnt;cnt %= 5;if (cnt == 0){DrawBigFood(csnake);}break;}
}void Food::DrawBigFood(Snake& csnake)//绘制限时食物
{SetCursorPosition(5, 0);SetColor(11);std::cout << "------------------------------------------" ;//进度条progress_bar = 42;while (true){int tmp_x = rand() % 30;int tmp_y = rand() % 30;if(tmp_x < 2) tmp_x += 2;if(tmp_y < 2) tmp_y += 2;bool flag = false;for (auto& point : csnake.snake){if ((point.GetX() == tmp_x && point.GetY() == tmp_y) || (tmp_x == x && tmp_y == y)){flag = true;break;}}if (flag)continue;big_x = tmp_x;big_y = tmp_y;SetCursorPosition(big_x, big_y);SetColor(18);std::cout << "■" ;big_flag = true;flash_flag = true;break;}
}int Food::GetCnt()
{return cnt;
}void Food::FlashBigFood()//闪烁限时食物
{SetCursorPosition(big_x, big_y);SetColor(18);if (flash_flag){std::cout << "  " ;flash_flag = false;}else{std::cout << "■" ;flash_flag = true;}SetCursorPosition(26, 0);SetColor(11);for (int i = 42; i >= progress_bar; --i)//进度条缩短std::cout << "\b \b" ;--progress_bar;if (progress_bar == 0) {SetCursorPosition(big_x, big_y);std::cout << "  " ;big_flag = false;big_x = 0;big_y = 0;}
}bool Food::GetBigFlag()
{return big_flag;
}int Food::GetProgressBar()
{return progress_bar;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119

map.h

#ifndef MAP_H
#define MAP_H#include <vector>
#include "point.h"

class Map
{
public:Map()//默认构造函数,将正方形各点压入initmap{initmap.emplace_back(Point(1, 1));initmap.emplace_back(Point(2, 1));initmap.emplace_back(Point(3, 1));initmap.emplace_back(Point(4, 1));initmap.emplace_back(Point(5, 1));initmap.emplace_back(Point(6, 1));initmap.emplace_back(Point(7, 1));initmap.emplace_back(Point(8, 1));initmap.emplace_back(Point(9, 1));initmap.emplace_back(Point(10, 1));initmap.emplace_back(Point(11, 1));initmap.emplace_back(Point(12, 1));initmap.emplace_back(Point(13, 1));initmap.emplace_back(Point(14, 1));initmap.emplace_back(Point(15, 1));initmap.emplace_back(Point(16, 1));initmap.emplace_back(Point(17, 1));initmap.emplace_back(Point(18, 1));initmap.emplace_back(Point(19, 1));initmap.emplace_back(Point(20, 1));initmap.emplace_back(Point(21, 1));initmap.emplace_back(Point(22, 1));initmap.emplace_back(Point(23, 1));initmap.emplace_back(Point(24, 1));initmap.emplace_back(Point(25, 1));initmap.emplace_back(Point(26, 1));initmap.emplace_back(Point(27, 1));initmap.emplace_back(Point(28, 1));initmap.emplace_back(Point(29, 1));initmap.emplace_back(Point(30, 1));initmap.emplace_back(Point(1, 2));initmap.emplace_back(Point(30, 2));initmap.emplace_back(Point(1, 3));initmap.emplace_back(Point(30, 3));initmap.emplace_back(Point(1, 4));initmap.emplace_back(Point(30, 4));initmap.emplace_back(Point(1, 5));initmap.emplace_back(Point(30, 5));initmap.emplace_back(Point(1, 6));initmap.emplace_back(Point(30, 6));initmap.emplace_back(Point(1, 7));initmap.emplace_back(Point(30, 7));initmap.emplace_back(Point(1, 8));initmap.emplace_back(Point(30, 8));initmap.emplace_back(Point(1, 9));initmap.emplace_back(Point(30, 9));initmap.emplace_back(Point(1, 10));initmap.emplace_back(Point(30, 10));initmap.emplace_back(Point(1, 11));initmap.emplace_back(Point(30, 11));initmap.emplace_back(Point(1, 12));initmap.emplace_back(Point(30, 12));initmap.emplace_back(Point(1, 13));initmap.emplace_back(Point(30, 13));initmap.emplace_back(Point(1, 14));initmap.emplace_back(Point(30, 14));initmap.emplace_back(Point(1, 15));initmap.emplace_back(Point(30, 15));initmap.emplace_back(Point(1, 16));initmap.emplace_back(Point(30, 16));initmap.emplace_back(Point(1, 17));initmap.emplace_back(Point(30, 17));initmap.emplace_back(Point(1, 18));initmap.emplace_back(Point(30, 18));initmap.emplace_back(Point(1, 19));initmap.emplace_back(Point(30, 19));initmap.emplace_back(Point(1, 20));initmap.emplace_back(Point(30, 20));initmap.emplace_back(Point(1, 21));initmap.emplace_back(Point(30, 21));initmap.emplace_back(Point(1, 22));initmap.emplace_back(Point(30, 22));initmap.emplace_back(Point(1, 23));initmap.emplace_back(Point(30, 23));initmap.emplace_back(Point(1, 24));initmap.emplace_back(Point(30, 24));initmap.emplace_back(Point(1, 25));initmap.emplace_back(Point(30, 25));initmap.emplace_back(Point(1, 26));initmap.emplace_back(Point(30, 26));initmap.emplace_back(Point(1, 27));initmap.emplace_back(Point(30, 27));initmap.emplace_back(Point(1, 28));initmap.emplace_back(Point(30, 28));initmap.emplace_back(Point(1, 29));initmap.emplace_back(Point(30, 29));initmap.emplace_back(Point(1, 30));initmap.emplace_back(Point(2, 30));initmap.emplace_back(Point(3, 30));initmap.emplace_back(Point(4, 30));initmap.emplace_back(Point(5, 30));initmap.emplace_back(Point(6, 30));initmap.emplace_back(Point(7, 30));initmap.emplace_back(Point(8, 30));initmap.emplace_back(Point(9, 30));initmap.emplace_back(Point(10, 30));initmap.emplace_back(Point(11, 30));initmap.emplace_back(Point(12, 30));initmap.emplace_back(Point(13, 30));initmap.emplace_back(Point(14, 30));initmap.emplace_back(Point(15, 30));initmap.emplace_back(Point(16, 30));initmap.emplace_back(Point(17, 30));initmap.emplace_back(Point(18, 30));initmap.emplace_back(Point(19, 30));initmap.emplace_back(Point(20, 30));initmap.emplace_back(Point(21, 30));initmap.emplace_back(Point(22, 30));initmap.emplace_back(Point(23, 30));initmap.emplace_back(Point(24, 30));initmap.emplace_back(Point(25, 30));initmap.emplace_back(Point(26, 30));initmap.emplace_back(Point(27, 30));initmap.emplace_back(Point(28, 30));initmap.emplace_back(Point(29, 30));initmap.emplace_back(Point(30, 30));}void PrintInitmap();//绘制初始地图
private:std::vector<Point> initmap;//保存初始地图/*Map类可自定义多种地图,只需将表示地图的各个点保存在相应的map中,并在Snake类中增加相应判断撞墙函数即可std::vector<Point> map1;std::vector<Point> map2;*/
};
#endif // MAP_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137

map.cpp

#include "map.h"
#include <windows.h>void Map::PrintInitmap()//绘制初始地图
{for (auto& point : initmap){point.Print();Sleep(10);//调用Sleep函数可营造动画效果}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

point.h

#ifndef POINT_H
#define POINT_Hclass Point
{
public:Point(){}Point(const int x, const int y) : x(x), y(y) {}void Print();void PrintCircular();void Clear();void ChangePosition(const int x, const int y);bool operator== (const Point& point) { return (point.x == this->x) && (point.y == this->y); }int GetX(){ return this->x; }int GetY(){ return this->y; }
private:int x, y;
};
#endif // POINT_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

point.cpp

#include "point.h"
#include "tools.h"
#include <iostream>void Point::Print()//输出方块
{SetCursorPosition(x, y);std::cout << "■" ;
}void Point::PrintCircular()//输出圆形
{SetCursorPosition(x, y);std::cout << "●" ;
}void Point::Clear()//清除输出
{SetCursorPosition(x, y);std::cout << "  " ;
}void Point::ChangePosition(const int x, const int y)//改变坐标
{this->x = x;this->y = y;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

snake.h

#ifndef SNAKE_H
#define SNAKE_H#include <deque>
#include "point.h"
#include "food.h"class Food;
class Snake
{
public:enum Direction {UP, DOWN, LEFT, RIGHT};Snake() {snake.emplace_back(14, 8);snake.emplace_back(15, 8);snake.emplace_back(16, 8);direction = Direction::DOWN;}void InitSnake();void Move();void NormalMove();bool OverEdge();bool HitItself();bool ChangeDirection();bool GetFood(const Food&);bool GetBigFood(Food&);
private:std::deque<Point> snake;Direction direction;friend class Food;//将Food类置为友元,以便访问其私有元素
};
#endif // SNAKE_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

snake.cpp

#include "snake.h"
#include <conio.h>
#include "tools.h"
#include <iostream>void Snake::InitSnake()//初始化蛇
{for (auto& point : snake){point.PrintCircular();}
}void Snake::Move()//蛇增长
{switch (direction){case Direction::UP:snake.emplace_back(Point(snake.back().GetX(), snake.back().GetY() - 1 ));break;case Direction::DOWN:snake.emplace_back(Point(snake.back().GetX(), snake.back().GetY() + 1 ));break;case Direction::LEFT:snake.emplace_back(Point(snake.back().GetX() - 1, snake.back().GetY() ));break;case Direction::RIGHT:snake.emplace_back(Point(snake.back().GetX() + 1, snake.back().GetY() ));break;default:break;}SetColor(14);snake.back().PrintCircular();
}void Snake::NormalMove()//蛇正常移动,头增长,尾缩短
{Move();snake.front().Clear();snake.pop_front();
}bool Snake::OverEdge()//超出边界
{return snake.back().GetX() < 30 &&snake.back().GetY() < 30 &&snake.back().GetX() > 1  &&snake.back().GetY() > 1;
}bool Snake::HitItself()//撞到自身
{std::deque<Point>::size_type cnt = 1;Point *head = new Point(snake.back().GetX(), snake.back().GetY());//获得头部坐标for (auto& point : snake) //如果整条蛇中与蛇头不相同的坐标不等于蛇长,则意味着蛇头碰撞到自身{if ( !(point == *head) )++cnt;elsebreak;}delete head;if(cnt == snake.size())return true;elsereturn false;
}bool Snake::ChangeDirection()//改变方向
{char ch;if (kbhit())//kbhit函数返回值为两个,需注意{ch = getch();switch (ch){case -32:ch = getch();switch (ch){case 72:if (direction != Direction::DOWN)//如果方向与当前运动方向相反,无效direction = Direction::UP;break;case 80:if (direction != Direction::UP)direction = Direction::DOWN;break;case 75:if (direction != Direction::RIGHT)direction = Direction::LEFT;break;case 77:if (direction != Direction::LEFT)direction = Direction::RIGHT;break;default:break;}return true;case 27://ESCreturn false;default:return true;}}return true;
}bool Snake::GetFood(const Food& cfood)
{if (snake.back().GetX() == cfood.x && snake.back().GetY() == cfood.y)return true;elsereturn false;
}bool Snake::GetBigFood(Food& cfood)
{if (snake.back().GetX() == cfood.big_x && snake.back().GetY() == cfood.big_y){cfood.big_flag = false;cfood.big_x = 0;cfood.big_y = 0;SetCursorPosition(1, 0);std::cout << "                                                            " ;return true;}elsereturn false;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135

startinterface.h

#ifndef STRATINTERFACE_H
#define STARTINTERFACE_H#include <deque>
#include <vector>
#include "point.h"

class StartInterface
{
public:StartInterface() : speed(35) {startsnake.emplace_back(Point(0,14));//Éßstartsnake.emplace_back(Point(1,14));startsnake.emplace_back(Point(2,15));startsnake.emplace_back(Point(3,16));startsnake.emplace_back(Point(4,17));startsnake.emplace_back(Point(5,18));startsnake.emplace_back(Point(6,17));startsnake.emplace_back(Point(7,16));startsnake.emplace_back(Point(8,15));startsnake.emplace_back(Point(9,14));textsnake.emplace_back(Point(-26, 14));//Stextsnake.emplace_back(Point(-25, 14));textsnake.emplace_back(Point(-27, 15));textsnake.emplace_back(Point(-26, 16));textsnake.emplace_back(Point(-25, 17));textsnake.emplace_back(Point(-27, 18));textsnake.emplace_back(Point(-26, 18));textsnake.emplace_back(Point(-23, 14));//Ntextsnake.emplace_back(Point(-23, 15));textsnake.emplace_back(Point(-23, 16));textsnake.emplace_back(Point(-23, 17));textsnake.emplace_back(Point(-23, 18));textsnake.emplace_back(Point(-22, 15));textsnake.emplace_back(Point(-21, 16));textsnake.emplace_back(Point(-20, 17));textsnake.emplace_back(Point(-19, 14));textsnake.emplace_back(Point(-19, 15));textsnake.emplace_back(Point(-19, 16));textsnake.emplace_back(Point(-19, 17));textsnake.emplace_back(Point(-19, 18));textsnake.emplace_back(Point(-17, 18));//Atextsnake.emplace_back(Point(-16, 17));textsnake.emplace_back(Point(-15, 16));textsnake.emplace_back(Point(-14, 15));textsnake.emplace_back(Point(-14, 16));textsnake.emplace_back(Point(-13, 14));textsnake.emplace_back(Point(-13, 16));textsnake.emplace_back(Point(-12, 15));textsnake.emplace_back(Point(-12, 16));textsnake.emplace_back(Point(-11, 16));textsnake.emplace_back(Point(-10, 17));textsnake.emplace_back(Point(-9, 18));textsnake.emplace_back(Point(-7, 14));//Ktextsnake.emplace_back(Point(-7, 15));textsnake.emplace_back(Point(-7, 16));textsnake.emplace_back(Point(-7, 17));textsnake.emplace_back(Point(-7, 18));textsnake.emplace_back(Point(-6, 16));textsnake.emplace_back(Point(-5, 15));textsnake.emplace_back(Point(-5, 17));textsnake.emplace_back(Point(-4, 14));textsnake.emplace_back(Point(-4, 18));textsnake.emplace_back(Point(-2, 14));//Etextsnake.emplace_back(Point(-2, 15));textsnake.emplace_back(Point(-2, 16));textsnake.emplace_back(Point(-2, 17));textsnake.emplace_back(Point(-2, 18));textsnake.emplace_back(Point(-1, 14));textsnake.emplace_back(Point(-1, 16));textsnake.emplace_back(Point(-1, 18));textsnake.emplace_back(Point(0, 14));textsnake.emplace_back(Point(0, 16));textsnake.emplace_back(Point(0, 18));}void PrintFirst();void PrintSecond();void PrintThird();void PrintText();void ClearText();void Action();
private:std::deque<Point> startsnake;//开始动画中的蛇std::vector<Point> textsnake;//开始动画中的文字int speed;//动画的速度
};
#endif // STRATINTERFACE_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92

startinterface.cpp

#include "startinterface.h"
#include <windows.h>void StartInterface::PrintFirst()//蛇从左边出现到完全出现的过程
{for (auto& point : startsnake){point.Print();Sleep(speed);}
}void StartInterface::PrintSecond()//蛇从左向右移动的过程
{for (int i = 10; i != 40; ++i) //蛇头需要从10移动到40{/*计算蛇头的下一个位置,并将其压入startsnake中,绘制出来,将蛇尾去掉*/int j = ( ((i-2)%8) < 4 )?( 15 + (i-2)%8 ) : ( 21 - (i-2)%8 );startsnake.emplace_back( Point(i, j) );startsnake.back().Print();startsnake.front().Clear();startsnake.pop_front();Sleep(speed);}
}void StartInterface::PrintThird()//蛇从接触右边到消失的过程
{while ( !startsnake.empty() || textsnake.back().GetX() < 33 ) //当蛇还没消失或文字没移动到指定位置{if ( !startsnake.empty() ) //如果蛇还没消失,继续移动{startsnake.front().Clear();startsnake.pop_front();}ClearText();//清除已有文字PrintText();//绘制更新位置后的文字Sleep(speed);}
}void StartInterface::PrintText()
{for (auto& point : textsnake){if (point.GetX() >= 0)point.Print();}
}void StartInterface::ClearText()
{for (auto& point : textsnake) //清除的同时将文字整体向右移动一格{if (point.GetX() >= 0)point.Clear();point.ChangePosition(point.GetX() + 1, point.GetY());}
}void StartInterface::Action()
{PrintFirst();PrintSecond();PrintThird();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

tools.h

#ifndef TOOLS_H
#define TOOLS_Hvoid SetWindowSize(int cols, int lines);
void SetCursorPosition(const int x, const int y);
void SetColor(int colorID);
void SetBackColor();#endif // TOOLS_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

tools.cpp

#include "tools.h"
#include <windows.h>
#include <stdio.h>void SetWindowSize(int cols, int lines)//设置窗口大小
{system("title 贪吃蛇");//设置窗口标题char cmd[30];sprintf(cmd, "mode con cols=%d lines=%d", cols * 2, lines);//一个图形■占两个字符,故宽度乘以2system(cmd);//system(mode con cols=88 lines=88)设置窗口宽度和高度
}void SetCursorPosition(const int x, const int y)//设置光标位置
{ COORD position;position.X = x * 2;position.Y = y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);
}void SetColor(int colorID)//设置文本颜色
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colorID);
}void SetBackColor()//设置文本背景色
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED );
}

C++控制台贪吃蛇小游戏详细教程相关推荐

  1. 【C++】经典项目控制台贪吃蛇小游戏详细教程

    [小游戏]贪吃蛇GreedySnake 本文将讲解如何使用c++面向对象方法编写控制台版贪吃蛇小游戏 项目github地址:游戏源码链接 游戏下载:GreedySnake 本人属初学者,水平所限,难免 ...

  2. [娱乐]一款浅陋的C++控制台贪吃蛇小游戏

    因为时间有限,没能尽可能完善这一款贪吃蛇,不过能做出来还是很有意思的 1 #include<bits/stdc++.h> 2 #include<windows.h> 3 #in ...

  3. 基于stm32、0.96寸OLED实现的贪吃蛇小游戏(详细源码注释)

    简介:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的贪吃蛇小游戏.项目源码地址:点击下载. 硬件设计: 普通摇杆,0.96寸OLED 单色屏幕(SPI协议通讯), ...

  4. python的pygame库使用方法_python基础教程使用Python第三方库pygame写个贪吃蛇小游戏...

    今天看到几个关于pygame模块的博客和视频,感觉非常有趣,这里照猫画虎写了一个贪吃蛇小游戏,目前还有待完善,但是基本游戏功能已经实现,下面是代码: # 导入模块 import pygame impo ...

  5. 蘑菇云「行空板Python入门教程」第六课:贪吃蛇小游戏

    在很久很久以前,手机屏幕都还是黑白的年代,有一款叫做"贪吃蛇"的游戏风靡了大街小巷,在那分辨率极低的屏幕上,几条扭扭曲曲的弧线似乎穿越了整个童年. 这节课上,就让我们用行空板来实现 ...

  6. Golang 控制台百行代码贪吃蛇小游戏

    Golang 并不适合在前端工作,缺少强大的图形图像包和硬件加速包,更适合做成后台服务程序.本文的贪吃蛇小游戏运行与控制台上,其中调用了Window系统kernel32.dll中控制台相关的函数. 项 ...

  7. STM32F407基于陀螺仪的贪吃蛇小游戏(全网最详细)

    一.前言 本次设计我用MPU6050在KEIL 5的环境下改进了贪吃蛇小游戏,用的开发板是STM32F407,本次设计综合利用多种ARM外设接口实现对外部设备信息的采集.处理及显示,实现了贪吃蛇游戏实 ...

  8. JavaScript 进阶教程(2)---面向对象实战之贪吃蛇小游戏

    目录 1 引言 2 游戏地图 3 游戏对象 3.1 食物对象 3.2 小蛇对象 3.3 游戏对象 4 游戏的逻辑 4.1小蛇的移动 4.2 让蛇自己动起来 4.2.1 自动移动 4.2.2 自调用函数 ...

  9. 控制台版贪吃蛇小游戏 C语言

    写在前面 最近我们C语言的课设快开始了,开始前刚好有时间就写了一下C语言的贪吃蛇小游戏(单链表实现),包含了经典模式和无边界模式 ,网上查了设置颜色 和 改变光标位置 还有 用方向键控制 的函数,第一 ...

最新文章

  1. Linux 命令之 eval -- 对参数执行两次解释
  2. listview的item中嵌套多个EditText时的问题
  3. Tensorflow安装错误ERROR: Cannot uninstall ‘wrapt‘.
  4. 用户研究三部曲:有关用户研究的战略思考
  5. git报错之fatal: protocol error: bad line length character: No This
  6. 如何将外置显示器与 Mac 搭配使用?
  7. 微软推出的在线代码查看神器github1s
  8. 信息熵、互信息、KL散度
  9. 小程序菜鸟的父子组件传值、父子组件方法调用的学习
  10. 读书笔记 摘自:《斯坦福极简经济学》
  11. Arduino基础学习-SG90舵机的使用
  12. 学习ximo脱壳视频:2、手脱ASPACK壳
  13. Nginx 使用 ngx_http_mirror_module 模块 复制 http请求流量
  14. ConcurrentHashMap的锁
  15. 从administrators组中删除guest来宾账户时提示无法在内置账号上运行此操作的解决办法...
  16. AXURE 手机尺寸设置
  17. 纯净安装 Windows 11 官方原版系统的方法图解(适用强迫症患者)
  18. 【WLAN】Android 13 p2p / wifi direct介绍
  19. 华为搜索引擎问世!互联网格局将改写?
  20. cuda无法使用nvprof命令,找不到cupti64_2021_3.0.dll

热门文章

  1. 【智能优化算法-倭黑猩猩算法】基于倭黑猩猩优化算法求解多目标优化问题附matlab代码
  2. 开源AI迷你版apache
  3. Luat Inside | 多功能YAP物联网终端机,你不会还不知道吧?
  4. PAT乙级 1070 结绳 python
  5. 移动端开发案例(Bootstrap布局,响应式开发)
  6. 组合模式-Composite Pattern
  7. Thinking-in-Java 读书笔记-11-持有对象
  8. 路由器恢复出厂设置上网方式服务器无响应,路由器恢复出厂设置后不能联网了如何解决...
  9. 华为校园招聘笔试题(机考题目)
  10. javaGUI绘图频闪