本次实现关卡中一开始就存在的实体,如屋顶关卡一开始会有花盆,有的关卡中一开始就有墓碑等。首先在tmx中添加一个对象层,名称为entity object layer,保存着这些对象
这个关卡中添加了两个睡莲,可以看到右侧,名称为LilyPad,类型为plant,加上类型是便于以后的扩展,如植物类交给PlantLayer,僵尸类交给ZombieLayer等,目前仅仅实现添加植物。在levelStart()函数里即在画面回转时产生这些植物。
void GameScene::levelStart()
{
//镜头向左回转,之后开始游戏
DelayTime*delayTime = DelayTime::create(0.5f);
MoveTo*move = MoveTo::create(3.f,Point(-100,0));//-100,0
CallFunc*end = CallFunc::create([this]()
{
this->scheduleUpdate();
});
auto seq = Sequence::create(delayTime,move,end,nullptr);
m_pLevelLayer->runAction(seq);
//进行对象层的解析
auto &groups = m_pLevelLayer->getEntityObjects();
for (const auto&value : groups)
{
const auto& object = value.asValueMap();
auto type = object.at("type").asString();
auto name = object.at("name").asString();
auto x = object.at("x").asInt();
auto y = object.at("y").asInt();
//获取对应的terrain
auto terrain = m_pLevelLayer->getClickedTerrain(Point(x,y));
//生成的植物也得符合地形
if (type == "plant")
{
auto card = m_pCardLayer->makeCard(name,CardType::Consumable);
bool bRet = this->tryPlanting(card,terrain);
}
}
}这里使用的还是tryPlanting函数,这里需要一个card和terrain的。逻辑是每次都生成一个card,然后再生成对应的植物,如果以后实现卡片选择界面就可以使用卡片选择界面的card来实现,因为卡片选择界面里有着所有的卡片,只不过没有拥有的卡片是不可点击的罢了。这次新增的makeCard函数,其实就是从原先的addCard分出来的一个函数。
Card*CardLayer::makeCard(const std::string& name,CardType type)
{
Card*card = nullptr;
//获取加载的对应的结构体
auto cardStruct = StaticData::getInstance()->getCardStruct(name);
if (cardStruct == nullptr)
{
return false;
}
if (type == CardType::Common)
{
card = Card::create(name,cardStruct->worth);
//设置准备时间
card->setCurCD(cardStruct->readyTime);
card->setCD(cardStruct->cd);
}
else if (type == CardType::Consumable)
{
card = Card::createConsumableCard(name);
}
//设置一些基础属性
card->setNeedfulTerrains(cardStruct->terrains);
card->setNecessoryItem(cardStruct->necessoryItem);
card->setActiveTime(cardStruct->active);
return card;
}而addCard就简单多了,内部只是调用了makeCard方法
bool CardLayer::addCard(const std::string &name,CardType type,const Point&pos)
{
auto card = this->makeCard(name,type);
card->setPosition(pos);
m_cards.push_back(card);
this->addChild(card);
return true;
}然后添加了移除卡片函数。
void CardLayer::removeCard(Card*card)
{
//当前选中了该卡片,则先取消选中
if (card == m_pSelectedCard)
this->unselectedCard();
auto it = find_if(m_cards.begin(),m_cards.end(),[card](Card*c)
{
return c == card;
});
if (it != m_cards.end())
{
m_cards.erase(it);
card->removeFromParent();
}
}这个函数的作用就是如果选中了卡片,就先取消选中,然后再移除卡片。
效果如下

1699





