您的位置:首页 > 编程语言 > C语言/C++

贪吃蛇项目总结

2016-04-29 11:49 459 查看
以下总结,在此次项目中遇到的问题以及解决方法:

控制台 显示设置:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  控制台 c++