cocos2dx 植物大战僵尸 12 僵尸卡片

本文介绍了一种游戏机制,通过设置关卡中的属性来区分游戏主角是植物还是僵尸,并据此调整游戏开始时的行为。实现了植物卡片和僵尸卡片的选择流程,包括卡片加载、移动动画及开始游戏的逻辑。

以前的代码中我们是通过在tmx中设置的一个属性来判断当前的游戏主角是植物还是僵尸,如下


上面的card属性,则标识了当前的关卡状态,目前的卡片有两种

1.植物卡片 在开始游戏时会显示出出场的僵尸的种类,然后选择植物卡片,接着游戏开始(这个已经实现)

2.僵尸卡片 选择僵尸卡片(和选择植物卡片类似),然后直接开始游戏

我在LevelLayer中新增了一个枚举为

/*关卡卡片类型*/
enum class LevelCardType
{
	Plant,
	Zombie,
};
bool GameScene::init()
{
	//...
	//根据当前关卡类型决定是否进行移动
	this->levelLoadCallback();
	return true;
}
在GameScene::init()中的LevelLayer有一个向左移动的动作,目前移到levelLoadCallback().修改后的levelLoadCallback()函数

void GameScene::levelLoadCallback()
{
	//获取当前的关卡状态
	auto levelType = this->getLevelCardShowType();
	//向右移动,之后回调函数
	Size visibleSize = Director::getInstance()->getVisibleSize();
	auto size = m_pLevelLayer->getContentSize();
	//当前是植物,则向左移动,出现卡片
	if (levelType == LevelCardType::Plant)
	{
		auto move = MoveTo::create(3.f,visibleSize.width - size.width);
		CallFunc*end = CallFunc::create([this,levelType]()
		{
			this->loadCard(levelType);
		});
		auto seq = Sequence::createWithTwoActions(move,end);
		m_pLevelLayer->runAction(seq);
	}//当前是僵尸,直接开始游戏
	else if (levelType == LevelCardType::Zombie)
	{
		this->loadCard(levelType);
	}
}
之后会判断LevelLayer是否会有一个向左的动作,之后回调loadCard()函数(顾名思义,就是加载卡片函数),目前还没实现卡片选择界面

void GameScene::loadCard(LevelCardType levelType)
{
	//获取当前的数目和卡槽数目
	auto cardVesselNum = DynamicData::getInstance()->getCardVesselNum();
	vector<string> ownCards;
	//开始位置
	Point startPos(50.f,50.f);

	if (levelType == LevelCardType::Plant)
	{
		ownCards = DynamicData::getInstance()->getNameOfPlantCards();
	}
	else if (levelType == LevelCardType::Zombie)
	{
		ownCards = DynamicData::getInstance()->getNameOfZombieCards();
		Size visibleSize = Director::getInstance()->getVisibleSize();
		
		startPos.x = visibleSize.width - startPos.x;
	}
	else
	{
		return;
	}
	//不显示卡片选择界面
	if (ownCards.size() <= cardVesselNum)
	{
		//添加卡片
		for (unsigned int i = 0;i < ownCards.size();i++)
		{
			//推导位置 todo
			auto pos = startPos + Point(0,i*60.f);
			m_pCardLayer->addCard(ownCards.at(i),CardType::Common,pos);
		}
		this->levelStart(levelType);
	}
	else//显示卡片选择界面
	{
	}
}
DynamicData里增加了个函数

vector<string>& DynamicData::getNameOfPlantCards()
{
	return m_plants;
}

vector<string>& DynamicData::getNameOfZombieCards()
{
	return m_zombieCards;
}
就是获取当前已经获取的植物和僵尸的卡片

接着就是在cards.plist中增加僵尸卡片的一些内容

    <!--普通僵尸-->
    <key>Zombie</key>
    <dict>
      <key>desc</key>
      <string></string>
      <key>worth</key>
      <integer>50</integer>
      <key>CD</key>
      <real>7.5</real>
      <key>ready time</key>
      <real>0</real>
      <key>active</key>
      <string>all</string>
      <key>needful terrain</key>
      <array>
        <string>Lawn</string>
      </array>
    </dict>

需要注意的是,僵尸目前的地形暂时用不到,留着以后扩展使用。

levelStart()函数

void GameScene::levelStart(LevelCardType levelType)
{
	if (levelType == LevelCardType::Plant)
	{
		//镜头向左回转,之后开始游戏
		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);
	}
	else if (levelType == LevelCardType::Zombie)
	{
		this->scheduleUpdate();
	}

	//进行对象层的解析
	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);
		}
	}
	//设置僵尸行走路径
	m_pZombieLayer->setZombiePaths(m_pLevelLayer->getZombiePaths());
}

同样进行了判断(暂时就这么实现吧)

编译,运行结果如下



可以看到右上角会有僵尸卡片
另外,目前的代码是可以在关卡开始时实现植物的嵌套,不过需要注意,嵌套的植物需要在逻辑上是有先后顺序的,即如果是水面,一定得是先有睡莲,然后才能种植一些其他的植物,要不然肯定不会种植成功,这个需注意。关于逻辑上的先后顺序,其实就是游戏中读取这些对象的先后顺序,如下为tmx文件

 <objectgroup name="entity object layer">
  <object id="66" name="LilyPad" type="plant" x="290" y="304"/>
  <object id="67" name="LilyPad" type="plant" x="291" y="383"/>
  <object id="68" name="SunFlower" type="plant" x="297" y="321"/>
  <object id="69" name="SunFlower" type="plant" x="852" y="223"/>
 </objectgroup>
这个就是这些对象的存储,id为66的睡莲是先创建的,id为68的向日葵是第三个创建的,所以能创建成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值