• [置顶] 【cocos2d-x入门实战】微信飞机大战之六:子弹层的处理


    这一篇将处理完子弹层的其他要点。


    1.子弹的初始位置

    子弹的初始位置在飞机的机头位置,因为飞机在游戏的过程中会随着玩家的触摸而改变其位置,所以,子弹的初始位置只能以当前飞机位置为基准进行添加。

    CCPoint planePosition=PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getPosition();
    CCPoint bulletPosition=ccp(planePosition.x,planePosition.y+PlaneLayer::sharedPlane->getChildByTag(AIRPLANE)->getContentSize().height/2);
    bullet->setPosition(bulletPosition);

    还记得当时给飞机加的tag(AIRPLANE)么?通过sharedPlane的getChildByTag就能获取到飞机精灵,然后计算出子弹初始的位置,添加到子弹层。

    其实更为严谨的方式是设计一个子弹管理器,然后在管理器中添加子弹,这里简单的处理,会比较好理解,虽然会影响到编程风格。


    2.子弹的飞行效果

    子弹的飞行效果,很简单,就是往Y方向移动,但是X方向不能改变。所以要注意,已发射的子弹不能随着飞机的移动而跟着移动,一旦这颗子弹发射了,它就是一个独立的个体,不管飞机移动或者爆炸了,它只会按照自己的规则进行运动而不受干扰。

    因为子弹的初始Y位置是不固定的,如果固定死一个时间会导致不同子弹的移动速度不同,所以必须先把每颗子弹的运动时间计算出来。

    float length=CCDirector::sharedDirector()->getWinSize().height+bullet->getContentSize().height/2-bulletPosition.y;//飞行距离,超出屏幕即结束
    float velocity=420/1;//飞行速度:420pixel/sec
    float realMoveDuration=length/velocity;//飞行时间
    
    CCFiniteTimeAction* actionMove=CCMoveTo::create(realMoveDuration,ccp(bulletPosition.x,CCDirector::sharedDirector()->getWinSize().height+bullet->getContentSize().height/2));
    CCFiniteTimeAction* actionDone=CCCallFuncN::create(this,callfuncN_selector(BulletLayer::bulletMoveFinished));//回调一个子弹结束处理函数
    
    CCSequence* sequence=CCSequence::create(actionMove,actionDone);
    bullet->runAction(sequence);


    3.子弹的管理和回收

    cocos2d-x提供了一个很好用的数组类CCArray,它相当于一个容器。我们可以把一些创建出来的精灵放在里面进行管理,在不需要的时候,从中删除它并且从屏幕上删除它(有时候看不见不代表它们已经从屏幕上删除了)。

    因为CCArray::create函数调用了autoRelease,所以我们必须在调用创建后手动进行retain,以免超出使用范围后被释放,同时在析构函数中再进行release防止内存泄漏。

    (1)创建成员变量指针

    CCArray* m_pAllBullet;

    (2)子弹层的构造函数和析构函数

    BulletLayer::BulletLayer(void)
    {
    	m_pAllBullet=CCArray::create();
    	m_pAllBullet->retain();
    }
    
    BulletLayer::~BulletLayer(void)
    {
    	m_pAllBullet->release();
    	m_pAllBullet=NULL;
    }

    (3)子弹飞出屏幕后(即子弹运动结束后,自然消失而不是和敌机碰撞)的调用函数

    void BulletLayer::bulletMoveFinished(CCNode* pSender)
    {
    	CCSprite* bullet=(CCSprite*)pSender;
    	m_pAllBullet->removeObject(bullet);//移除CCArray
    	this->removeChild(bullet,true);//移除屏幕
    }


    4.子弹层其他接口

    (1)开始发射子弹

    void BulletLayer::StartShoot(float delay)//这里使用的是一个缺省函数,为什么这么用,后面会解释到。
    {
    	this->schedule(schedule_selector(BulletLayer::AddBullet),0.01f,kCCRepeatForever,delay);
    }

    (2)停止发射子弹

    void BulletLayer::StopShoot()//卸载任务执行器
    {
    	this->unschedule(schedule_selector(BulletLayer::AddBullet));
    }

    (3)删除某颗子弹

    void BulletLayer::RemoveBullet(CCSprite* bullet)//一旦子弹和敌机碰撞,我们就要删掉这个子弹
    {
    	if (bullet!=NULL)
    	{
    		this->m_pAllBullet->removeObject(bullet);
    		this->removeChild(bullet,true);
    	}
    }

    好吧,到此为止,子弹层就创建完毕了,我们把它加入GameLayer层的init函数中,并执行开始发射子弹,看一下飞机是不是可以发射子弹了。

    //加入bulletLayer
    this->bulletLayer=BulletLayer::create();
    this->addChild(bulletLayer);
    this->bulletLayer->StartShoot();
  • 相关阅读:
    设计模式-17-迭代器
    设计模式-16-备忘录
    微服务架构设计
    数据库拆分案例
    生成多个git ssh密钥
    分布式数据中间件TDDL、Amoeba、Cobar、MyCAT架构比较
    maven工程 java 实现文件上传 SSM ajax异步请求上传
    MySQL的分区、分表、集群
    Redis实现分布式锁原理与实现分析
    关于消息队列的使用
  • 原文地址:https://www.cnblogs.com/james1207/p/3331137.html
Copyright © 2020-2023  润新知