cocos2dx 植物大战僵尸 18 土豆雷
2017-06-07 20:43
337 查看
土豆雷是我打植物大战僵尸时喜欢使用的植物,它能保证在开局时能快速地种植植物。今天就实现土豆雷。
土豆雷有一个准备时间,在准备时间完成前不具有任何攻击力。以后破土,能够炸死小范围的僵尸,之后土豆雷死亡。土豆雷在破土后,每一帧检查是否有僵尸和它发生碰撞,如果有,就炸死小范围的僵尸,然后有一个土豆雷炸过后的特效,以及僵尸有一个变成灰的特效。我的思路是使用一个特殊的子弹Boom,这个子弹并没有贴图,只是负责在一帧之内炸死所有和它发生碰撞的所在行的僵尸,这样一来土豆雷就负责调用API,主要的逻辑就给了Boom和检测是否碰撞的方法。
土豆雷有一个准备时间,在准备时间完成前不具有任何攻击力。以后破土,能够炸死小范围的僵尸,之后土豆雷死亡。土豆雷在破土后,每一帧检查是否有僵尸和它发生碰撞,如果有,就炸死小范围的僵尸,然后有一个土豆雷炸过后的特效,以及僵尸有一个变成灰的特效。我的思路是使用一个特殊的子弹Boom,这个子弹并没有贴图,只是负责在一帧之内炸死所有和它发生碰撞的所在行的僵尸,这样一来土豆雷就负责调用API,主要的逻辑就给了Boom和检测是否碰撞的方法。
class PotatoMine : public Plant { SDL_SYNTHESIZE(float,m_fReadyTime,ReadyTime);//破土时间 SDL_SYNTHESIZE(int,m_nDamage,Damage);//伤害值 private: bool m_bReady;//是否已经准备完成 float m_elapsed; public: PotatoMine(); ~PotatoMine(); static PotatoMine*create(const string&plantName); bool init(const string&plantName); virtual void updateHook(float dt); private: void readySuccess(); void checkCollision(); };看看updateHook()
void PotatoMine::updateHook(float dt) { //当前还没破土 if (!m_bReady) { m_elapsed += dt; //到达破土时间,破土 if (m_elapsed >= m_fReadyTime) { this->readySuccess(); m_elapsed -= m_fReadyTime; } } else { //进行僵尸的检测 this->checkCollision(); } }updateHook()负责逻辑上的更新,并且会在准备完成后判断是否和僵尸碰撞回调函数。
void PotatoMine::checkCollision() { auto row = m_pCarrier->getRow(); auto rect = this->getBoundingBox(); auto pos = this->getPosition(); auto zombie = m_pDelegate->findCollidedZombie(row,rect); //发生碰撞,炸死僵尸 if (zombie != nullptr && zombie->getHitPoint() > 0) { //展示特效 m_pDelegate->showExplosionSpudow(pos); //直接死亡 this->setDead(true); //爆炸 m_pDelegate->addBoom(this->getDamage(),row,rect); } }获取当前行的僵尸并判断是否和僵尸发生碰撞,主要就是findCollidedZombie()函数。
void PotatoMine::readySuccess() { m_bReady = true; //获取破土后的动画 auto animationName = AnimationCache::getInstance()->getAnimation(this->getPlantName()); auto animate = Animate::create(animationName); this->getSprite()->runAction(animate); //显示破土特效 auto pos = this->getPosition(); Size size = this->getContentSize(); m_pDelegate->showRisingDirt(pos + Point(0,size.height/3)); }这个是在破土之后的动画以及破土后的动画
ZombieBase*GameScene::findCollidedZombie(int row,const Rect&rect) { auto zombies = this->getZombiesOfRow(row); ZombieBase *zombie = nullptr; auto it = find_if(zombies.begin(),zombies.end(),[rect](ZombieBase*zombie) { return zombie->getCollisionBoundingBox().intersectsRect(rect); }); if (it != zombies.end()) { zombie = *it; } return zombie; }这里是获取一行的僵尸,然后判断是否和所给的矩形发生碰撞,并返回发生碰撞的第一个僵尸。另外就是并且更新了getZombiesOfRow()函数。
vector<ZombieBase*> GameScene::getZombiesOfRow(int row) { const auto&allZombies = m_pZombieLayer->getZombies(); vector<ZombieBase*> zombies; for (auto mapIter = allZombies.begin();mapIter != allZombies.end();mapIter++) { auto curRow = mapIter->first; auto &lineZombies = mapIter->second; if (row == curRow) { return lineZombies; } else if (row == -1) { copy(lineZombies.begin(),lineZombies.end(),back_inserter(zombies)); } } return zombies; }这里做了一个小小的更新,如果row为-1时则返回所有的僵尸。另外为Bullet添加一个虚函数,负责获取当前的碰撞范围。
//碰撞结束后调用 virtual void contactEnd(); virtual Rect getCollisionBoundingBox()const;实现Boom。另外需要注意,如果跨行直接设置row为-1即可。这样就能很简单地实现樱桃炸弹,窝瓜等植物。
class Boom : public Bullet { SDL_SYNTHESIZE(Rect,m_collisionRect,CollisionRect); public: Boom(); ~Boom(); CREATE_FUNC(Boom); bool init(); virtual void hurt(); virtual void contactEnd(); virtual Rect getCollisionBoundingBox()const; };Boom类似一般的子弹,接下来看看实现
void Boom::hurt() { } void Boom::contactEnd() { //在一帧后死亡 this->setHitPoint(0); this->setDead(true); } Rect Boom::getCollisionBoundingBox()const { return m_collisionRect; }contactEnd函数是在BulletLayer中调用的。
void BulletLayer::checkCollisionBetweenZombieAndBullet(Bullet*bullet) { auto row = bullet->getRow(); auto zombies = m_pDelegate->getZombiesOfRow(row); auto r = bullet->getCollisionBoundingBox(); for (auto it = zombies.begin();it != zombies.end();it++) { auto zombie = *it; if (bullet->isDying()) break; auto rect = zombie->getCollisionBoundingBox(); //僵尸收到伤害 if (r.intersectsRect(rect)) { bullet->hurt(); //僵尸受伤 zombie->hurt(bullet->getDamage(),bullet->getAttackType()); } } //子弹碰撞结束 bullet->contactEnd(); }至于土豆雷在发生碰撞后就直接死亡了,其他显示地全是特效层内容罢了,这里就不贴上了。本节效果图
相关文章推荐
- cocos2dx 植物大战僵尸 10 铲子的实现
- cocos2dx 植物大战僵尸 24 坚果和大坚果
- cocos2dx 植物大战僵尸 14 僵尸的攻击
- cocos2dx 植物大战僵尸 3 卡片
- cocos2dx 植物大战僵尸 5 塔基Terrain的更新
- cocos2dx 植物大战僵尸 12 僵尸卡片
- cocos2dx 植物大战僵尸 16 僵尸的行走死亡和攻击死亡
- cocos2dx 植物大战僵尸 21 塔基的更新
- cocos2dx 植物大战僵尸 6 植物层
- cocos2dx 植物大战僵尸 15 豌豆射手的实现
- cocos2dx 植物大战僵尸 1 简言创建关卡层
- cocos2dx 植物大战僵尸 22 寒冰射手
- cocos2dx 植物大战僵尸 11 场景自带的植物
- cocos2dx 植物大战僵尸 13 僵尸的产生
- cocos2dx 植物大战僵尸 17 路障僵尸
- cocos2dx 植物大战僵尸 23 撑杆僵尸
- cocos2dx 植物大战僵尸 9 容器植物类
- cocos2dx 植物大战僵尸 20 卷心菜投手
- cocos2dx 植物大战僵尸 2 创建卡片层
- cocos2dx 植物大战僵尸 19 读报僵尸