码迷,mamicode.com
首页 > 其他好文 > 详细

贪吃蛇项目总结

时间:2016-04-29 15:10:06      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

以下总结,在此次项目中遇到的问题以及解决方法:

控制台 显示设置:

#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;
}



贪吃蛇项目总结

标签:

原文地址:http://blog.csdn.net/qq_25235869/article/details/51279295

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!