商店功能
一、进入商店:
当条件满足时,游戏状态改为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]);
}
}
}
}
}