基于cocos2dx的飞机大战学习[四]-添加英雄子弹

前端之家收集整理的这篇文章主要介绍了基于cocos2dx的飞机大战学习[四]-添加英雄子弹前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

第四节:添加英雄子弹


实现这个功能需要如下考虑:

1、每隔一小段时间就创建一个子弹在英雄机顶,并将其加入一个sprite*的容器中,并添加在flyplane层中显示出来。

2、创建出来的子弹每帧刷新都增加Y坐标让其看起来向上移动。

3、子弹出界,回收清除。 (打中敌人也要从容器中和flyplane对象中清除,以后再考虑)。


综合这几点修改FlyPlane.h 和 FlyPlane.cpp文件

一、FlyPlane.h

  1. #include "cocos2d.h"
  2.  
  3.  
  4. class FlyPlane : public cocos2d::Layer {
  5. public:
  6. CREATE_FUNC(FlyPlane);
  7. bool init();
  8. static cocos2d::Scene* createScene();
  9. //定时器函数必须是void返回类型,必须有一个float类型的参数
  10. void update(float);
  11. private:
  12. cocos2d::Point m_vec;
  13. //英雄子弹集合
  14. std::vector<cocos2d::Sprite*> h_bullets;
  15. //创建子弹
  16. void createBullet(float);
  17. };


二、FlyPlane.cpp
  1. #include "FlyPlane.h"
  2. #include "CommonData.h"
  3.  
  4. cocos2d::Scene* FlyPlane::createScene() {
  5. //1、auto是c++11的新特性,是自动根据变量的值确定变量的类型,类似var
  6. //2、大多数时候,cocos中的类想获取它的对象,不建议去new,而是调用它的create方法(oc语法导致)
  7. //调用cocos2d空间中scene类的静态create方法,返回一个cocos2d::Scene*对象给scene连接
  8. //‘场景’是一个自动关联的对象
  9. auto scene = cocos2d::Scene::create();
  10. auto layer = FlyPlane::create();
  11. //把层添加到场景里
  12. scene->addChild(layer);
  13. return scene;
  14. }
  15.  
  16. bool FlyPlane::init() {
  17. //一定要先调用父类初始函数
  18. if( !cocos2d::Layer::init() ) {
  19. return false;
  20. }
  21.  
  22. //使用精灵集需要两步
  23. //1、将美工做好的plist文件读取到缓存中
  24. //2、通过帧名字创建精灵并显示
  25. cocos2d::CCSpriteFrameCache::getInstance()->
  26. addSpriteFramesWithFile("shoot_background.plist");
  27. auto bg1 = cocos2d::Sprite::createWithSpriteFrameName("background.png");
  28.  
  29. //把精灵bg1加到FlyPlane层中,第二个参数ZOrder表示距离用户的距离,第三个参数tag设为1
  30. this->addChild(bg1,-1,1);
  31.  
  32. //默认锚点为(0.5,0.5),只会显示一半的图,必须设置锚点为(0,0)
  33. bg1->setAnchorPoint(cocos2d::Point(0,0));
  34.  
  35. //texture:纹理,通过精灵找到对应的纹理,并开启抗锯齿
  36. bg1->getTexture()->setAliasTexParameters();
  37. auto bg2 = cocos2d::Sprite::createWithSpriteFrameName("background.png");
  38. this->addChild(bg2,2);
  39. bg2->setAnchorPoint(cocos2d::Point(0,0));
  40. bg2->getTexture()->setAliasTexParameters();
  41. //添加英雄
  42. cocos2d::CCSpriteFrameCache::getInstance()->
  43. addSpriteFramesWithFile("shoot.plist");
  44. auto hero = cocos2d::Sprite::createWithSpriteFrameName("hero1.png");
  45. hero->setPosition(VISIBLE_SIZE.width / 2,100);
  46. this->addChild(hero,3,3);
  47. //为英雄添加飞行动作,动作由动画组成,所以得到动作对象前,需要先得到动画对象
  48. //一、创建动画对象
  49. //1.1通过create得到动画对象
  50. auto animation = cocos2d::Animation::create();
  51. //1.2添加这个动画所要用的精灵帧
  52. animation->addSpriteFrame(cocos2d::SpriteFrameCache::getInstance()->
  53. getSpriteFrameByName("hero1.png"));
  54. animation->addSpriteFrame(cocos2d::SpriteFrameCache::getInstance()->
  55. getSpriteFrameByName("hero2.png"));
  56. //1.3设置切换时间
  57. animation->setDelayPerUnit(0.2f);
  58. //1.4循环次数,默认为1,设为-1使其无限循环
  59. animation->setLoops(-1);
  60. //二、根据动画对象创建动作对象
  61. auto animate = cocos2d::Animate::create(animation);
  62. //三、让hero执行这个动作
  63. hero->runAction(animate);
  64.  
  65.  
  66. //用单个处理事件添加鼠标监听事件
  67. auto listener = cocos2d::EventListenerTouchOneByOne::create();
  68. //用lambda表达式处理分解事件
  69. //Lambda表达式:
  70. // {} 类似于普通函数函数
  71. // () 类似于普通函数的参数列表
  72. // [] 默认Lambda表达式不能访问外部的变量,如果想访问外部变量,就通过中括号传进来
  73. listener->onTouchBegan = [=](cocos2d::Touch* touch,cocos2d::Event*) {
  74. auto touchPos = touch->getLocation();
  75. bool isContain = hero->getBoundingBox().containsPoint(touchPos);
  76. if(isContain) {
  77. m_vec = hero->getPosition() - touchPos;//my_vector,记录touchPos指向hero的向量
  78. }
  79. return isContain;
  80. };
  81. const float leftMinX = hero->getContentSize().width / 2; //英雄的X最小值(左边界线)
  82. const float rightMaxX = VISIBLE_SIZE.width - hero->getContentSize().width / 2;//英雄X最大值(右边界线)
  83. const float downMinY = hero->getContentSize().height / 2; //英雄Y最小值(下边界线)
  84. const float upMaxY = VISIBLE_SIZE.height - hero->getContentSize().height / 2; //英雄Y最大值(上边界线)
  85. listener->onTouchMoved = [=](cocos2d::Touch* touch,cocos2d::Event*) {
  86. auto touchPos = touch->getLocation() + m_vec;
  87. //让英雄跟着手指动并且不超出边界
  88. hero->setPosition(cocos2d::Point(MAX(leftMinX,MIN(rightMaxX,touchPos.x)),MAX(downMinY,MIN(upMaxY,touchPos.y))));
  89. };
  90. //将监听器添加到事件分配器上
  91. this->getEventDispatcher()->
  92. addEventListenerWithSceneGraPHPriority(listener,hero);
  93.  
  94. //定时添加子弹
  95. schedule(schedule_selector(FlyPlane::createBullet),0.1f);
  96. //定时器。scheduleUpdate每帧调用一次update函数
  97. scheduleUpdate();
  98.  
  99. return true;
  100. }
  101.  
  102. void FlyPlane::update(float) {
  103. auto bg1 = this->getChildByTag(1);
  104. auto bg2 = this->getChildByTag(2);
  105. //bg1下落,bg2跟随
  106. bg1->setPositionY(bg1->getPositionY() - 5);
  107. bg2->setPositionY(bg1->getPositionY() + bg1->getContentSize().height);
  108. if(bg2->getPositionY() <= 0) {
  109. bg1->setPositionY(0);
  110. }
  111.  
  112.  
  113. for(std::vector<cocos2d::Sprite*>::iterator iter = this->h_bullets.begin(); iter != this->h_bullets.end();) {
  114. (*iter)->setPositionY((*iter)->getPositionY() + 12); //更新子弹位置
  115. if((*iter)->getPositionY() > VISIBLE_SIZE.height) { //判断子弹是否越界,越界则清除,双开(容器清除,FlyPlane层中清除)
  116. this->removeChild((*iter));
  117. iter = h_bullets.erase(iter);
  118. } else {
  119. ++iter;
  120. }
  121. }
  122. }
  123.  
  124. void FlyPlane::createBullet(float) {
  125. auto hero = this->getChildByTag(3);
  126. auto bullet = cocos2d::Sprite::createWithSpriteFrameName("bullet1.png");//初始子弹在shoot.plist中名字叫bullet1
  127. bullet->setPosition(hero->getPosition() + cocos2d::Point(0,hero->getContentSize().height / 2));//子弹初始位置
  128. this->addChild(bullet,0); //zorder为0,高于背景层-1,低于英雄的3
  129. //每创建一个子弹就存在容器中
  130. h_bullets.push_back(bullet);
  131. }

最主要更新的两段代码就是创建子弹代码
  1. void FlyPlane::createBullet(float) {
  2. auto hero = this->getChildByTag(3);
  3. auto bullet = cocos2d::Sprite::createWithSpriteFrameName("bullet1.png");//初始子弹在shoot.plist中名字叫bullet1
  4. bullet->setPosition(hero->getPosition() + cocos2d::Point(0,0); //zorder为0,高于背景层-1,低于英雄的3
  5. //每创建一个子弹就存在容器中
  6. h_bullets.push_back(bullet);
  7. }

以及子弹容器遍历判断的代码
  1. for(std::vector<cocos2d::Sprite*>::iterator iter = this->h_bullets.begin(); iter != this->h_bullets.end();) {
  2. (*iter)->setPositionY((*iter)->getPositionY() + 12); //更新子弹位置
  3. if((*iter)->getPositionY() > VISIBLE_SIZE.height) { //判断子弹是否越界,越界则清除,双开(容器清除,FlyPlane层中清除)
  4. this->removeChild((*iter));<span>
  5. iter = h_bullets.erase(iter);
  6. } else {
  7. ++iter;
  8. }
  9. }

运行效果图如下:




子弹添加完成,明天再添加敌机,晚安。

猜你在找的Cocos2d-x相关文章