以下总结,在此次项目中遇到的问题以及解决方法:
控制台 显示设置:
#include <windows.h>
//void pf(int x, int y, const char & ch) // X坐标, y坐标, 输出的字符
//{
// HANDLE two = GetStdHandle(STD_OUTPUT_HANDLE); //取得输出句柄
// 还有别的两种句柄 输入:STD_INPUT_HANDLE, 错误流:STD_ERROR_HANDLE
// COORD coor; //定义一个控制台光标坐标变量
// coor.X = x; //给光标的X赋值
// coor.Y = y; //给光标的y赋值
// SetConsoleCursorPosition(two,coor); //传给修改函数修改
// cout << ch;
//}
//
//void hideCur()
//{
// HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); //取得输出句柄
// CONSOLE_CURSOR_INFO cur; 定义一个光标信息结构体
// cur.bVisible = FALSE; //光标可见性
// cur.dwSize = 1; //光标宽度
// SetConsoleCursorInfo(h,&cur); //设置信息到控制台
//}
数据类型:
//size_t a = 2222; //无符号64位
//cout << a;
//快捷功能:
//1,F12跳转到定义 ctrl + Shift + 8可以跳转回来
//F5启动调试
//F9 增加删除断点
//F10 单步调试
//F11 逐语句调试 进入所有函数
//F10 逐过程调试 不进入函数
//Shift + F5 停止调试
//F5 继续
Vector:
#include <vector>
/*vector<int>num; //迭代器的使用
num.push_back(1);
num.push_back(2);
num.push_back(3);
num.push_back(4);
vector<int>::iterator itr = num.begin();
int i = -1;
for(itr; itr != num.end(); itr ++)
{
i ++;
}
cout << i;*/
//释放vector新技能get
//vector<type>.swap(yourVector) //释放vector的内存 clear做不到的
键盘:
#include <conio>
//kbhit() //检测键盘是否按下
getch()//获得键盘按键不回显
需要两个getch() 才能接收到方向键盘的值 但是 除了方向键盘 别的键只需一个getch()就能完成接收 解决办法:
char ch;
ch = getch();
if(ch != KEY_ENTER) //回车一个getch()可以完成接受回车键,但是方向键需要两个getch()完成接受
{
ch = getch();
}
宏定义 一个[a,b) 之间的随机数:
#define R(a,b) (int)(((double)rand()/RAND_MAX)*((b)-(a)) + (a))
代码如下:
sn.h
#ifndef SN_H_ #define SN_H_ #include <string> #include <vector> #include <Windows.h> #include <conio.h> #include <iostream> #include <string> #define R(a,b) (int)(((double)rand()/RAND_MAX)*((b)-(a)) + (a)) #define KNOCKED_WALL 0 #define KNOCKED_FOOD 1 #define KNOCKED_NOTHING 2; #define KEY_UP 72 #define KEY_RIGHT 77 #define KEY_DOWN 80 #define KEY_LEFT 75 #define KEY_ENTER 13 #define MENUCHA "→" #define SNAHEAD "H" #define SNABODY "b" #define FOODS "f" struct sna_body { <span style="white-space:pre"> </span>int x; <span style="white-space:pre"> </span>int y; <span style="white-space:pre"> </span>int col; <span style="white-space:pre"> </span>char *ch; <span style="white-space:pre"> </span>sna_body(int x, int y, int col, char *ch) <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>this->x = x; <span style="white-space:pre"> </span>this->y = y; <span style="white-space:pre"> </span>this->col = col; <span style="white-space:pre"> </span>this->ch = new char[strlen(ch) + 1]; //深拷贝 <span style="white-space:pre"> </span>strcpy(this->ch,ch); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>~sna_body() <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>} }; struct coor_col { <span style="white-space:pre"> </span>int x; <span style="white-space:pre"> </span>int y; <span style="white-space:pre"> </span>int c; }; struct food { <span style="white-space:pre"> </span>int x; <span style="white-space:pre"> </span>int y; <span style="white-space:pre"> </span>int col; <span style="white-space:pre"> </span>char *ch; }; using namespace std; //格式类 class words { public : <span style="white-space:pre"> </span>//字体颜色,背景颜色 <span style="white-space:pre"> </span>void setColor(unsigned short ForeColor,unsigned short BackGroundColor = 0) const <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE); <span style="white-space:pre"> </span>SetConsoleTextAttribute(hCon,ForeColor|BackGroundColor); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>//光标大小&光标可见性 <span style="white-space:pre"> </span>void hideCursor(BOOL j = FALSE) const <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE); <span style="white-space:pre"> </span>CONSOLE_CURSOR_INFO cur; <span style="white-space:pre"> </span>cur.bVisible = j; <span style="white-space:pre"> </span>cur.dwSize = 1; <span style="white-space:pre"> </span>SetConsoleCursorInfo(hCon,&cur); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>//文字位置 <span style="white-space:pre"> </span>void wordsLoca(int x, int y) <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE); <span style="white-space:pre"> </span>COORD coor; <span style="white-space:pre"> </span>coor.X = x; <span style="white-space:pre"> </span>coor.Y = y; <span style="white-space:pre"> </span>SetConsoleCursorPosition(hCon,coor); <span style="white-space:pre"> </span>} }; //snak 类 class sna { private: <span style="white-space:pre"> </span>int nowKey; //当前按键 <span style="white-space:pre"> </span>int life; // 生命 <span style="white-space:pre"> </span>int greds; //成绩 <span style="white-space:pre"> </span>bool lifeBeenChange; <span style="white-space:pre"> </span>int snackSleepTime; //自动移动睡眠时间 <span style="white-space:pre"> </span>int singleSleepTime; <span style="white-space:pre"> </span>food f; <span style="white-space:pre"> </span>struct moveDir <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>int x; <span style="white-space:pre"> </span>int y; <span style="white-space:pre"> </span>}moveDir; <span style="white-space:pre"> </span>vector<sna_body> Snake; <span style="white-space:pre"> </span>words format; <span style="white-space:pre"> </span>//根据迭代器 获得下标; <span style="white-space:pre"> </span>int getLastoneIndex(); <span style="white-space:pre"> </span>//设置蛇的输出位置 颜色 <span style="white-space:pre"> </span>void setSnaFormat(sna_body s); <span style="white-space:pre"> </span>void printSna(); <span style="white-space:pre"> </span>//吃到食物 <span style="white-space:pre"> </span>void eatFood(); <span style="white-space:pre"> </span>//移动 <span style="white-space:pre"> </span>void move(); <span style="white-space:pre"> </span>//生成食物 <span style="white-space:pre"> </span>void buildFood(); <span style="white-space:pre"> </span>//输出食物 <span style="white-space:pre"> </span>void printFood(); <span style="white-space:pre"> </span>void autoMove(); <span style="white-space:pre"> </span>//碰撞检测 <span style="white-space:pre"> </span>int colider(); <span style="white-space:pre"> </span>bool cloider_self(); <span style="white-space:pre"> </span>void dieFlash(); <span style="white-space:pre"> </span>void gameOver(); public: <span style="white-space:pre"> </span>sna(sna_body s); <span style="white-space:pre"> </span>void getKey(); <span style="white-space:pre"> </span>void begin(); }; //界面类 class menu { private: <span style="white-space:pre"> </span>coor_col title; //标题 <span style="white-space:pre"> </span>coor_col start_1; //开始的项目符号 <span style="white-space:pre"> </span>coor_col start_2; //开始 <span style="white-space:pre"> </span>coor_col level_1; //等级 <span style="white-space:pre"> </span>coor_col level_2; //等级项目符号 <span style="white-space:pre"> </span>words format; //格式化对象 <span style="white-space:pre"> </span>int select_num; <span style="white-space:pre"> </span>//**************************************************************** <span style="white-space:pre"> </span>void confiFlash() ; <span style="white-space:pre"> </span>//设置title 坐标,颜色,内容 <span style="white-space:pre"> </span>void setTitle(const coor_col &a); <span style="white-space:pre"> </span>//设置start 坐标,颜色,内容 <span style="white-space:pre"> </span>void setStart(const coor_col &st_1, const coor_col &st_2); <span style="white-space:pre"> </span>//设置title 坐标,颜色,内容 <span style="white-space:pre"> </span>void setLevel(const coor_col &le_1, const coor_col &le_2) ; <span style="white-space:pre"> </span>//***************************************************************** <span style="white-space:pre"> </span>coor_col getTitle() const {return title;} <span style="white-space:pre"> </span>coor_col getLevel_1() const {return level_1;} <span style="white-space:pre"> </span>coor_col getLevel_2() const {return level_2;} <span style="white-space:pre"> </span>coor_col getStart_1() const {return start_1;} <span style="white-space:pre"> </span>coor_col getStart_2() const {return start_2;} <span style="white-space:pre"> </span>//******************************************************************* <span style="white-space:pre"> </span>void drawTitle(const string & str); <span style="white-space:pre"> </span>void drawStart(const char *ch, const string & str); <span style="white-space:pre"> </span>void drawLevel(const char *ch, const string & str) ; public: <span style="white-space:pre"> </span>menu();//构造函数 <span style="white-space:pre"> </span>int getSelectNum() const {return this->select_num;} <span style="white-space:pre"> </span>void select(); <span style="white-space:pre"> </span>void drawMenu(coor_col &format,coor_col &format_2); <span style="white-space:pre"> </span>void beginClean();//开始动画 }; #endif
SNACK.cpp
#include "sn.h" // class sna : sna::sna(sna_body s) //构造函数 { snackSleepTime = 500; singleSleepTime = 100; this->life = 100; this->greds = 0; this->lifeBeenChange = false; nowKey = KEY_RIGHT; //默认按键 向右 moveDir.x = s.x; moveDir.y = s.y; sna_body head = s; sna_body head1(s.x-1,s.y,3,SNABODY); sna_body head2(head1.x-1,head1.y,head1.col,head1.ch); Snake.push_back(head); Snake.push_back(head1); Snake.push_back(head2); this->printSna(); this->buildFood(); } int sna::getLastoneIndex() { int i = -1; vector<sna_body>::iterator itr = Snake.begin(); for(;itr != Snake.end(); itr ++) { i++; } return i; } //设置蛇的输出位置 颜色 void sna::setSnaFormat(sna_body s) { format.setColor(s.col); format.wordsLoca(s.x,s.y); } void sna::printSna() { for(vector<sna_body>::iterator itr = Snake.begin(); itr != Snake.end(); itr ++) { setSnaFormat(*itr); cout << itr->ch; } } //吃到食物 void sna::eatFood() { greds ++; //更新成绩显示 format.wordsLoca(93,3); cout << "GREDS: "; format.wordsLoca(99,3); format.setColor(3); cout << greds << endl; sna_body got(f.x, f.y, Snake.begin()->col, Snake.begin()->ch); Snake.insert(Snake.begin(),got); //开始位置插入节点 Snake[1].ch = Snake[2].ch; Snake[1].col = Snake[2].col; this->printSna(); this->buildFood(); //新建一个食物 } void sna::move() { if(colider() == KNOCKED_WALL) //撞墙或者撞到自己 { this->life --; this->lifeBeenChange = true; dieFlash(); } else if(colider() == KNOCKED_FOOD) //撞到食物 { eatFood(); //吃到食物 } else { sna_body newHead(moveDir.x, moveDir.y,Snake[0].col,Snake[0].ch);//新的头结点等于新的移动坐标,等于原来的ch内容 Snake.insert(Snake.begin(),newHead); //插入新的节点 Snake[1].ch = Snake[2].ch;//第二个节点(原来的头)等于第三个节点内容,位置不变 Snake[1].col = Snake[2].col; //更改最后一个节点内容为空格,然后输出SNAKE,然后删掉最后一个节点 Snake[getLastoneIndex()].ch = " "; this->printSna(); Snake.pop_back(); } } void sna::buildFood() { bool foodOk = true; do { foodOk = true; f.x = R(1,23); //x f.y = R(1,89); //y for(vector<sna_body>::iterator itr = Snake.begin(); itr != Snake.end(); itr ++) { if((itr->x == f.x && itr->y == f.y) || f.x <= 0 || f.x >= 89 || f.y <= 0 || f.y >= 24) { foodOk = false; break; } } }while(!foodOk); if(foodOk) { } //char *t = f.ch = FOODS; f.col = 4; //红色; //输出食物 printFood(); } void sna::printFood() { format.wordsLoca(f.x, f.y); format.setColor(f.col); cout << f.ch; } void sna::getKey() { while(true) { int sleepTime = 0; while(sleepTime != snackSleepTime) { if(kbhit())//如果检测到按键 { sleepTime = 0; getch(); this->nowKey = getch(); if(nowKey == KEY_UP) //上 { moveDir.y = Snake.begin()->y - 1; } else if(nowKey == KEY_RIGHT) //右 { moveDir.x = Snake.begin()->x + 1; } else if(nowKey == KEY_DOWN) //下 { moveDir.y = Snake.begin()->y + 1; } else if(nowKey == KEY_LEFT)//左 { moveDir.x = Snake.begin()->x - 1; } move(); if(this->life <= 0) //生命指使用完 { gameOver(); //结束游戏 return; } } sleepTime += singleSleepTime; Sleep(singleSleepTime); //单次睡眠时间越大 连续按键移动速度越慢,因为扫面按键时间变短了 } if(this->lifeBeenChange) //死后停止不动,按键按下才向前动 { this->lifeBeenChange = false; } else { autoMove(); if(this->life <= 0) //生命指使用完 { gameOver(); //结束游戏 return; } } } } void sna::autoMove() { if(nowKey == KEY_UP) { moveDir.y --; } else if(nowKey == KEY_RIGHT) { moveDir.x ++; } else if(nowKey == KEY_DOWN) { moveDir.y ++; } else if(nowKey == KEY_LEFT) { moveDir.x --; } move(); } void sna::begin() { getKey(); } bool sna::cloider_self() { for(vector<sna_body>::iterator itr = Snake.begin();itr != Snake.end(); itr ++) { if(moveDir.x == itr->x && moveDir.y == itr->y) { cout << itr->x << " " <<itr->y << endl; cout << moveDir.x << " " << moveDir.y << endl; return true; } } return false; } int sna::colider() { if(moveDir.x <= 0 || moveDir.x >= 89 || moveDir.y <= 0 || moveDir.y >= 24 || cloider_self()) //撞墙 || 撞自己 { format.wordsLoca(93,5); cout << "LIFE: " << this->life - 1; //更新生命显示 format.wordsLoca(3,3); cout << moveDir.x << " " << moveDir.y << endl; if(nowKey == KEY_UP) //恢复错误 免得困在死亡无法逃生 { moveDir.y ++; } if(nowKey == KEY_DOWN) { moveDir.y --; } if(nowKey == KEY_LEFT) { moveDir.x ++; } if(nowKey == KEY_RIGHT) { moveDir.x --; } format.wordsLoca(3,4); cout << moveDir.x << " " << moveDir.y << endl; return KNOCKED_WALL; } else if(moveDir.x == f.x && moveDir.y == f.y) { return KNOCKED_FOOD; } return KNOCKED_NOTHING; } void sna::dieFlash() { int T = 3; while(T--) { for(vector<sna_body>::iterator itr = Snake.begin(); itr != Snake.end(); itr ++) { format.wordsLoca(itr->x,itr->y); cout << " "; } Sleep(400); this->printSna(); Sleep(400); } } void sna::gameOver() { vector<sna_body>().swap(Snake); //通过swap释放vector内存 format.setColor(2); //绿色 for(int y = 1; y < 24; y ++) //填满界面 { format.wordsLoca(1,y); for(int i = 1; i < 89; i ++) { Sleep(1); cout << "#"; if(y == 12 && i == 42) { format.setColor(4); //红色 cout << "GAME OVER !"; i += 11; format.setColor(2); //恢复绿色 } } } Sleep(1000); for(int b_x = 1, e_x = 23; b_x <= 12 || e_x > 12; b_x ++, e_x --) { for(int b_y = 1, e_y = 88; b_y < 89; b_y ++, e_y --) { format.wordsLoca(b_y,b_x); cout << " "; format.wordsLoca(e_y,e_x); cout << " "; Sleep(1); } } } //class menu: menu::menu() { words colo; colo.setColor(1); colo.hideCursor(); this->select_num = 1; for(int i = 0; i < 90; i ++) { format.wordsLoca(i,0); //第一排边框 cout << "|"; format.wordsLoca(i,24); //最后一排边框 cout << "|"; } for(int i = 0; i < 25; i ++) { format.wordsLoca(0,i); //左边边框 cout << "*"; format.wordsLoca(89,i); //右边边框 cout << "*"; } } //设置title 坐标,颜色,内容 void menu::confiFlash() //确认闪烁 { if(this->select_num == 1) //闪烁start { int T = 3; while(T) { drawStart(" "," "); //擦除输出 Sleep(400); drawStart(MENUCHA,"START"); Sleep(400); T --; } } else if(this->select_num == 2) //闪烁LEVEL { int T = 3; while(T) { drawLevel(" "," "); //擦除输出 Sleep(400); drawLevel(MENUCHA,"LEVEL"); Sleep(400); T --; } } } void menu::setTitle(const coor_col &a) { title.x = a.x, title.y = a.y, title.c = a.c; } //设置start 坐标,颜色,内容 void menu::setStart(const coor_col &st_1, const coor_col &st_2) { start_1.x = st_1.x, start_1.y = st_1.y, start_1.c = st_1.c, start_2.x = st_2.x, start_2.y = st_2.y, start_2.c = st_2.c; } //设置title 坐标,颜色,内容 void menu::setLevel(const coor_col &le_1, const coor_col &le_2) { level_1.x = le_1.x, level_1.y = le_1.y, level_1.c = le_1.c; level_2.x = le_2.x, level_2.y = le_2.y, level_2.c = le_2.c; } void menu::drawTitle(const string & str) { format.setColor(title.c); //设置标题颜色 format.wordsLoca(title.x,title.y); //设置标题输出坐标 cout << str; //输出标题 } void menu::drawStart(const char *ch,const string & str) { format.setColor(start_1.c); //设置标题颜色 format.wordsLoca(start_1.x,start_1.y); //设置标题输出坐标 wcout << ch; format.setColor(start_2.c); format.wordsLoca(start_2.x, start_2.y); cout << str; } void menu::drawLevel(const char *ch,const string & str) { format.setColor(level_1.c); //设置标题颜色 format.wordsLoca(level_1.x,level_1.y); //设置标题输出坐标 cout << ch; format.setColor(level_2.c); format.wordsLoca(level_2.x,level_2.y); cout << str; } void menu::select() { while(true) { char ch; ch = getch(); if(ch != KEY_ENTER) //回车一个getch()可以完成接受回车键,但是方向键需要两个getch()完成接受 { ch = getch(); } if(this->select_num == 1) { if(ch == KEY_DOWN) //80 下键 { this->select_num ++; drawStart(" ","START"); drawLevel(MENUCHA,"LEVEL"); } else if(ch == KEY_ENTER) //13 回车键 { confiFlash(); //闪烁 break; } } if(this->select_num == 2) { if(ch == KEY_UP) //72 上键 { this->select_num --; drawStart(MENUCHA,"START"); drawLevel(" ","LEVEL"); } else if(ch== KEY_ENTER) //13 回车键 { confiFlash(); //闪烁 break; } } } } void menu::drawMenu(coor_col &format,coor_col &format_2) { this->setTitle(format); this->drawTitle("WELLCOME TO THE SNAKE"); format.x = 25, format_2.x = format.x + 3; format.y = 10, format_2.y = format.y; format.c = 6, format_2.c = 3; this->setStart(format, format_2); this->drawStart(MENUCHA,"START"); format.x = 25; format_2.x = format.x + 3; format.y = 12; format_2.y = format.y; format.c = 6; format_2.c = 3; this->setLevel(format,format_2); this->drawLevel(" ","LEVEL"); } void menu::beginClean() //开始动画 { for(int y = 1; y < 24; y ++) { format.wordsLoca(1,y); for(int i = 1; i < 89; i ++) cout << " "; } //输出空格 填充过期的成绩 format.wordsLoca(93,3); cout << "GREDS: "; format.wordsLoca(93,5); cout << "LIFE: 3 "; //输出tip format.wordsLoca(93,8); format.setColor(6); cout << "TIP:"; format.wordsLoca(93,10); cout << "↑ "; cout << "向上移动"; format.wordsLoca(93,12); cout << "↓ "; cout <<"向下移动"; format.wordsLoca(93,14); cout << "← "; cout << "向左移动"; format.wordsLoca(93,16); cout << "→ "; cout << "向右移动"; }
MAIN.cpp
#include "sn.h" using namespace std; int main() { menu in_face; coor_col format; coor_col format_2; while(true) { format.x = 35; //标题位置 format.y = 5; format.c = 3; //标题颜色 in_face.drawMenu(format,format_2); in_face.select(); int num = in_face.getSelectNum(); in_face.beginClean(); if(num == 1) //start { sna_body s_b(5,1,4,SNAHEAD); sna one(s_b); one.begin(); } else if(num == 2) { cout << "sorry, wait please...\n"; } } return 1; }