寒冰射手是我目前感觉比较难的植物,因为这个植物的子弹会给僵尸一个减速的debuff的,而这个debuff对有的僵尸 起作用,比如一般的僵尸,而对带有报纸的僵尸或者一些特殊的僵尸也是不会减速的,所以饰品需要以下两个功能

1.吸收伤害

2.吸收一些debuff

因为c++无法有两个返回值,所以就不能使用返回值了,对于c++,可以使用引用来改变伤害值和当前攻击类型。先对当前的饰品基类进行改变。

class Garnishry : public Entity
{
public:enum class Type{Common,//普通饰品Iron,//铁质饰品};SDL_SYNTHESIZE(int,m_nHitPoint,HitPoint);//当前血量SDL_SYNTHESIZE(Type,m_type,Type);//饰品类型
public:Garnishry();~Garnishry();/**吸收伤害值*baseDamage attackType可能会改变*/virtual void absorbDamage(int &baseDamage,AttackType &attackType);

路障和报纸需要作一些改变

void Conehead::absorbDamage(int &baseDamage,AttackType &attackType)
{//吸收部分伤害,如果伤害值小于0,强制减少1auto damage = baseDamage - this->getDefense();if (damage < 0){damage = 1;}baseDamage = damage;
}
void Paper::absorbDamage(int &baseDamage,AttackType &attackType)
{int afterDamage = 0;//跟踪性子弹,无法吸收if (Bullet::isTrackBullet(attackType)){afterDamage = baseDamage;}else//吸收伤害TODO{auto afterHP = this->getHitPoint() - baseDamage;//饰品即将死亡if (afterHP <= 0){afterDamage = SDL_abs(afterHP);afterHP = 0;}this->setHitPoint(afterHP);m_pHpBar->setValue((float)afterHP);//如果受到寒冰攻击,转换成正常状态if (attackType == AttackType::Deceleration){attackType = AttackType::Common;}}baseDamage = afterDamage;
}

报纸能使得当前的报纸僵尸免疫减速效果的,这里注意,AttackType增加了一个减速类型,目前的Attack Type如下

enum class AttackType
{Common,/*无效果*/Boom,/*爆炸效果*/Swallow,/*吞噬效果*/Track,/*追踪效果*/Deceleration,/*减速*/TrackAndDeceleration,/*追踪且减速*/
};

这是对以后的一些适配,以后可能还是会修改的。接下来就是僵尸基类的改变了。

void ZombieBase::hurt(int baseDamage,AttackType attackType)
{int afterDamage = baseDamage;//调用饰品,吸收伤害if (m_pGarnishry != nullptr && m_pGarnishry->getHitPoint() > 0){m_pGarnishry->absorbDamage(baseDamage,attackType);afterDamage = baseDamage;//如果饰品死亡,回调饰品死亡函数if (m_pGarnishry->getHitPoint() <= 0)onGarnishryDead();}if (afterDamage <= 0)return ;//进行debuff的操作this->debuff(attackType);auto afterHP = this->getHitPoint() - afterDamage;bool bDead = false;if (afterHP <= 0){afterHP = 0;bDead = true;}this->setHitPoint(afterHP);//设置血量条if (m_pHpBar != nullptr){m_pHpBar->setValue((float)afterHP);}onHurt();//如果死亡,回调死亡函数if (bDead){if (attackType == AttackType::Swallow){onSwallowDead();}else if (attackType == AttackType::Boom){onBoomDead();}else{onNormalDead();}}
}

在这之前还需要添加

/*僵尸的减益效果*/
enum class DebuffType
{Deceleration,
};
typedef struct Debuff
{DebuffType type;float duration;
public:Debuff(DebuffType type,float d):type(type),duration(d){}
}Debuff;

表示当前的减益效果和持续时间。然后需要在ZombieBase种添加一个数组,来保存当前的debuff

vector<Debuff> m_debuffs;//当前的僵尸的debuff

然后添加了两个函数。

 //减速debuff开始动画必须经过Speed包装virtual void onDecelerationDebuffEnter();//减速debuff结束virtual void onDecelerationDebuffExit();
void ZombieBase::debuff(AttackType attackType)
{//TODOif (attackType == AttackType::Deceleration){DebuffType debuffType = DebuffType::Deceleration;auto it = find_if(m_debuffs.begin(),m_debuffs.end(),[debuffType](Debuff debuff){return debuff.type == debuffType;});if (it != m_debuffs.end()){it->duration = 10.f;}else//添加buff{m_debuffs.push_back(Debuff(debuffType,10.f));//回调减速函数this->onDecelerationDebuffEnter();}}
}

同时修改了update的函数。

void ZombieBase::update(float dt)
{//当前僵尸血量小于0,死亡if (this->getHitPoint() <= 0){auto afterCRP = this->getCriticalPoint() - 0.4f;this->setCriticalPoint(afterCRP);//僵尸真正死亡if (afterCRP <= 0.f){onCRPDead();}}else{updateAlive(dt);}//进行debuff的更新for (auto it = m_debuffs.begin();it != m_debuffs.end();){auto &debuff = *it;debuff.duration -= dt;//减速结束if (debuff.duration <= 0.f &&debuff.type == DebuffType::Deceleration){it = m_debuffs.erase(it);this->onDecelerationDebuffExit();}else{it++;}}performMove(dt);
}

在update中进行debuff的更新,如果持续时间到了之后,就回调onDecelrationDebuffExit()函数。

void ZombieBase::onDecelerationDebuffEnter()
{if (m_pSprite){m_pSprite->setColorMod(Color3B(0,255,255));auto action = this->getSprite()->getActionByTag(ANIMATION_TAG);auto speed = dynamic_cast<Speed*>(action);speed->setSpeed(0.7f);}
}void ZombieBase::onDecelerationDebuffExit()
{if (m_pSprite){m_pSprite->setColorMod(Color3B(255,255,255));auto action = this->getSprite()->getActionByTag(ANIMATION_TAG);auto speed = dynamic_cast<Speed*>(action);speed->setSpeed(1.f);}
}

注意,在僵尸减速时会使得动画播放会变得很慢,所以需要内部动画使用Speed进行封装(Speed使用了装饰者模式),这个需要在子类中进行定义每个动画的tag必须是ANIMATION_TAG,并且是Speed才行。

float ZombieBase::getCurSpeed()const
{auto speed = m_fBaseSpeed;//减速成三分之二if (this->isDuringDeceleration()){speed = speed /3.f * 2.f;}return speed;
}

获取当前的速度收到减速的影响,会减速到原来的三分之二

bool ZombieBase::isDuringDeceleration()const
{auto it = find_if(m_debuffs.begin(),m_debuffs.end(),[](Debuff debuff){return debuff.type == DebuffType::Deceleration;});if (it != m_debuffs.end()){return true;}return false;
}

表示当前是否存在减速状态。然后需要在子类僵尸中进行更新动画,以报纸僵尸为例。

bool PaperZombie::init(const string&zombieName)
{//正常动画this->setZombieName(zombieName);//获取站立状态贴图int status = m_bIsAngry ? 0 : 1;auto animationName = StringUtils::format("%sWalk%d",m_zombieName.c_str(),status);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(size.width/2,size.height/2);this->setContentSize(size);this->addChild(m_pSprite);//运行站立动画auto animate = Animate::create(animation);Speed*speed = Speed::create(animate,1.f);speed->setTag(ANIMATION_TAG);m_pSprite->runAction(speed);//设置为行走状态m_state = State::Walk;return true;
}

同时在

 virtual void changeState(State state);virtual void showZombieHead();virtual float getCurSpeed()const;virtual void onGarnishryDead();

也是需要上面的更新。

float PaperZombie::getCurSpeed()const
{auto speed = ZombieBase::getCurSpeed();if (m_bIsAngry)speed *= 2.f;return speed;
}

当前速度受到了减速效果,同时也会加速的。然后就是寒冰子弹的实现了,寒冰子弹的实现类似于一般的豌豆子弹,只是死亡动画不同,不再叙述。

SnowPeaBullet*BulletLayer::addSnowPeaBullet()
{//设置基础属性auto bullet = SnowPeaBullet::create();bullet->setDead(false);bullet->setAttackType(AttackType::Deceleration);bullet->setHitPoint(1);m_bullets.push_back(bullet);return bullet;
}

本节游戏截图。

cocos2dx 植物大战僵尸 22 寒冰射手相关推荐

  1. 第5课python植物大战僵尸-添加豌豆射手类

    提示:第5课python植物大战僵尸-添加豌豆射手类 文章目录 摘要 一.豌豆射手类 Peashooter 1.import导入pygame模块 2.定义一个豌豆射手的类型,不用继承任何的类 3.定义 ...

  2. scratch中的植物大战僵尸之豌豆射手收集豌豆

    这是一个简单的案例,主要的是运用植物大战僵尸里面的素材去做到一个好玩的小游戏,这个游戏的概念是教会小学生怎样运用一些变量还有数学中的知识,例如有负数和坐标的概念,下面我来展示一下我的这个案例: 有的小 ...

  3. cocos2dx 植物大战僵尸 5 塔基Terrain的更新

    以前的代码中并有设置行数这个概念,但是植物大战僵尸这个游戏里确实是有一个概念的,那怎么设置行数呢?个人认为,每一行都有一个僵尸的行走路径,并且路径之间是不交叉的,那么我们就可以先生成路径,然后在生成t ...

  4. cocos2dx 植物大战僵尸 18 土豆雷

    土豆雷是我打植物大战僵尸时喜欢使用的植物,它能保证在开局时能快速地种植植物.今天就实现土豆雷. 土豆雷有一个准备时间,在准备时间完成前不具有任何攻击力.以后破土,能够炸死小范围的僵尸,之后土豆雷死亡. ...

  5. cocos2dx 植物大战僵尸 17 路障僵尸

    原版植物大战僵尸的路障是饰品,能阻挡一部分伤害,在路障掉落前路障僵尸是不会受伤的. 如下为个人头脑风暴. 路障僵尸使用装饰者的话,需要继承自ZombieBase,由于图片原因,所以内部需要有一个普通僵 ...

  6. 【Unity植物大战僵尸】豌豆射手子弹发射逻辑(十三)

    目录 23.子弹导入及其初始化 24.子弹逻辑完善 测试 23.子弹导入及其初始化 导入子弹素材 在Bullet游戏对象上添加相关组件 既然子弹具有碰撞体,那么僵尸也得有碰撞体 新建Zombie的Ta ...

  7. cocos2dx 植物大战僵尸 20 卷心菜投手

    在实现卷心菜投手前,需要对以前的代码进行稍微地调整.因为以前仅仅实现了豌豆射手,所以不需要关注第一个僵尸的位置,而卷心菜投手就不同了,它是锁定第一个最靠近的僵尸,然后进行攻击的,所以需要对僵尸进行x轴 ...

  8. cocos2dx 植物大战僵尸 10 铲子的实现

    铲子的作用是移除植物,而且铲子是和卡片互斥的,即点击了卡片,再点击铲子时会取消卡片的选中,反之亦然,接下来看看铲子的实现吧 class Shovel : public Entity { private ...

  9. cocos2dx 植物大战僵尸 8 植物类和向日葵的小更新

    这次实现容器类的植物,即睡莲和花盆 不过在写之前,需要重写下以前的Plant代码. /*植物类型*/ enum class PlantType {Common,//普通类植物Vessel,//容器类植 ...

最新文章

  1. ActiveMQ消息中间件简明笔记(1)——理论知识点整理
  2. 每周分享五个 PyCharm 使用技巧(一)
  3. BZOJ5249: [2018多省省队联测]IIIDX(线段树 贪心)
  4. swift UI专项训练20 WebView浏览器
  5. WebView 在 APP 中的使用
  6. 通过通用数据访问扩展AWS生态系统
  7. Python学习笔记三
  8. git 命令 clone分支的代码
  9. 编写高质量代码的十个秘诀(转)
  10. pytorch macos_Windows,Linux和MacOS上的PyTorch安装
  11. R+python︱XGBoost极端梯度上升以及forecastxgb(预测)+xgboost(回归)双案例解读
  12. 关于本地缓存localstorage与sessionStorage 数组 (array)字符串(string) 对象(object)的存储技巧和注意事项...
  13. oracle讲师视频教程,赵强老师:Oracle数据库系列视频课程
  14. java用dockerfile生成镜像_【HAVENT原创】创建 Dockerfile 生成新的镜像,并发布到 DockerHub...
  15. win7没有显示wifi连接到服务器,Win7笔记本电脑搜不到无线网络(Wifi)怎么办?...
  16. Nginx事件管理之epoll模块
  17. Psychtoolbox刺激呈现方式
  18. 说一下字典的:addEntriesFromDictionary用法
  19. 【C语言常识】Keil MDK的分散加载文件.sct
  20. 爬虫爬取糗事百科段子

热门文章

  1. easyui datagrid 悬浮事件
  2. PVN3D 配置过程(适用ubuntu20,适用30系显卡)
  3. linux如何修改文件权限
  4. 为何网红都用iPhone?因为安卓在拍照方面一直落后
  5. linux查oracle端口被占用,Linux查看端口占用及对应进程号
  6. 颠倒二进制[位运算]
  7. Ogre水面倒影的实现
  8. Word 怎么画三线表
  9. Intellij IDEA的代码提示功能如何设置
  10. word中参考文献的引用方法