⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.cpp

📁 一个用C++写的文字类游戏
💻 CPP
字号:
#include "StdAfx.h"
#include ".\game.h"
#include "globalobject.h"
#include <windows.h> 
#include "role.h"
#include "fileoperation.h"
extern CGlobalObject g_Object;


CGame::CGame(void)
{
}

CGame::~CGame(void)
{
}



void CGame::GameHelp()
{
	g_Object.HelpString("E", 'q',	"uip:     查看装备");
	g_Object.HelpString("S", 't',	"ate:     查看人物状态");
	g_Object.HelpString("", 'B',	"undle:    打开包袱");
	g_Object.HelpString("", 'R',	"est:     休息,每次回复生命10%");
	g_Object.HelpString("", 'G',	"et:      拿取物品");
	g_Object.HelpString("", 'H',	"elp:     查看帮助");
	g_Object.HelpString("", 'V',	"iew:     查看周围环境");
	g_Object.HelpString("Q", 'u',	"it:     退出游戏");

	g_Object.HelpString("", 'E',	"ast:      向东走一步");
	g_Object.HelpString("", 'W',	"est:      向西走一步");
	g_Object.HelpString("", 'S',	"outh:     向南走一步");
	g_Object.HelpString("", 'N',	"outh:     向北走一步");

}





//人物文件中的信息如下所示
//</白无影;1;2;2/>人物名,级别,装备数量,物品数量
//</无影刀;1;30/>装备名,装备类型,属性(武器的属性是攻击,盾的属性是防御)
//</坚金盾;2;50/>
//</大补丸;3;20;20/>物品名,类型(持续回血还是瞬间回血),属性(回血量),数量
//</g保命丹;4;80;10/>
bool CGame::InitRole(char * strFileName)
{
	char * pStart = new char[FILE_MAX];
	memset(pStart, 0, FILE_MAX);
	CFileOperation file;
	int nFileLength;
	bool bRead = file.ReadFile(strFileName, nFileLength, pStart);
	int i,j,k=0;
	bool bFirst = true;
	char pTemp[30];
	memset(pTemp, 0, 30);
	// 用i,j找到</..../>部分。用k找到;部分。
	for (i = 0; i<nFileLength; i++) {
		if (pStart[i] == '<' && pStart[i+1] == '/') {
			for (j= i+2; j<nFileLength; j++) {
				if (pStart[j] == '>' && pStart[j-1] == '/') {
					if (bFirst) {
						for (k=i+1; k<j; k++) {
							if (pStart[k] == ';'){
								
								memcpy(g_Object.m_protagonist.m_strName, &pStart[i+2],k-i-2);
								memcpy(pTemp, &pStart[k+1], j-k-2);
								g_Object.m_protagonist.InitByLevelAndType(atoi(pTemp),ROLE_PROTAGONIST);
							}
						}
						bFirst = false;
						i = j+1;
						break;
					}
					if (pStart[i+2] == '1') {
						FillEquip(&pStart[i+3], j-i-4);
					} else if (pStart[i+2] == '2') {
						FillGoods(&pStart[i+3], j-i-4);
					}
					i = j+1;
					break;
				}
			}
		}
	}

	delete[] pStart;
	if (!bRead) {
		cout<<"加载人物信息失败!"<<endl;
	}
	return bRead;
}

void CGame::FillEquip(char * strEquip, int nLength)
{
	int nStart = 0;
	int j = 0;
	ROLE_EQUIP equip;
	char strTemp[30];
	memset(strTemp, 0, 30);
	for (int i = 0; i<nLength;i++) {
		if (strEquip[i] == ';') {
			if (j == 0) {
				equip.strName = new char[i-nStart+1];
				memset(equip.strName, 0, i-nStart+1);
				memcpy(equip.strName, &strEquip[nStart], i-nStart);
			} else if (j == 1) {
				memset(strTemp, 0, 30);
				memcpy(strTemp, &strEquip[nStart], i-nStart);
				equip.nType = atoi(strTemp);
				
		
				memset(strTemp, 0, 30);
				memcpy(strTemp, &strEquip[i+1], nLength-i-1);
				equip.nAttribute = atoi(strTemp);
			} 
			nStart = i+1;
			j++;
		}
	}
	if (equip.nType == 1) {
		g_Object.m_protagonist.m_nAttack = g_Object.m_protagonist.m_nBaseAtt + equip.nAttribute;
	} else if (equip.nType == 2) {
		g_Object.m_protagonist.m_nDefend = g_Object.m_protagonist.m_nBaseDef + equip.nAttribute;
	}
	g_Object.m_vecEquip.push_back(equip);
}

void CGame::FillGoods(char * strGoods, int nLength)
{
	int nStart = 0;
	int j = 0;
	ROLE_GOODS goods;
	char strTemp[30];
	memset(strTemp, 0, 30);
	for (int i = 0; i<nLength;i++) {
		if (strGoods[i] == ';') {
			if (j == 0) {
				goods.strName = new char[i-nStart+1];
				memset(goods.strName, 0, i-nStart+1);
				memcpy(goods.strName, &strGoods[nStart], i-nStart);
			} else if (j == 1) {
				memset(strTemp, 0, 30);
				memcpy(strTemp, &strGoods[nStart], i-nStart);
				goods.nType = atoi(strTemp);
				
			}else if (j == 2) {
				memset(strTemp, 0, 30);
				memcpy(strTemp, &strGoods[nStart], i-nStart);
				goods.nAttribute = atoi(strTemp);
			
				memset(strTemp, 0, 30);
				memcpy(strTemp, &strGoods[i+1], nLength - i -1);
				goods.nNumber = atoi(strTemp);
			}
			nStart = i+1;
			j++;
		}
	}
	g_Object.m_vecGoods.push_back(goods);
	
}

bool CGame::InitScenario(char * strFileName)
{
	char * pStart = new char[FILE_MAX];
	memset(pStart, 0, FILE_MAX);
	CFileOperation file;
	int nFileLength;
	bool bRead = file.ReadFile(strFileName, nFileLength, pStart);
	if (!bRead) {
		cout<<"加载剧情信息失败!"<<endl;
		delete [] pStart;
		return false;
	}
	int i,j,k=0;
	char strId[3];
	strId[2] = 0;
	SCENARIO_INFO sInfo;	
	for (i = 0; i<nFileLength; i++) {
		if (pStart[i] == '<' && pStart[i+1] == '/') {
			for (j= i+2; j<nFileLength; j++) {
				if (pStart[j] == '>' && pStart[j-1] == '/') {
					sInfo.strInfor = new char[j-i-4];
					memcpy(sInfo.strInfor,&pStart[i+4],j-i-5);
					sInfo.strInfor[j-i-5] = 0;
					memcpy(strId, &pStart[i+2], 2);
					sInfo.nLength  = j-i-3;
					sInfo.nType = atoi(strId);
					g_Object.m_vecScenarioInfo.push_back(sInfo);
					k++;
					i = j+1;
					break;
				}
			}
		}
	}

	delete[] pStart;
	return bRead;
}

bool CGame::InitNPC(char * strFileName)
{
	char * pStart = new char[FILE_MAX];
	memset(pStart, 0, FILE_MAX);
	CFileOperation file;
	int nFileLength;
	bool bRead = file.ReadFile(strFileName, nFileLength, pStart);
	if (!bRead) {
		cout<<"加载NPC信息失败!"<<endl;
		delete [] pStart;
		return false;
	}
	int i,j,k=0;
	char strId[3];
	strId[2] = 0;

	for (i = 0; i<nFileLength; i++) {
		if (pStart[i] == '<' && pStart[i+1] == '/') {
			for (j= i+2; j<nFileLength; j++) {
				if (pStart[j] == '>' && pStart[j-1] == '/') {
					FillNPC(&pStart[i+2], j-i-2);
					i = j+1;
					break;
				}
			}
		}
	}

	delete[] pStart;
	return bRead;
}

void CGame::FillNPC(char * strNPC, int nLength)
{
	int nStart = 0;
	int j = 0;

	char strTemp[30];
	memset(strTemp, 0, 30);
	CRole  role;
	int nLevel,nPosX, nPosY;
	for (int i = 0; i<nLength;i++) {
		if (strNPC[i] == ';') {
			if (j == 0) {
				memcpy(role.m_strName, &strNPC[nStart], i-nStart);
			} else if (j == 1) {
				memset(strTemp, 0, 30);
				memcpy(strTemp, &strNPC[nStart], i-nStart);
				nLevel = atoi(strTemp);
				
			}else if (j == 2) {
				memset(strTemp, 0, 30);
				memcpy(strTemp, &strNPC[nStart], i-nStart);
				nPosX = atoi(strTemp);
				
			} else if ( j== 3) {
				memset(strTemp, 0, 30);
				memcpy(strTemp, &strNPC[nStart], i-nStart);
				nPosY = atoi(strTemp);
			}
			nStart = i+1;
			j++;
		}
	}
	role.InitNPC(nLevel, ROLE_MONSTER, nPosX, nPosY);
	g_Object.m_vecNpc.push_back(role);
}

bool CGame::Init()
{
	SetConsoleTitle("勇闯伏曦陵");
	g_Object.DrawSword();
	if (!InitRole("role.txt")) 
		return false;
	if (!InitScenario("start.txt"))
		return false;
	if (!InitNPC("monster.txt"))
		return false;

	return true;

}

void CGame::Over()
{
    g_Object.SetColor(); 
   
	g_Object.DrawSword();
	system("pause");
}

//HelpString("E", 'q',"uip: 查看装备");
//HelpString("S", 't',"ate: 查看人物状态");
//HelpString("", 'B',"undle: 打开包袱");
//HelpString("", 'R',"est:休息,每次回复生命10%");
//HelpString("", 'G',"et:拿取物品");
//HelpString("", 'H',"elp:查看帮助");
//HelpString("", 'V',"iew:查看周围环境");
//HelpString("Q", u'',"it:退出游戏");


//HelpString("", 'E',"ast: 向东走一步");
//HelpString("", 'W',"est: 向西走一步");
//HelpString("", 'S',"outh: 向南走一步");
//HelpString("", 'N',"outh: 向北走一步");

void CGame::Render(char cCommand)
{
	switch(cCommand) {
	case 'q':
	case 'Q':{
		vector<ROLE_EQUIP>::iterator iter;
		for (iter = g_Object.m_vecEquip.begin(); iter != g_Object.m_vecEquip.end(); iter++) {
			if (iter->nType == EQUIP_WEAPON) {
				cout<<g_Object.m_protagonist.m_strName<<"装备的武器是:"<<iter->strName<<endl;
				cout<<"攻击力为:"<<iter->nAttribute<<endl;
			} else if (iter->nType == EQUIP_SHIELD) {
				cout<<g_Object.m_protagonist.m_strName<<"装备的盾牌是:"<<iter->strName<<endl;
				cout<<"防御值为:"<<iter->nAttribute<<endl;
			}
		}
			 
		}
		break;
	case 't':
	case 'T':
		cout<<g_Object.m_protagonist.m_strName<<"的状态:"<<endl;
		cout<<"当前等级:   "<<g_Object.m_protagonist.m_nLevel<<endl;
		cout<<"当前生命:   "<<g_Object.m_protagonist.m_nBlood<<endl;
		cout<<"当前攻击力: "<<g_Object.m_protagonist.m_nAttack<<endl;
		cout<<"当前防御:   "<<g_Object.m_protagonist.m_nDefend<<endl;
		cout<<"当前经验:   "<<g_Object.m_protagonist.m_nExperience<<endl;

		break;
	case 'B':
	case 'b':{
		vector<ROLE_GOODS>::iterator iter;
		for (iter = g_Object.m_vecGoods.begin(); iter != g_Object.m_vecGoods.end(); iter++) {
			if (iter->nType == GOODS_DURATIVE) {
				cout<<iter->strName<<"每回合回复"<<iter->nAttribute<<"生命,回复五回合。现在有"<<iter->nNumber<<"个"<<endl;
				
			} else if (iter->nType == GOODS_INSTANTANEOUS) {
				cout<<iter->strName<<"瞬间回复"<<iter->nAttribute<<"生命。现在有"<<iter->nNumber<<"个"<<endl;
			}
		}	
		}

		break;
	case 'R':
	case 'r':
		//回复10%,到顶了就不回复了。
		g_Object.m_protagonist.m_nBlood += (g_Object.m_protagonist.m_nLevel*30 + 100)/10;
		if (g_Object.m_protagonist.m_nBlood > (g_Object.m_protagonist.m_nLevel*30 + 100)) 
				g_Object.m_protagonist.m_nBlood = g_Object.m_protagonist.m_nLevel*30 + 100;
		cout<<g_Object.m_protagonist.m_strName<<"休息后生命回复为"<<g_Object.m_protagonist.m_nBlood <<endl;
		break;
	case 'G':
	case 'g':
		cout<<"当前没有东西要拾取。"<<endl;
		break;
	case 'H':
	case 'h':
		GameHelp();
		break;
	case 'V':
	case 'v':
		GetCurStart();
		break;
	case 'u':
	case 'U': 
		cout<<"您确定要退出游戏吗?(Y/N)";
		g_Object.m_nGameStart = GS_QUIT;
		break;
	case 'E':
	case 'e':
	case 'W':
	case 'w':
	case 'S':
	case 's':
	case 'N':
	case 'n':
		MovePos(cCommand);
		break;
	default:
		cout<<"请进行有效输入。"<<endl;
		break;
	}
}


void CGame::GetCurStart()
{
	g_Object.SetColor(FOREGROUND_GREEN);
	vector<SCENARIO_INFO>::iterator iter;
	for (iter = g_Object.m_vecScenarioInfo.begin(); iter != g_Object.m_vecScenarioInfo.end(); iter++) {
		if (iter->nType == 5) {
			cout<<iter->strInfor<<endl;
			break;
		}
	}
	int nX = g_Object.m_protagonist.m_nPosX;
	int nY = g_Object.m_protagonist.m_nPosY;
	cout<<g_Object.m_protagonist.m_strName<<"的所在位置是("<<nX<<", "<<nY<<")"<<endl;
	vector<CRole>::iterator iterRole;
	bool bFind = false;
	for (iterRole = g_Object.m_vecNpc.begin(); iterRole != g_Object.m_vecNpc.end(); iterRole++) {
		if (iterRole->m_nPosX == nX -1 && iterRole->m_nPosY == nY) {
			cout<<"在你的西面有";
			cout<<iterRole->m_strName<<"在到处游荡。"<<endl;
			bFind = true;
		} else if (iterRole->m_nPosX == nX + 1 && iterRole->m_nPosY == nY) {
			cout<<"在你的东面有";
			cout<<iterRole->m_strName<<"在到处游荡。"<<endl;
			bFind = true;
		} else if (iterRole->m_nPosX == nX && iterRole->m_nPosY == nY - 1) {
			cout<<"在你的北面有";
			cout<<iterRole->m_strName<<"在到处游荡。"<<endl;
			bFind = true;
		} else if (iterRole->m_nPosX == nX && iterRole->m_nPosY == nY + 1) {
			cout<<"在你的南面有";
			cout<<iterRole->m_strName<<"在到处游荡。"<<endl;
			bFind = true;
		} 
	}
	if (!bFind) {
		cout<<"四周非常安静没有发现怪物。"<<endl;
	}
}

void CGame::MovePos(char cDirection)
{
	g_Object.SetColor(FOREGROUND_GREEN);
	bool bIsMove = false;
	switch (cDirection) {
	case 'E':
	case 'e':
		if (g_Object.m_protagonist.m_nPosX + 1 < MAP_MAX_SIZE) {
			g_Object.m_protagonist.m_nPosX += 1;
			cout<<"向东走了一段路。"<<endl;
			bIsMove = true;
		} else {
			cout<<"已走到陵墓的东墙,走不动了。"<<endl;	
		}
		break;
	case 'W':
	case 'w':
		if (g_Object.m_protagonist.m_nPosX - 1 >= 0) {
			g_Object.m_protagonist.m_nPosX -= 1;
			cout<<"向西走了一段路。"<<endl;
			bIsMove = true;
		}  else {
			cout<<"已走到陵墓的西墙,走不动了。"<<endl;	
		}
		break;
	case 'S':
	case 's':
		if (g_Object.m_protagonist.m_nPosY + 1 < MAP_MAX_SIZE) {
			g_Object.m_protagonist.m_nPosY += 1;
			cout<<"向南走了一段路。"<<endl;
			bIsMove = true;
		}  else {
			cout<<"已走到陵墓的南墙,走不动了。"<<endl;	
		}
		break;
	case 'N':
	case 'n':
		if (g_Object.m_protagonist.m_nPosY - 1 >= 0) {
			g_Object.m_protagonist.m_nPosY -= 1;
			cout<<"向北走了一段路。"<<endl;
			bIsMove = true;
		}  else {
			cout<<"已走到陵墓的北墙,走不动了。"<<endl;	
		}
		break;
	default:
		return ;
	}

	//如果到了最后一个格就结束游戏。
	if ((g_Object.m_protagonist.m_nPosX == MAP_MAX_SIZE -1) && 
		(g_Object.m_protagonist.m_nPosY == MAP_MAX_SIZE -1)) {
		vector<SCENARIO_INFO>::iterator iter;
		for (iter = g_Object.m_vecScenarioInfo.begin(); iter != g_Object.m_vecScenarioInfo.end(); iter++) {
			if (iter->nType == 6) {
				g_Object.PlayString(50, iter->strInfor, iter->nLength);
				break;
			}
		}
		g_Object.SetColor(FOREGROUND_GREEN);
		cout<<"游戏结束,请按任意键退出。"<<endl;
		g_Object.m_nGameStart = GS_OVER;
		return ;
			
	}
	if (!bIsMove) {
		return ;
	}
	//HelpString("", '1',"普通功击");
	////三斩三绝为杀敌技能,望有效利用。
	//HelpString("", '2',"飞龙斩:攻击敌人单体");
	//HelpString("", '3',"狂风斩:攻击敌人全体");
	//HelpString("", '4',"霹雳斩:攻击敌人单体,三回合内晕乎乎的");
	//HelpString("", '5',"金钟诀:六回合内防御加倍");
	//HelpString("", '6',"必杀诀:五回合内致命一击机率+50%");
	//HelpString("", '7',"灵体诀:十回合内闪避机率+20%");
	//HelpString("", '8',"使用药物");
	//如果方格中有怪物则进入战斗状态。
	vector<CRole>::iterator iterRole;
	bool bFind = false;
	for (iterRole = g_Object.m_vecNpc.begin(); iterRole != g_Object.m_vecNpc.end(); iterRole++) {
		if (iterRole->m_nPosX == g_Object.m_protagonist.m_nPosX && 
			iterRole->m_nPosY == g_Object.m_protagonist.m_nPosY) {
			// 当有怪物时进入战斗状态
			g_Object.m_fight.m_nBout = 0;
			g_Object.m_fight.m_iterNPC = *iterRole;

			cout<<g_Object.m_protagonist.m_strName<<"碰到了在此处游荡的";
			cout<<iterRole->m_nLevel<<"级"<<iterRole->m_strName<<"进入战斗状态"<<endl;
			cout<<"1:普通攻击  2:飞龙斩  3:狂风斩  4:霹雳斩"<<endl;
			cout<<"5:金钟诀    6:必杀诀  7:灵体诀  8:使用药物"<<endl;
			cout<<"9:参看状态             H:查看详细说明"<<endl;
			g_Object.m_nGameStart = GS_FIGHT;
			break;
		} 
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -