(所用编译器vs2013)
#include"stdafx.h" #include"windows.h" #include"conio.h" #include"time.h" #include<iostream> #include<list> using namespace std; class point { public: point(); point(int m_x, int m_y) { x = m_x; y = m_y; } int getx() { return x; } int gety() { return y; } int x, y; }; list<point> snake; int x_food, y_food; enum Direction{UP,DOWN,LEFT,RIGHT}; Direction direction = DOWN; bool alive(); void changeDirecion(); void initSnake();//初始化蛇的坐标 void setWindowSize(int x, int y); void drawWelcome(); void setCursorPosition(int x, int y); //设置光标的位置 void hideCursor(); //隐藏光标 void createFood(); //产生食物 void Move(); void add(); bool eatfood();//判断是否吃到食物; int _tmain(int argc, _TCHAR* argv[]) { int speed = 230,count=0; //speed和count用于改变速度 srand(time_t(0));//设置随机数种子 setWindowSize(32, 32); hideCursor(); drawWelcome(); initSnake(); createFood(); while (alive()) { changeDirecion(); if (eatfood()) { add(); createFood(); count++; if (speed > 80 && count%5==0) //每吃五个食物改变一次速度 speed -= 50; } else Move(); Sleep(speed); } setCursorPosition(12,14); cout << "Game Over !!!"; setCursorPosition(6, 16); cout << "Thanks for playing Snake,see you next time."; return 0; } void initSnake()//初始化蛇的坐标 { system("cls"); snake.push_back(point(3, 3)); snake.push_back(point(4, 3)); snake.push_back(point(5, 3)); for (auto&p : snake) { setCursorPosition(p.getx(), p.gety()); cout << "●"; } } void setWindowSize(int x, int y) { //设置控制台窗口标题 system("title Snake"); //设置窗口大小 char cmd[30]; //标准化写入cdm数组 x*2为了显示为正方形这样高度和宽度一致(单个字符高度占比两个字节宽,所以宽度乘2) sprintf_s(cmd, "mode con cols=%d lines=%d", x * 2, y); //如果编译器为vs请将sprintf改为sprintf_s //运行cmd system(cmd); } void drawWelcome() { setCursorPosition(12, 16); cout << "Welcome to Snake "; setCursorPosition(10, 18); cout << "Press any key to start....."; setCursorPosition(12, 20); cout << "(操作键:方向键)"; getchar(); } void setCursorPosition(int x, int y) //设置光标的位置 { COORD position; position.X = 2 * x; //乘2为了满足前面的显示正方形 position.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position); } void hideCursor() //隐藏光标 { //设置光标厚度为1%,不可见 CONSOLE_CURSOR_INFO cursor_info = { 1, false }; //设置光标信息 GetStdHandle 获得缓冲句柄 由于SetConsoleCursorInfo第二个参数为一个指针,所以利用& SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); } void createFood() //产生食物 { while (true) //防止食物产生在蛇身上 { x_food = rand() % 32; y_food = rand() % 32; for (auto & p : snake) { if (x_food == p.getx() && y_food == p.gety()) continue; } break; } setCursorPosition(x_food, y_food); //画食物 cout << "★"; } void Move() { add(); setCursorPosition(snake.front().getx(), snake.front().gety()); cout << " "; snake.pop_front(); } void add() { switch (direction) { case UP: //超上走蛇的正上方加一个,蛇尾去掉一个 snake.emplace_back(point(snake.back().getx(), snake.back().gety() - 1)); break; case DOWN://向下走,正下方加一个,先清除屏幕蛇尾的显示,再去掉链表的头结点 snake.emplace_back(point(snake.back().getx(), snake.back().gety() + 1)); break; case LEFT://向左走,正左方加一个,先清除屏幕蛇尾的显示,再去掉链表的头结点 snake.emplace_back(point(snake.back().getx() - 1, snake.back().gety())); break; case RIGHT://向右走,正右方加一个,先清除屏幕蛇尾的显示,再去掉链表的头结点 snake.emplace_back(point(snake.back().getx() + 1, snake.back().gety())); break; default: break; } setCursorPosition(snake.back().getx(), snake.back().gety()); cout << "●"; } bool eatfood()//判断是否吃到食物 { if (snake.back().getx() == x_food && snake.back().gety() == y_food) { return true; } return false; } bool alive() { if (snake.back().getx()<0 || snake.back().getx()>32 || snake.back().gety()<0 || snake.back().gety()>32) //判断是否撞墙 return false; point P = snake.back(); int count = 0; for (auto & p : snake) //判断是否吃到自己 { if (p.getx() == P.getx() && p.gety() == P.gety()) count++; } if (count > 1) return false; return true; } void changeDirecion() { char ch;//存结果 _kbhit()不按键不返回,getch()必须按一个值待返回 (卡住,阻塞) ,kbhit()判断是否按键比getch更好 if (_kbhit()) //如果按下键则返回非零的值,没有按下则返回零 { ch = _getch(); //获取按的键是什么 switch (ch) { case -32: //方向键 ch = _getch(); switch (ch) { case 72://上键 if (direction != DOWN) //蛇超下时不可以向上走 direction = UP; break; case 80://下键 if (direction != UP) direction = DOWN; break; case 75://左 if (direction != RIGHT) direction = LEFT; break; case 77://右 if (direction != LEFT) direction = RIGHT; break; default: break; } } } }