[cocos2dx学习笔记]用cocos2dx3.X完成塔防游戏王国保卫战--防御塔(二)之初级箭塔

[cocos2dx学习笔记]用cocos2dx3.X完成塔防游戏王国保卫战--防御塔(二)之初级箭塔,第1张

概述首先我们先观察下这个游戏的箭塔   这个游戏的箭塔都是拥有两个弓箭手。以初级塔为例,左右两边分别有两个弓箭手,可以攻击不同的目标,并且同时只有一个弓箭手在攻击。根据这个特性我们写一个BaseArrowTower class BaseArrowTower: public BaseTower{public:protected: Sprite* shooter_1;//弓箭手1号 Sprit

首先我们先观察下这个游戏的箭塔


这个游戏的箭塔都是拥有两个弓箭手。以初级塔为例,左右两边分别有两个弓箭手,可以攻击不同的目标,并且同时只有一个弓箭手在攻击。根据这个特性我们写一个BaseArrowTower

class BaseArrowTower: public Basetower{public:protected:	Sprite* shooter_1;//弓箭手1号	Sprite* shooter_2;//弓箭手2号	Sprite* towerBase;//塔	int shoottag;//弓箭手标记	voID initTower(int level);//初始化弓箭塔	voID addTerrain();//添加塔坯子(就是那个都是塔下面那个都是弓箭的地面,不同地图有不同的坯子~)	virtual Bullet* ArrowTowerBullet();//生成弓箭	virtual voID shoot(float dt);//射!};


现在让我们看下防御塔建造过程:

1.选择建造类型

2.执行建造动画(进度条,冒烟等)

3.去除动画精灵,添加防御塔

4.开始攻击

同样用1级箭塔举例

class SimpleArrowTowerlvl1: public BaseArrowTower{public:	bool init();//初始化        CREATE_FUNC(SimpleArrowTowerlvl1);	voID updatetower();//升级	voID showUpdateMenu();//显示升级菜单	Bullet* ArrowTowerBullet();//生成弓箭private:	voID buildingAnimation();//开始建造动画	voID buildingSmokeAnimation(float dt);};

其中init()函数会由BaseArrowTower中的CREATE_FUNC宏自动执行,在init()中依次初始化各个参数,并且执行建造动画buildingAnimation

其中建造动画就是添加进度条、建造动画精灵等动作

voID SimpleArrowTowerlvl1::buildingAnimation(){    auto building = Sprite::create();    auto constructing = Sprite::createWithSpriteFramename("tower_constructing_0004.png");    auto hpBgSprite = Sprite::createWithSpriteFramename("buildbar_bg.png");    hpBgSprite->setposition(Point(constructing->getContentSize().wIDth / 2,constructing->getContentSize().height /2+10));    auto hpbar = Progresstimer::create(Sprite::createWithSpriteFramename("buildbar.png"));    hpbar->setType(Progresstimer::Type::bar);    hpbar->setMIDpoint(Point(0,0.5f));    hpbar->setbarChangeRate(Point(1,0));    hpbar->setPercentage(0);    hpbar->setposition(Point(hpBgSprite->getContentSize().wIDth / 2,hpBgSprite->getContentSize().height / 2 ));    hpBgSprite->addChild(hpbar);    constructing->addChild(hpBgSprite);    building->addChild(constructing);    addChild(building);    hpbar->runAction(Sequence::create(Progressto::create(0.5f,100),CallFuncN::create(CC_CALLBACK_0(Sprite::removeFromParent,building)),NulL));    scheduleOnce(schedule_selector(SimpleArrowTowerlvl1::buildingSmokeAnimation),0.5f);}
hpbar->runAction(Sequence::create(Progressto::create(0.5f,NulL));是执行一个动画序列,首先是执行进度条的动画,时间0.5秒,从0-100,再执行removeFromParent将建造动画精灵移除。

再延迟0.5S执行scheduleOnce(schedule_selector(SimpleArrowTowerlvl1::buildingSmokeAnimation),0.5f);执行一个冒烟动画然后将塔添加进去(当然这里也可以写到上面的动画序列当中)

voID SimpleArrowTowerlvl1::buildingSmokeAnimation(float dt){    auto smoke = Sprite::createWithSpriteFramename("effect_buildSmoke_0001.png");    addChild(smoke,99);    smoke->runAction(Sequence::create(		Animate::create(AnimationCache::getInstance()->getAnimation("build_smoke")),smoke)),NulL));    SoundManager::playArcherReady();    initTower(1);    setListener();    schedule(schedule_selector(SimpleArrowTowerlvl1::shoot),1.0f);}
并在1S后开始执行shoot攻击敌人
voID BaseArrowTower::shoot(float dt){    auto instance = GameManager::getInstance();    checkNearestMonster();    char temp1[20];     sprintf(temp1,"level%d_shoot_down",level);     char temp2[20];     sprintf(temp2,"level%d_shoot_top",level);//根据等级生成图片名,保存临时变量    if(nearestMonster!=NulL && nearestMonster->getCurrHp() > 0 )    {	auto currBullet = ArrowTowerBullet();	Point shootVector = nearestMonster->baseSprite->getposition() - this->getParent()->getposition();//怪物精灵是在地图上添加的,而塔的父精灵才是在地图上添加的,所以要统一标准计算        //计算防御塔与敌人之间的角度	float startAngle = currBullet->getRotation();	float endAngle = 0;	auto pVectr = currBullet->getposition()-shootVector;        float angleradians=atan(pVectr.y/pVectr.x);        float angledegrees = CC_radians_TO_degrees(angleradians);			if(shootVector.x - currBullet->getposition().x<=0)//敌人在坐标,需要向左攻击	{	    startAngle = startAngle + abs(angledegrees);//初始弓箭角度	    endAngle = -90;//弓箭结束角度,向下,即插入地面	    if(shoottag == 1)//轮到1号弓箭手	    {		currBullet->setposition(Point(0,30));//子d设置在弓箭手所在位置			shooter_1->setFlippedX(true);//X轴翻转,即面向左边		if(shootVector.y - currBullet->getposition().y<=0)		{		    //执行攻击动画,AnimationCache是自定义的动画类,会根据传入图片名生成帧动画		    shooter_1->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(temp1)));		}else{		    shooter_1->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(temp2)));		}		    shoottag = 2;		}		    else//轮到2号弓箭手		{		    currBullet->setposition(Point(10,30));				    shooter_2->setFlippedX(true);		    if(shootVector.y - currBullet->getposition().y<=0)		    {			shooter_2->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(temp1)));		    }else{			shooter_2->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(temp2)));		    }			shoottag = 1;		    }		}else//敌人在右边,其他同上		{		    startAngle = startAngle - abs(angledegrees);		    endAngle = 270;		    if(shoottag == 1)		    {			currBullet->setposition(Point(0,30));					shooter_1->setFlippedX(false);			if(shootVector.y - currBullet->getposition().y<=0)			{			    shooter_1->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(temp1)));			}else{			    shooter_1->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(temp2)));			}			    shoottag = 2;			}		    else		    {			currBullet->setposition(Point(10,30));					shooter_2->setFlippedX(false);			if(shootVector.y - currBullet->getposition().y<=0)			{			    shooter_2->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(temp1)));			}else{			    shooter_2->runAction(Animate::create(AnimationCache::getInstance()->getAnimation(temp2)));			}			    shoottag = 1;			}		}		//贝叶斯弧线		ccBezIErConfig bezIEr;		if(shoottag == 1)//播放射箭音效		    SoundManager::playArrowShoot1();		else		    SoundManager::playArrowShoot2();		//计算贝叶斯曲线的两个控制点		bezIEr.controlPoint_1 = Point(currBullet->getposition().x,currBullet->getposition().y+200); 		bezIEr.controlPoint_2 = Point(shootVector.x,shootVector.y+200);; 		bezIEr.endposition = shootVector;		auto action = Spawn::create(BezIErTo::create(0.5f,bezIEr),Rotateto::create(0.5f,endAngle),NulL);		//攻击动画传递弓箭		currBullet->setBulletAction(action);		currBullet->shoot();		currBullet = NulL;	}}
根据角度使用ccBezIErConfig类来生成BezIErTo移动动画,是一个弧线,具体内容百度的到

然后用Spwan将BezIErTo与弓箭旋转动画合成为一个action,将action传递给子d类,由子d类具体执行,为何不在塔类中执行,将在子d章节中讲解。

执行子d类的shoot,攻击动画完成

总结

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

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

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存