cocos2dx 植物大战僵尸 9 容器植物类

在写容器植物类前,需要对Terrain进行一些小小的更新。这次我是把Terrain中提取出Carrier类,让Terrain塔基和容器类植物都继承自这个类,对于Carrier类,添加的内容很少,只是把Terrain以前的代码移动Carrier中就行了

class Carrier
{
        //使用cocos2dx,把SDL改成CC即可
	SDL_SYNTHESIZE(TerrainType,m_terrainType,TerrainType);//该地形的类型
	SDL_BOOL_SYNTHESIZE(m_bDestroyed,Destroyed);//当前的地形是否被毁坏
	SDL_SYNTHESIZE(int,m_nRow,Row);
protected:
	Plant*m_pInnerPlant;
public:
	Carrier();
	~Carrier();

	void setInnerPlant(Plant*plant);
	Plant*getInnerPlant();
};
对于睡莲和花盆,倒是没什么可说的,只是有一个动画而已

class LilyPad : public Plant,public Carrier
{
public:
	LilyPad();
	~LilyPad();
	static LilyPad*create(const string&plantName);
	bool init(const string&plantName);
	virtual void updateHook(float dt,float elapsed);
	virtual void skillHook();
};
睡莲的初始化函数

bool LilyPad::init(const string&plantName)
{
	this->setPlantName(plantName);
	//设置正常动画
	auto animationName = plantName;
	auto animation = AnimationCache::getInstance()->getAnimation(animationName);
	//设置贴图
	auto firstFrame = animation->getFrames().front()->getSpriteFrame();
	m_pSprite = Sprite::createWithSpriteFrame(firstFrame);
	
	auto size = m_pSprite->getContentSize();
	//设置位置
	m_pSprite->setPosition(Point::ZERO);
	m_pSprite->setAnchorPoint(Point::ZERO);

	this->setContentSize(size);
	this->addChild(m_pSprite);
	//设置运行动画
	Animate*animate = Animate::create(animation);
	this->getSprite()->runAction(animate);

	return true;
}
然后更新PlantLayer的makePlant函数,使之能生成睡莲和花盆

	else if (name == FLOWERPOT_NAME)
	{
		plant = m_pPlantFactory->createFlowerPot(name);
	}
	else if (name == LILYPAD_NAME)
	{
		plant = m_pPlantFactory->createLilyPad(name);
		//对莲叶添加一个上下浮动的效果
		MoveBy*move1 = MoveBy::create(1.f,Point(0.f,5.f));
		MoveBy*move2 = MoveBy::create(1.f,Point(0.f,-5.f));

		auto seq = Sequence::createWithTwoActions(move1,move2);
		RepeatForever*repeat = RepeatForever::create(seq);

		plant->runAction(repeat);
	}
睡莲有一个一直重复的向上向下移动效果

然后在LevelLayer中也添加了几个适用于Carrier的函数

	//链式获取最上层的植物
	Plant*getTopPlant(Terrain*terrain);
	//获取植物相邻的容器
	Carrier*getVesselOfPlant(Terrain*terrain,Plant*plant);
	//获取植物的tag
	int getSumOfTagPlant(Terrain*terrain,Plant*plant);
分别看看实现吧

Plant*LevelLayer::getTopPlant(Terrain*terrain)
{
	auto innerPlant = terrain->getInnerPlant();
	while (innerPlant != nullptr
		&& innerPlant->getPlantType() == PlantType::Vessel)
	{
		auto vessel = dynamic_cast<Carrier*>(innerPlant);
		//容器中还存在植物
		if (vessel->getInnerPlant() != nullptr)
		{
			innerPlant = vessel->getInnerPlant();
		}
		else
		{
			break;
		}
	}

	return innerPlant;
}
这个函数是获取的最上层的植物,链式进行获取,如果该植物是容器类植物,则进行动态类型转换,另外,这个不可以使用静态类型转换,因为Carrier和Plant没有关系。

Carrier*LevelLayer::getVesselOfPlant(Terrain*terrain,Plant*plant)
{
	auto innerPlant = terrain->getInnerPlant();

	while (innerPlant != nullptr 
		&& innerPlant->getPlantType() == PlantType::Vessel)
	{
		auto vessel = dynamic_cast<Carrier*>(innerPlant);
		//容器中存在对应的植物
		if (vessel->getInnerPlant() == plant)
		{
			return vessel;
		}
		else
		{
			innerPlant = vessel->getInnerPlant();
		}
	}
	return terrain;
}
这个函数是获取植物所相邻的容器。

比如水面上种睡莲,则该容器是水面。水面上种睡莲,向日葵,那么向日葵的容器就是睡莲。

{
	int tag = 0;
	Carrier*carrier = terrain;

	do
	{
		tag += carrier->getRow();
		auto innerPlant = carrier->getInnerPlant();

		if (plant == innerPlant)
			break;
		else if (innerPlant->getPlantType() == PlantType::Vessel)
			carrier = dynamic_cast<Carrier*>(innerPlant);
		else
			break;

	}while(carrier != nullptr);

	return tag;
}

这个是获取植物对应的tag,是为了便于植物之间的显示确定

bool GameScene::tryPlanting(Card*card,Terrain*terrain)
{
	auto topPlant = m_pLevelLayer->getTopPlant(terrain);
	Plant*newPlant = nullptr;
	Point newPos;
	//获取必要物品
	auto necessaryItem = card->getNecessoryItem();
	//升级植物
	if (!necessaryItem.empty() && topPlant != nullptr
		&& topPlant->getPlantName() == necessaryItem)
	{
		//获取临近容器
		auto vessel = m_pLevelLayer->getVesselOfPlant(terrain,topPlant);
		//创建新植物
		newPlant = m_pPlantLayer->makePlant(card->getCardName());

		newPos = terrain->getPosition();
		//该容器为容器类植物
		if (vessel != terrain)
		{
			auto vesselPlant = dynamic_cast<Plant*>(vessel);
			auto height = topPlant->getContentSize().height;
			auto offsetPos = Point(0.f,-height/2.f);

			newPos = vesselPlant->getPosition() + offsetPos;
			newPlant->setVesselPlant(vesselPlant);
		}

		vessel->setInnerPlant(newPlant);
		//移除旧植物
		m_pPlantLayer->removePlant(topPlant);
		topPlant->removeFromParent();
	}
	//种植植物
	else if (necessaryItem.empty())
	{
		//地形上的植物为空 并且地形符合,则创建
		if (topPlant == nullptr && card->isIncludeTerrain(terrain->getTerrainType()))
		{
			newPlant = m_pPlantLayer->makePlant(card->getCardName());
			//再设置一些基础属性
			newPos = terrain->getPosition();

			terrain->setInnerPlant(newPlant);

			if (newPlant->getPlantType() == PlantType::Vessel)
			{
				dynamic_cast<Carrier*>(newPlant)->setRow(terrain->getRow());
			}
		}
		//存在容器植物,继续判断
		else if(topPlant != nullptr && topPlant->getPlantType() == PlantType::Vessel)
		{
			auto height = topPlant->getContentSize().height;
			auto vessel = dynamic_cast<Carrier*>(topPlant);
			auto offsetPos = Point(0.f,-height/2.f);

			if (card->isIncludeTerrain(vessel->getTerrainType()))
			{
				newPlant = m_pPlantLayer->makePlant(card->getCardName());
				//再设置一些基础属性
				newPos = topPlant->getPosition() + offsetPos;

				vessel->setInnerPlant(newPlant);
				newPlant->setVesselPlant(topPlant);
			}

		}//end else if
		
	}
	//设置基础属性
	if (newPlant != nullptr)
	{
		newPlant->setActiveTime(card->getActiveTime());
		newPlant->setPosition(newPos);
		newPlant->setDelegate(this);
		//添加到entity layer 场景
		auto entityLayer = this->getEntityLayer();
		int tag = m_pLevelLayer->getSumOfTagPlant(terrain,newPlant);

		entityLayer->addChild(newPlant,tag);
	}

	return newPlant != nullptr;
}

tryPlanting又更新了一次,添加了容器植物的相关逻辑

本节截图


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值