基于cocos2dx的飞机大战学习[三]-为英雄添加飞行帧动作并控制飞机移动

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


第三节:为英雄添加飞行帧动作并控制飞机移动


一、为飞机添加飞行动画

为飞机添加飞行动画十分简单,只需要在FlyPlane::init()函数中创建一个动画对象,在里面添加两张英雄图并相互切换就可以了。

添加代码如下:

  1. //为英雄添加飞行动作,动作由动画组成,所以得到动作对象前,需要先得到动画对象
  2. //一、创建动画对象
  3. //1.1通过create得到动画对象
  4. auto animation = cocos2d::Animation::create();
  5. //1.2添加这个动画所要用的精灵帧
  6. animation->addSpriteFrame(cocos2d::SpriteFrameCache::getInstance()->
  7. getSpriteFrameByName("hero1.png"));
  8. animation->addSpriteFrame(cocos2d::SpriteFrameCache::getInstance()->
  9. getSpriteFrameByName("hero2.png"));
  10. //1.3设置切换时间
  11. animation->setDelayPerUnit(0.2f);
  12. //1.4循环次数,默认为1,设为-1使其无限循环
  13. animation->setLoops(-1);
  14. //二、根据动画对象创建动作对象
  15. auto animate = cocos2d::Animate::create(animation);
  16. //三、让hero执行这个动作
  17. hero->runAction(animate);


修改后init()函数如下:
  1. bool FlyPlane::init() {
  2. //一定要先调用父类初始函数
  3. if( !cocos2d::Layer::init() ) {
  4. return false;
  5. }
  6.  
  7. //使用精灵集需要两步
  8. //1、将美工做好的plist文件读取到缓存中
  9. //2、通过帧名字创建精灵并显示
  10. cocos2d::CCSpriteFrameCache::getInstance()->
  11. addSpriteFramesWithFile("shoot_background.plist");
  12. auto bg1 = cocos2d::Sprite::createWithSpriteFrameName("background.png");
  13.  
  14. //把精灵bg1加到FlyPlane层中,第二个参数ZOrder表示距离用户的距离,第三个参数tag设为1
  15. this->addChild(bg1,-1,1);
  16.  
  17. //默认锚点为(0.5,0.5),只会显示一半的图,必须设置锚点为(0,0)
  18. bg1->setAnchorPoint(cocos2d::Point(0,0));
  19.  
  20. //texture:纹理,通过精灵找到对应的纹理,并开启抗锯齿
  21. bg1->getTexture()->setAliasTexParameters();
  22. auto bg2 = cocos2d::Sprite::createWithSpriteFrameName("background.png");
  23. this->addChild(bg2,2);
  24. bg2->setAnchorPoint(cocos2d::Point(0,0));
  25. bg2->getTexture()->setAliasTexParameters();
  26. //添加英雄
  27. cocos2d::CCSpriteFrameCache::getInstance()->
  28. addSpriteFramesWithFile("shoot.plist");
  29. auto hero = cocos2d::Sprite::createWithSpriteFrameName("hero1.png");
  30. hero->setPosition(VISIBLE_SIZE.width / 2,100);
  31. this->addChild(hero,3,3);
  32. //为英雄添加飞行动作,动作由动画组成,所以得到动作对象前,需要先得到动画对象
  33. //一、创建动画对象
  34. //1.1通过create得到动画对象
  35. auto animation = cocos2d::Animation::create();
  36. //1.2添加这个动画所要用的精灵帧
  37. animation->addSpriteFrame(cocos2d::SpriteFrameCache::getInstance()->
  38. getSpriteFrameByName("hero1.png"));
  39. animation->addSpriteFrame(cocos2d::SpriteFrameCache::getInstance()->
  40. getSpriteFrameByName("hero2.png"));
  41. //1.3设置切换时间
  42. animation->setDelayPerUnit(0.2f);
  43. //1.4循环次数,默认为1,设为-1使其无限循环
  44. animation->setLoops(-1);
  45. //二、根据动画对象创建动作对象
  46. auto animate = cocos2d::Animate::create(animation);
  47. //三、让hero执行这个动作
  48. hero->runAction(animate);
  49.  
  50. //定时器。scheduleUpdate每帧调用一次update函数
  51. scheduleUpdate();
  52.  
  53. return true;
  54. }
运行效果图(就是飞机屁股能喷火- -):




二、控制英雄移动

控制英雄需要监听事件,有这么几个问题需要考虑。

1.hero可以跟随触摸点移动
2.触摸点必须在hero的绘制区域内才会跟随移动
3.hero随触摸点移动时保持向量差
4.hero不能移出规定区域

现在进行编码,为了解决第三个问题首先我们需要在FlyPlane.h文件添加一个属性m_vec,表示由touch指向英雄锚点坐标的向量。

  1. private:
  2. cocos2d::Point m_vec;


在FlyPlane.cpp中的init()函数添加如下代码

  1. //用单个处理事件添加鼠标监听事件
  2. auto listener = cocos2d::EventListenerTouchOneByOne::create();
  3. //用lambda表达式处理分解事件
  4. //Lambda表达式:
  5. // {} 类似于普通函数函数
  6. // () 类似于普通函数的参数列表
  7. // [] 默认Lambda表达式不能访问外部的变量,如果想访问外部变量,就通过中括号传进来
  8. listener->onTouchBegan = [=](cocos2d::Touch* touch,cocos2d::Event*) {
  9. auto touchPos = touch->getLocation();
  10. bool isContain = hero->getBoundingBox().containsPoint(touchPos);
  11. if(isContain) {
  12. m_vec = hero->getPosition() - touchPos;//my_vector,记录touchPos指向hero的向量
  13. }
  14. return isContain;
  15. };
  16. const float leftMinX = hero->getContentSize().width / 2; //英雄的X最小值(左边界线)
  17. const float rightMaxX = VISIBLE_SIZE.width - hero->getContentSize().width / 2;//英雄X最大值(右边界线)
  18. const float downMinY = hero->getContentSize().height / 2; //英雄Y最小值(下边界线)
  19. const float upMaxY = VISIBLE_SIZE.height - hero->getContentSize().height / 2; //英雄Y最大值(上边界线)
  20. listener->onTouchMoved = [=](cocos2d::Touch* touch,cocos2d::Event*) {
  21. auto touchPos = touch->getLocation() + m_vec;
  22. //让英雄跟着手指动并且不超出边界
  23. hero->setPosition(cocos2d::Point(MAX(leftMinX,MIN(rightMaxX,touchPos.x)),MAX(downMinY,MIN(upMaxY,touchPos.y))));
  24. };
  25. //将监听器添加到事件分配器上
  26. this->getEventDispatcher()->
  27. addEventListenerWithSceneGraPHPriority(listener,hero);

添加后FlyPlane::init() 函数如下

  1. 添加飞行动作,动作由动画组成,所以得到动作对象前,需要先得到动画对象
  2. //一、创建动画对象
  3. //1.1通过create得到动画对象
  4. auto animation = cocos2d::Animation::create();
  5. //1.2添加这个动画所要用的精灵帧
  6. animation->addSpriteFrame(cocos2d::SpriteFrameCache::getInstance()->
  7. getSpriteFrameByName("hero1.png"));
  8. animation->addSpriteFrame(cocos2d::SpriteFrameCache::getInstance()->
  9. getSpriteFrameByName("hero2.png"));
  10. //1.3设置切换时间
  11. animation->setDelayPerUnit(0.2f);
  12. //1.4循环次数,默认为1,设为-1使其无限循环
  13. animation->setLoops(-1);
  14. //二、根据动画对象创建动作对象
  15. auto animate = cocos2d::Animate::create(animation);
  16. //三、让hero执行这个动作
  17. hero->runAction(animate);
  18.  
  19.  
  20. //用单个处理事件添加鼠标监听事件
  21. auto listener = cocos2d::EventListenerTouchOneByOne::create();
  22. //用lambda表达式处理分解事件
  23. //Lambda表达式:
  24. // {} 类似于普通函数函数
  25. // () 类似于普通函数的参数列表
  26. // [] 默认Lambda表达式不能访问外部的变量,如果想访问外部变量,就通过中括号传进来
  27. listener->onTouchBegan = [=](cocos2d::Touch* touch,hero);
  28.  
  29. //定时器。scheduleUpdate每帧调用一次update函数
  30. scheduleUpdate();
  31.  
  32. return true;
  33. }

运行操作英雄,发现必须要点中英雄才可以自由移动并且不会超过边界,BUG解决



本节效果完成,下节讲添加子弹。

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