C++控制台RPG游戏具体实现思路: 任务系统

接受任务,提交任务,显示任务

玩家里面应该有一个容器,用来存放已接收的任务,

任务NPC里面也应该有一个容器,用来存放开启的任务

接受任务:

1.不同NPC对应不同任务:

任务数据里面应该对应包含NPCID属性。由此实现不同npc对应不同任务(同商店)

2.NPC里面有开启的任务,和没开启的任务:

任务数据应该具有是否开启的属性,满足条件开启任务,否则不开启,NPC里面只显示开启的任务。

3.接受任务后,玩家任务窗口里应当显示当前任务,以及任务进度。完成任务后,任务属性应当变为已完成。

如何实现任务进度?

提交任务:

当当前任务完成时,提交任务成功,并获取相应奖励。

显示任务:

玩家应当包含一个装有已接任务的容器,定义对任务属性的数据更新和渲染(装备和技能是否也是如此?装备和任务系统是否可以都继承某个窗口类,所以玩家里面应该包含装备管理者、技能管理者、任务管理者的成员去进行管理),当按下某个建的时候,gameMgr对任务进行数据更新和渲染。对窗口基类进行数据更新、以及渲染。(battle我是直接归游戏管理者管理了,事实上,让其属于map管理(battl只需要enemy和player数据,map中均可以拿到),这样battle也能够变成一个窗口延伸了。)

任务是商品吗?任务不应当是商品。任务应当单独配表

三、不同任务不同的达成条件:

1.杀怪   2.找npc  3.购买相关物品

四、完成任务后获取相关奖励

1.经验、金币

2.装备

3.开启相应任务

具体实现:

整个任务系统包含三个类:CMission类、MissionMgr类、CMissionNpc类、CRecivedMission类

四个类分别进行:CMission:任务的逻辑处理,如获取奖励,判断任务是否完成等。

CMissionMgr类:创建所有任务、并对其初始化,获取已接任务和已解锁任务分别传给CRecivedMission类和CMissionNpc类。

CMissionNpc类:任务NPC的处理,和商店买卖物品类似的功能,处理任务的接受、提交、对话等

CRecivedMission类:玩家的任务窗口,用于显示已经接受的任务、以及任务描述等

源代码:

CMission类:

#pragma once
#include "Talk.h"
class CMission
{
public:
	CMission();
	~CMission();
	void getReward();
	int getID()
	{
		return m_nID;
	};
	void initMission(SMissionDt* data);
	void showName();
	void showDescripe();
	void showSchedule();
	void updataIsAchieve();
	CTalk* getTalk(){ return m_pTalk; }
	CTalk* getFinishTalk(){ return m_pFinishTalk; }
	int getNpcID(){ return m_nNpcID; };
	GETTER_SETTER(bool, isAchieve, m_bIsAchieve);
	GETTER_SETTER(bool, isRecived, m_bIsRecived);
	GETTER_SETTER(bool, isUnlock, m_bIsUnlocked);
private:
	int m_nID;
	int m_nNpcID;
	char m_szName[32];
	char m_szDescripe[128];
	CTalk* m_pTalk;
	CTalk* m_pFinishTalk;

};

MissionMgr类:

#pragma once
#include "Mission.h"
class CMissionMgr
{
public:
	CMissionMgr();
	~CMissionMgr();
	void creatAllMission();
	vector<CMission*>getUnlockMission();
	vector<CMission*>getRecivedMission();
	CMission* getMission(int nID);
private:
	vector<CMission*>m_vecMissions;
};

CMissionNpc类: 

#pragma once
#include "Mission.h"
class CMissionNpc:public CWndBase
{
public:
	CMissionNpc();
	~CMissionNpc();
	void updata();
	void onRander();
	void updataMission();
	void setMissions(int nNpcID);
private:
	vector<CMission*>m_vecUnlockedMission;
	int m_nIndex;
};

CRecivedMission类: 

#pragma once
#include "Mission.h"
#include "WndBase.h"
class CRecivedMission:public CWndBase
{
public:
	CRecivedMission();
	~CRecivedMission();
	void setMission();
	void updata();
	void onRander();
private:
	vector<CMission*>m_vecRecivedMission;
	int m_nIndex;
};

CMission类的实现:

#include "stdafx.h"
#include "Mission.h"


CMission::CMission()
{
	m_nID = 0;
	m_nNpcID = 0;
	m_bIsRecived = false;
	m_bIsUnlocked = false;
	memset(m_szName, 0, sizeof(m_szName));
	memset(m_szDescripe, 0, sizeof(m_szDescripe));
	m_bIsAchieve=false;
	m_pTalk = new CTalk;
	m_pFinishTalk = new CTalk;
}


CMission::~CMission()
{
}

void CMission::initMission(SMissionDt* data)
{
	m_nID = data->nID;
	m_nNpcID = data->nNpcID;
	m_bIsRecived = data->bIsRecive;
	m_bIsUnlocked = data->bIsUnlocked;
	memcpy(m_szName, data->szName, sizeof(data->szName));
	memcpy(m_szDescripe, data->szDescripe, sizeof(data->szDescripe));
	//接收任务时的对话
	m_pTalk->setTalkLines(data->nTalkLines);
	memcpy(m_pTalk->getArrTalk()->arrTalk, data->arrTalk, sizeof(data->arrTalk));
	//提交任务时的对话
	m_pFinishTalk->setTalkLines(data->nFinishTalkLines);
	memcpy(m_pFinishTalk->getArrTalk()->arrTalk, data->arrFinishTalkLines, sizeof(data->arrFinishTalkLines));
}

void CMission::showName()
{
	cout << m_szName;
}

void CMission::showDescripe()
{
	cout << m_szDescripe;
}

void CMission::updataIsAchieve()
{
	CPlayer* player = g_GameMgr->getGameMap()->getplayer();
	switch (m_nID)
	{
	case 6001:
		if (2 <= player->getKillEnemyNum(4001))
		{
			m_bIsAchieve = true;
		}
		break;
	case 6002:
		if (2 <= player->getKillEnemyNum(4002))
		{
			m_bIsAchieve = true;
		}
		break;
	case 6003:
		if (2 <= player->getKillEnemyNum(4003))
		{
			m_bIsAchieve = true;
		}
		break;
	case 6004:
		if (10 <= player->getPackage()->getItemNum(3004))
		{
			m_bIsAchieve = true;
		}
		break;
	case 6005:
		//当背包里面有回信的时候,完成任务。
		if (player->getPackage()->getItemNum(3013)>0)
		{
			m_bIsAchieve = true;
		}
		break;
	case  6006:
		if (player->getPackage()->getItemNum(3014) > 0)
		{
			m_bIsAchieve = true;
		}
		break;
	default:
		break;
	}
}


 void CMission::getReward()
 {
	 CPlayer* player = g_GameMgr->getGameMap()->getplayer();
 	switch (m_nID)
 	{
 	case 6001:
 		player->addExp(100);
 		player->changeMoney(5000);
 		player->getEquitment()->addEquiepment(g_DataMgr->getIteamDtMgr()->getByID(3001));
 		break;
 	case 6002:
 		player->addExp(100);
 		player->changeMoney(5000);
 		break;
 	case 6003:
 		player->addExp(100);
 		player->changeMoney(5000);
 		break;
 	case 6004:
 		player->addExp(100);
 		player->changeMoney(5000);
 		break;
 	case 6005:
 		player->addExp(100);
 		player->changeMoney(400);
 		//解锁新的任务
		g_GameMgr->getMissionMgr()->getMission(6006)->setisUnlock(true);
		//任务物品消失
		g_GameMgr->getGameMap()->getplayer()->getPackage()->deleteItem(3013);
		男人移动
		//g_GameMgr->getGameMap()->getNpcMgr()->moveNpc(2007,1003, 5, 10);
		/*男人消失*/
		g_GameMgr->getGameMap()->getNpcMgr()->deleteNpc(2007);
 		break;
 	case 6006:
 		player->addExp(100);
 		player->changeMoney(5000);
 		player->getPackage()->addItem(g_DataMgr->getIteamDtMgr()->getByID(3006));
 		break;
 	default:
 		break;
 	}
 }

 void CMission::showSchedule()
 {
	 CPlayer* player = g_GameMgr->getGameMap()->getplayer();
	 switch (m_nID)
	 {
	 case 6001:
		 cout << player->getKillEnemyNum(4001)<<"/2";
		 break;
	 case 6002:
		 cout << player->getKillEnemyNum(4002)<< "/2";
		 break;
	 case 6003:
		 cout << player->getKillEnemyNum(4003)<< "/2";
		 break;
	 case 6004:
		 cout << player->getPackage()->getItemNum(3004)<< "/10";
		 break;
	 case 6005:
		 cout << "  杰克马上要奔赴战场了,找到珍妮,并把这封信交给她";
		 break;
	 case 6006:
		 cout << "  在漫长的日子里,珍妮愈发的思念杰克,她让我务必把这封信交到杰克手中";
		 break;
	 default:
		 break;
	 }
 }

 CMissionMgr类的实现:

#include "stdafx.h"
#include "MissionMgr.h"


CMissionMgr::CMissionMgr()
{
	creatAllMission();
}


CMissionMgr::~CMissionMgr()
{
}

void CMissionMgr::creatAllMission()
{
	for (int i = 0; i < 6;i++)
	{
		SMissionDt* pData = g_DataMgr->getMissionDtMgr()->getByID(6001 + i);
		CMission* pMission = new CMission;
		pMission->initMission(pData);
		m_vecMissions.push_back(pMission);
	}
}

vector<CMission*> CMissionMgr::getUnlockMission()
{
	vector<CMission*>vecUnlockMission;
	for (int i = 0; i < m_vecMissions.size();i++)
	{
		if (m_vecMissions[i]->getisUnlock()==true)
		{
			vecUnlockMission.push_back(m_vecMissions[i]);
		}
	}
	return vecUnlockMission;
}

vector<CMission*> CMissionMgr::getRecivedMission()
{
	vector<CMission*>vecRecivedMission;
	for (int i = 0; i < m_vecMissions.size();i++)
	{
		if (m_vecMissions[i]->getisRecived()==true)
		{
			vecRecivedMission.push_back(m_vecMissions[i]);
		}
	}
	return vecRecivedMission;
}

CMission* CMissionMgr::getMission(int nID)
{
	for (int i = 0; i < m_vecMissions.size();i++)
	{
		if (nID==m_vecMissions[i]->getID())
		{
			return m_vecMissions[i];
		}
	}
	return nullptr;
}

CReceivedMission类:

#include "stdafx.h"
#include "RecivedMission.h"


CRecivedMission::CRecivedMission()
{
}


CRecivedMission::~CRecivedMission()
{
}

void CRecivedMission::updata()
{
	if (KEY_DOWN(VK_UP))
	{
		m_nIndex--;
		if (m_nIndex < 0)
		{
			m_nIndex = m_vecRecivedMission.size() - 1;
		}
	}
	else if (KEY_DOWN(VK_DOWN))
	{
		m_nIndex++;
		if (m_nIndex >m_vecRecivedMission.size() - 1)
		{
			m_nIndex = 0;
		}
	}
	if (KEY_DOWN(VK_ESCAPE))
	{
		g_GameMgr->recoverWnd();
	}
}

void CRecivedMission::onRander()
{
	for (int i = 0; i < m_vecRecivedMission.size(); i++)
	{

		if (i == m_nIndex)
		{
			cout << "->";
		}
		else
		{
			cout << "  ";
		}
		m_vecRecivedMission[i]->showName();
		if (i == m_nIndex)
		{
			cout << "\t";
			m_vecRecivedMission[i]->showDescripe();
			m_vecRecivedMission[i]->showSchedule();
		}
		cout << endl;
	}
}

void CRecivedMission::setMission()
{
	m_vecRecivedMission=g_GameMgr->getMissionMgr()->getRecivedMission();//调用MissionMgr的获取接口,每次进入任务界面时,更新任务数据
}

CMissionNpc类:

#include "stdafx.h"
#include "MissionNpc.h"


CMissionNpc::CMissionNpc()
{
	m_nIndex = 0;
}


CMissionNpc::~CMissionNpc()
{
}

void CMissionNpc::setMissions(int nNpcID)
{
	//每次进入前要把之前的任务清除
	m_vecUnlockedMission.clear();
	vector<CMission*> vecUnlockedMission = g_GameMgr->getMissionMgr()->getUnlockMission();
	for (int i = 0; i < vecUnlockedMission.size();i++)
	{
		if (vecUnlockedMission[i]->getNpcID()==nNpcID)
		{
			m_vecUnlockedMission.push_back(vecUnlockedMission[i]);
		}
	}
	
}

void CMissionNpc::updata()
{
	if (KEY_DOWN(VK_UP))
	{
		m_nIndex--;
		if (m_nIndex < 0)
		{
			m_nIndex = m_vecUnlockedMission.size() - 1;
		}
	}
	else if (KEY_DOWN(VK_DOWN))
	{
		m_nIndex++;
		if (m_nIndex >m_vecUnlockedMission.size() - 1)
		{
			m_nIndex = 0;
		}
	}
	if (KEY_DOWN(VK_ESCAPE))
	{
		g_GameMgr->recoverWnd();
	}
	if (KEY_DOWN(VK_RETURN))
	{
		updataMission();
	}
}

void CMissionNpc::onRander()
{
	for (int i = 0; i < m_vecUnlockedMission.size();i++)
	{
		
		if (i==m_nIndex)
		{
			cout << "->";
		}
		else
		{
			cout << "  ";
		}
		m_vecUnlockedMission[i]->showName();
		if (i==m_nIndex)
		{
			cout << "\t";
			m_vecUnlockedMission[i]->showDescripe();
		}
		cout << endl;
	}
}

void CMissionNpc::updataMission()
{
	if (!m_vecUnlockedMission.empty())
	{
		//如果当前任务已经接受.
		if (m_vecUnlockedMission[m_nIndex]->getisRecived())
		{
			//更新任务状态
			m_vecUnlockedMission[m_nIndex]->updataIsAchieve();
			if (m_vecUnlockedMission[m_nIndex]->getisAchieve())
			{
				if (!m_vecUnlockedMission[m_nIndex]->getFinishTalk()->getIsTalked())
				{
					//进行完成任务时候的对话

					g_GameMgr->changWnd(m_vecUnlockedMission[m_nIndex]->getFinishTalk());
				}
				else
				{
					m_vecUnlockedMission[m_nIndex]->getReward();
					//将任务从待接任务中移除。
					SAFE_DELET(m_vecUnlockedMission[m_nIndex]);
					m_vecUnlockedMission.erase(m_vecUnlockedMission.begin() + m_nIndex);
					//回到地图
					g_GameMgr->recoverWnd();
				}
			}
			else
			{
				cout << "请去完成任务再来获取奖励" << endl;
			}
		}
		//如果当前任务并未接受
		else
		{
			
			//男人的任务
			if (m_vecUnlockedMission[m_nIndex]->getID() == 6005)
			{
				g_GameMgr->getGameMap()->getplayer()->getPackage()->addItem(g_DataMgr->getIteamDtMgr()->getByID(3012));
			}
			//女人的任务
			else if (m_vecUnlockedMission[m_nIndex]->getID() == 6006)
			{
				g_GameMgr->getGameMap()->getplayer()->getPackage()->addItem(g_DataMgr->getIteamDtMgr()->getByID(3014));
			}
			//按下return键位,接受当前任务,将该任务是否被接受设置为被接受,将当前任务目标置零,是否完成置为false
			m_vecUnlockedMission[m_nIndex]->setisRecived(true);
			g_GameMgr->getGameMap()->getplayer()->setKillEnemyNumToZero(m_vecUnlockedMission[m_nIndex]->getID());
			m_vecUnlockedMission[m_nIndex]->setisAchieve(false);
			//进行接受任务时候的对话
			if (!m_vecUnlockedMission[m_nIndex]->getTalk()->getIsTalked())
			{
				g_GameMgr->changWnd(m_vecUnlockedMission[m_nIndex]->getTalk());
			}
			///*回到地图界面*/
			//g_GameMgr->recoverWnd();
			
		}
	}
}

 待改进:

任务分为:对话任务,杀怪任务,购买物品任务。

杀怪任务和购买物品可以写成同一种任务:判断玩家背包中是否有足够的相对应的物品(红药水数量、杀某种怪掉落的物品数量),从而判断任务是否完成。对话任务也可以判断玩家背包中是否拥有某一种物品,来判断是否完成任务。所以任务类的任务是否完成可以封装成一个函数,通过传入需要完成任务的物品ID和需要的数量,来判断是否完成。这样,任务的数据就可以配备在表中,而不是我现在这样写死的方式。

 

 

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值