cocos2dx 植物大战僵尸 4 太阳

游戏中的场景有的会产生阳光,所以需要在每一个关卡设置一个标识,来确定是否产生阳光,在tmx中添加以下属性


之后在LevelLayer中获取该属性
void LevelLayer::loadProperties()
{
	auto &properties = m_pTiledMap->getProperties();

	for (auto property : properties)
	{
		if (property.first == "produce sun")
		{
			m_bProduceSun = property.second.asBool();
		}
	}
}
然后就是在合适的时间产生阳光
void LevelLayer::update(float dt)
{
	if (!m_bProduceSun)
		return ;
	m_elapsed += dt;
	//产生阳光
	if (m_elapsed >= 16.f)
	{
		m_elapsed -= 16.f;

		Size visibleSize = Director::getInstance()->getVisibleSize();
		Point bornPos = Point(visibleSize.width/2,0);
		float duration = 6.f;
		MoveBy*move = MoveBy::create(duration,Point(0,500.f));

		m_pDelegate->makeSun(25,move,bornPos);
	}
}
目前设置每16秒出现一次太阳,这个间隔时间也可以放到tmx中的。

另外实现了PanelLayet,目前保存了 阳光背景 阳光计数板和一个铲子背景(铲子以后实现),可以用外部文件,也可以使用代码生成(如果使用cocostudio,需要和cocos2dx版本对应),另外,如果使用外部文件的话,还需要获取这些控件,作扩展使用,另一个就是点击阳光后会有有一个移动到阳光计数器板的动作,也是需要获取阳光计数板的位置的

接着就是Product 和ProductLayer的实现
Product就是产品,这里包括 金币 阳光(还有以后扩展的花园模式的道具),都是Product,这些除了贴图不同,还有一个区别就是效果不同(效果在GameScene中判断),所以仅仅实现Product类就行了,然后使用enum来标识不同种类,再在GameScene中判断

生成太阳的方法如下
void ProductLayer::makeSun(int number,FiniteTimeAction*action,const Point&bornPos)
{
	//生成太阳
	Product*sun = Product::create();
	//设置各种属性
	sun->setNumber(number);
	sun->setClicked(false);
	sun->setUpdate(false);
	sun->setDead(false);
	sun->setDuration(10.f);
	sun->setProductType(ProductType::Sun);
	sun->setPosition(bornPos);

	this->addChild(sun);
	m_products.push_back(sun);
	//设置动画
	auto animationName = "Sun";
	auto animation = AnimationCache::getInstance()->getAnimation(animationName);
	//获取第一帧
	auto firstFrame = (animation->getFrames().at(0))->getSpriteFrame();
	//设置贴图
	sun->bindSpriteWithSpriteFrame(firstFrame);
	//根据number设置太阳大小
	if (number < 25)
		sun->getSprite()->setScale(0.5f,0.5f);

	//运行动画和动作
	sun->getSprite()->runAction(Animate::create(animation));

	CallFunc*end = CallFunc::create([sun]()
	{
		sun->setUpdate(true);
	});

	auto seq = Sequence::createWithTwoActions(action,end);
	sun->runAction(seq);
}

在这里我使用了AnimationCache读取的外部动画文件,在使用时直接加载就可以了
enum class ProductType
{
	None,
	Sun,//太阳
	Gold,//金币
};
目前仅仅有太阳和金币这两种
void Product::update(float dt)
{
	//如果死亡或者已经点击过了,则不进行更新
	if (m_bDead || m_bClicked)
		return;
	if (m_bUpdate)
	{
		m_duration -= dt;
		if (m_duration <= 0.f)
			m_bDead = true;
	}
}

这是产品的普遍更新函数,都有一定的存活时间,在时间消耗完后直接消失

目前的触碰到阳光放在了onTouchEnded(),主要是为了点击阳光成功就不会向下执行种植等操作。
void GameScene::onTouchEnded(Touch*touch,SDL_Event*event)
{
	auto pos = touch->getLocation();
	//是否点击了ProductLayer
	auto product = m_pProductLayer->getClickedProduct(pos);
	if (product)
	{
		product->setClicked(true);
		this->collectProduct(product);

		return;
	}
	//...
}
在点击了阳光后会直接返回,不再执行后面的操作
void GameScene::collectProduct(Product*product)
{
	//点击了太阳
	if (product->getProductType() == ProductType::Sun)
	{
		//获取结束位置
		auto endPos = m_pPanelLayer->getSunBgPosition();
		auto deltaPos = product->getPosition() - endPos;

		auto length = deltaPos.length();

		MoveTo*move = MoveTo::create(length/400,endPos);
		CallFunc*end = CallFunc::create([this,product]()
		{
			this->addSun(product->getNumber());
			product->setDead(true);
		});
		auto seq = Sequence::createWithTwoActions(move,end);
		//运行动作
		product->stopAllActions();
		product->runAction(seq);
	}
}

这个结束位置就是获取在PanelLayer获取的阳光计数板背景的位置。






  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
植物大战僵尸游戏需要掌握cocos2d-x引擎的基础知识,包括场景、图层、精灵、动画等,同时还需要了解游戏的规则和逻辑。下面是一个简单的植物大战僵尸游戏的实现思路: 1. 创建游戏场景和游戏图层 2. 加载游戏背景、植物、僵尸等资源 3. 实现植物的种植和僵尸的出现 4. 实现植物攻击僵尸和僵尸攻击植物 5. 实现游戏结束和胜利的判定 具体实现细节可以参考下面的代码示例: 1. 创建游戏场景和游戏图层 ``` auto scene = Scene::create(); auto layer = Layer::create(); scene->addChild(layer); ``` 2. 加载游戏资源 ``` auto bg = Sprite::create("bg.png"); auto sunflower = Sprite::create("sunflower.png"); auto zombie = Sprite::create("zombie.png"); ``` 3. 实现植物的种植和僵尸的出现 ``` auto addSunflower = CallFunc::create([&](){ auto sunflower = Sprite::create("sunflower.png"); sunflower->setPosition(Vec2(100, 100)); layer->addChild(sunflower); }); auto addZombie = CallFunc::create([&](){ auto zombie = Sprite::create("zombie.png"); zombie->setPosition(Vec2(500, 100)); layer->addChild(zombie); }); auto sequence = Sequence::create(addSunflower, DelayTime::create(5.0f), addZombie, nullptr); layer->runAction(RepeatForever::create(sequence)); ``` 4. 实现植物攻击僵尸和僵尸攻击植物 ``` auto sunflowerAttack = CallFunc::create([&](){ // 植物攻击 auto bullet = Sprite::create("bullet.png"); bullet->setPosition(sunflower->getPosition()); layer->addChild(bullet); auto move = MoveTo::create(1.0f, zombie->getPosition()); auto remove = RemoveSelf::create(); bullet->runAction(Sequence::create(move, remove, nullptr)); }); auto zombieAttack = CallFunc::create([&](){ // 僵尸攻击 auto attack = Sprite::create("attack.png"); attack->setPosition(zombie->getPosition()); layer->addChild(attack); auto remove = RemoveSelf::create(); attack->runAction(Sequence::create(DelayTime::create(1.0f), remove, nullptr)); }); auto sunflowerSequence = Sequence::create(sunflowerAttack, DelayTime::create(1.0f), nullptr); sunflower->runAction(RepeatForever::create(sunflowerSequence)); auto zombieSequence = Sequence::create(zombieAttack, DelayTime::create(1.0f), nullptr); zombie->runAction(RepeatForever::create(zombieSequence)); ``` 5. 实现游戏结束和胜利的判定 ``` bool isGameOver = false; bool isGameWin = false; auto checkGameOver = CallFunc::create([&](){ if (isGameOver) { // 游戏结束 // ... } }); auto checkGameWin = CallFunc::create([&](){ if (isGameWin) { // 游戏胜利 // ... } }); auto gameOverSequence = Sequence::create(DelayTime::create(10.0f), checkGameOver, nullptr); auto gameWinSequence = Sequence::create(DelayTime::create(10.0f), checkGameWin, nullptr); layer->runAction(gameOverSequence); layer->runAction(gameWinSequence); ``` 以上就是一个简单的植物大战僵尸游戏的实现思路,具体实现还需要根据自己的需求进行调整和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值