[cocos2dx学习笔记]用cocos2dx3.X完成塔防游戏王国保卫战--子d(一)

[cocos2dx学习笔记]用cocos2dx3.X完成塔防游戏王国保卫战--子d(一),第1张

概述有了防御塔没有子d类是不能攻击敌人的,所以接着来讨论子d,新建一个子d基类Bullet.h class Bullet : public Sprite{public: Bullet(); ~Bullet(); virtual bool init(); CREATE_FUNC(Bullet);protected: CC_SYNTHESIZE(int, m

有了防御塔没有子d类是不能攻击敌人的,所以接着来讨论子d,新建一个子d基类Bullet.h

class Bullet : public Sprite{public:    Bullet();    ~Bullet();    virtual bool init();    CREATE_FUNC(Bullet);protected:    CC_SYNTHESIZE(int,maxForce,MaxForce);//攻击力    CC_SYNTHESIZE(int,bulletScope,BulletScope);//塔的子d攻击范围    CC_SYNTHESIZE(int,bulletType,BulletType);//子d类型    CC_SYNTHESIZE(Spawn*,bulletAction,BulletAction);//子d飞行动画    Sprite* sprite;//子d精灵-贴图    virtual voID shoot(){};//攻击    virtual voID removeBullet(){};//攻击完毕后移除};

在基类中我们定义了一些共有的方法和属性,然后根据不同的子d来重写它

例如上一篇提到的初级箭塔的弓箭,我们需要重写init()来给精灵贴上弓箭这张图片(arrow.png在pList里,实现加载过该pList,具体加载过程见开始动画章节)

bool Arrow::init(){    if (!Sprite::init())    {	return false;    }    sprite = Sprite::createWithSpriteFramename("arrow.png");    addChild(sprite);		    return true;}
然后重写shoot(),弓箭的攻击动作最简单,新建一个动画序列,先执行箭塔根据自身位置和敌人位置生成的弧线和弓箭自身旋转的动画,然后执行removeBullet
voID Arrow::shoot(){    SoundManager::playArrowRelease();//播放音效    runAction(Sequence::create(bulletAction,CallFuncN::create(CC_CALLBACK_0(Arrow::removeBullet,this)),NulL));}
其中弓箭在执行完上述动画后,若此时弓箭所在位置与敌人位置重叠即击中敌人,则根据攻击力减少敌人血量,弓箭所在的区域如下:

auto bulletRect = Rect(

this->getpositionX() +this->getParent()->getpositionX() - this->getContentSize().wIDth /2,

this->getpositionY() +this->getParent()->getpositionY() - this->getContentSize().height/2,

this->sprite->getContentSize().wIDth,

this->sprite->getContentSize().height );

因为弓箭是由防御塔创建并且添加在防御塔建造点那个精灵上上,所以需要通过this->getParent()->getpositionX()先来获取防御塔X轴所在的位置,this->getpositionX() 即子d相对于防御塔的X轴位置,两者相加即子d在地图所在的位置,Y轴同理,根据宽高计算相应的区域。

然后我们遍历保存在单例中的敌人,若区域重叠,则判断集中,进行更新敌人血量、执行喷血(血腥~)动画等动作。

具体思路来自于cocos2dx官网《贼来了》这款教程,但不同的是他将子d的动画与击中敌人等动作由地图类完成,通过每一帧来判断是否集中敌人,这样方案在2D平面中可行,因为这款游戏是2.5D的,弓箭有一个飞到最高点并下落的过程,所以必须由其自身执行,并在其动画结束在判断。、

若为集中敌人,有一个弓箭插在地上并且等待若干时间后消失的动画

voID Arrow::removeBullet(){	bool isMissed = true;//判断是否击中,默认未击中        auto instance = GameManager::getInstance();   	auto bulletRect = Rect(this->getpositionX() +this->getParent()->getpositionX() - this->getContentSize().wIDth /2,this->getpositionY() +this->getParent()->getpositionY() - this->getContentSize().height/2,this->sprite->getContentSize().wIDth,this->sprite->getContentSize().height );		auto monsterVector = instance->monsterVector;        //遍历	for (int j = 0; j < monsterVector.size(); j++)	{		auto monster = monsterVector.at(j);		auto monsterRect = monster->baseSprite->getBoundingBox();		//判断是否重叠并且可以被士兵击中,即不在地下(有种地下的敌人无法被射中)			if (monsterRect.intersectsRect(bulletRect) && monster->getAttackBySoldIEr())		{			auto currHp = monster->getCurrHp();			currHp =  currHp - this->getMaxForce() + monster->getArmor();//                			if(currHp <= 0){				currHp = 0;			}			monster->setCurrHp( currHp );			monster->getHpbar()->setPercentage((currHp/monster->getMaxHp())*100);//更新血条			monster->getHurt();                        isMissed = false;  //设为击中  			if(currHp == 0){				monster->death();			}			break;		}	}	if(isMissed){//若未击中		sprite->setSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByname("decal_arrow.png"));		sprite->runAction(Sequence::create(FadeOut::create(1.0f),CallFuncN::create(CC_CALLBACK_0(Bullet::removeFromParent,NulL));	}else{		this->removeFromParent();	}}

这就是最简单的子d类---弓箭,还有其他子d例如炮d、导d甚至震荡波,巫毒图腾等~也是这个思路,只不过动画复杂的鞋


有了地图,防御塔,子d,相信初学者已经可以独立完成这款游戏了,下面将介绍基本怪物类

总结

以上是内存溢出为你收集整理的[cocos2dx学习笔记]用cocos2dx3.X完成塔防游戏王国保卫战--子d(一)全部内容,希望文章能够帮你解决[cocos2dx学习笔记]用cocos2dx3.X完成塔防游戏王国保卫战--子d(一)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/1072561.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存