控制台RPG游戏具体实现思路:商店功能

商店功能

一、进入商店:

当条件满足时,游戏状态改为E_GAMESTATE_SHOP,将玩家坐标还原(否则,玩家坐标与商店坐标重合,将一直重复进入商店)。处理逻辑写在地图的碰撞中,关键代码:

	//玩家碰到NPC
	vector<CNpc*>vecNpcs = npcMgr->getNpcs();
	for (int i = 0; i < vecNpcs.size(); i++)
	{
		if (m_pPlayer->getRow() == vecNpcs[i]->getRow()
			&& m_pPlayer->getCol() == vecNpcs[i]->getCol()
			&& vecNpcs[i]->getMapID() == m_curMap->nID)
		{
			//玩家坐标还原
			m_pPlayer->playerRestore();
			g_GameMgr->setgameState(E_GAME_SHOP);
			g_GameMgr->getShop()->setIteams(vecNpcs[i]->getID());
		}
	}

二、不同商店陈列不同物品:

物品配置表(ItemDt)里面配有NPCID这一属性,物品数据管理员(CItemDtMgr)的getByNPC()函数,返回一个容器,里面存储了符合该NPC下的所有物品信息,shop的初始化物品信息函数(setItems())从地图中获取npcid并传给数据管理员的getByNPCID()这个函数,并获取到返回的容器。关键代码如下:

物品数据管理员返回符合的商品

vector<SIteamDt*> CIteamDtMgr::getByNpcID(int nNpcID)
{
	vector<SIteamDt*>vecDatas;
	for (int i = 0; i < m_vecIteamDts.size();i++)
	{
		if (m_vecIteamDts[i]->nNpcID==nNpcID)
		{
			vecDatas.push_back(m_vecIteamDts[i]);
		}
	}
	return vecDatas;
}

商店(shop)接受返回的容器

void CShop::setIteams(int nNpcID)
{
	//清空上次使用的容器内容
	m_vecItems.clear();
	m_vecItems = g_DataMgr->getIteamDtMgr()->getByNpcID(nNpcID);
}

当玩家触碰到NPC时,对商店信息进行初始化:

		g_GameMgr->getShop()->setIteams(vecNpcs[i]->getID());

三、商店选择物品:

不同于菜单中的updata函数,不同的商店物品数量不一致,使用固定数据无法实现此功能。但由于商店中的所有物品信息均存在m_vecItems这个容器中,在shop中定义一个成员变量m_nIndex,根据m_nIndex的值即可控制商店中商品的选择以及渲染问题。具体代码如下:

渲染

void CShop::onRander()
{
	for (int i = 0; i < m_vecItems.size();i++)
	{
		if (i == m_index)
		{
			cout << "->";
		}
		else
		{
			cout << "  ";
		}
		cout << m_vecItems[i]->szName << "\t"
			<< m_vecItems[i]->szPic << "\t"
			<< m_vecItems[i]->nPrice <<"\t" 
			<<m_vecItems[i]->nNum<< endl;
	}
}

数据更新(控制选择商品)

if (KEY_DOWN(VK_UP))
	{
		m_index--;
		if (m_index<0)
		{
			m_index = m_vecItems.size() - 1;
		}
	}
	else if (KEY_DOWN(VK_DOWN))
	{
		m_index++;
		if (m_index > m_vecItems.size() - 1)
		{
			m_index = 0;
		}
	}
	if (KEY_DOWN(VK_ESCAPE))
	{
		g_GameMgr->setgameState(E_GAME_MAP);
	}

退出商店:

在商店的数据更新里,当按下esc键时,将游戏状态改为E_GAME_MAP即可退出商店。代码就是上面的最后一段if语句

购买商品:

if (KEY_DOWN(VK_RETURN))
	{
		//如果买得起,将当前项目丢进背包 
		
		if (m_vecItems[m_index]->nNum > 0)
		{
			if (g_GameMgr->getgameMap()->getplayer()->getmoney() > m_vecItems[m_index]->nPrice)
			{
				m_vecItems[m_index]->nNum--;
				g_GameMgr->getgameMap()->getplayer()->changeMoney(-m_vecItems[m_index]->nPrice);
				g_GameMgr->getPackage()->addIteam(m_vecItems[m_index]);
			}
			else
			{
				cout << "滚开,你个死穷鬼!" << endl;
				system("pause");
			}
		}
		else
		{
			cout << "没有库存" << endl;
			system("pause");
		}

	}

所有代码:

头文件:

#pragma once
class CShop
{
public:
	CShop();
	~CShop();
	void updata();
	void onRander();
	void setIteams(int nNpcID);
private:
	int m_nIndex;//用来存储商品索引
	vector<SIteamDt*>m_vecItems;//存放商品
};

源文件:

#include "stdafx.h"
#include "Shop.h"


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


CShop::~CShop()
{
	for (int i = 0; i < m_vecItems.size();i++)
	{
		SAFE_DELET(m_vecItems[i]);
	}
	m_vecItems.clear();
}

void CShop::setIteams(int nNpcID)
{
	//清空上次使用的容器内容
	m_vecItems.clear();
	m_vecItems = g_DataMgr->getIteamDtMgr()->getByNpcID(nNpcID);
}

void CShop::onRander()
{
	for (int i = 0; i < m_vecItems.size();i++)
	{
		if (i == m_nIndex)
		{
			cout << "->";
		}
		else
		{
			cout << "  ";
		}
		cout << m_vecItems[i]->szName << "\t"
			<< m_vecItems[i]->szPic << "\t"
			<< m_vecItems[i]->nPrice <<"\t" 
			<<m_vecItems[i]->nNum<< endl;
	}
}

void CShop::updata()
{
	if (KEY_DOWN(VK_UP))
	{
		m_nIndex--;
		if (m_nIndex<0)
		{
			m_nIndex = m_vecItems.size() - 1;
		}
	}
	else if (KEY_DOWN(VK_DOWN))
	{
		m_nIndex++;
		if (m_nIndex > m_vecItems.size() - 1)
		{
			m_nIndex = 0;
		}
	}
	if (KEY_DOWN(VK_ESCAPE))
	{
		g_GameMgr->setgameState(E_GAME_MAP);
	}
	if (KEY_DOWN(VK_RETURN))
	{
		if (m_vecItems[m_nIndex]->nNum > 0)
		{
			if (g_GameMgr->getgameMap()->getplayer()->getMoney() > m_vecItems[m_nIndex]->nPrice)
			{
				
				m_vecItems[m_nIndex]->nNum--;
				g_GameMgr->getgameMap()->getplayer()->changeMoney(-m_vecItems[m_nIndex]->nPrice);
				//如果是一次性消耗物品,则进入背包,否则进入装备栏
				if (m_vecItems[m_nIndex]->nType == E_ITEM_ONEUSED)
				{
					g_GameMgr->getPackage()->addItem(m_vecItems[m_nIndex]);
				}
				else if (m_vecItems[m_nIndex]->nType > E_ITEM_ONEUSED)
				{
					g_GameMgr->getEquitment()->addEquiepment(m_vecItems[m_nIndex]);
				}
			}
			
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41791653/article/details/81877057
今日推荐