基于cocos2dx的飞机大战学习[二]-添加移动背景与英雄

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

第二节:添加无限移动背景英雄飞机@H_301_15@


@H_301_15@

一、新建文件@H_301_15@

删除HelloWorldScene.h与HelloWorldScene.cpp文件,新建FlaPlane类如下,cpp文件同样的创建方法,这里注意FlyPlane的位置一定要在classes文件夹下,名字随意,最好和项目名保持一致。
@H_301_15@


@H_301_15@


@H_301_15@

二、修改AppDelegate.cpp@H_301_15@

AppDelegate.cpp中会有两处红线错误,第一个地方是头文件,改成@H_301_15@

  1. #include "FlyPlane.h"

第二个地方改成@H_301_15@

  1. auto scene = FlyPlane::createScene();

这里的错误很好理解,因为HelloWorld层类已经被删除了。@H_301_15@

修改bool AppDelegate::applicationDidFinishLaunching() 函数代码,如下:@H_301_15@

  1. bool AppDelegate::applicationDidFinishLaunching() {
  2. // initialize director
  3. auto director = Director::getInstance();
  4. auto glview = director->getOpenGLView();
  5. if(!glview) {
  6. glview = GLView::create("FlyPlane");
  7. director->setOpenGLView(glview);
  8. }
  9.  
  10. //glview设置设备尺寸 和 屏幕拉升解决策略--适应宽度
  11. glview->setFrameSize(480,640);
  12. glview->setDesignResolutionSize(480,640,ResolutionPolicy::FIXED_WIDTH);
  13.  
  14. //FileUtils添加查找资源树
  15. cocos2d::FileUtils::getInstance()->addSearchPath("ui");
  16.  
  17. // turn on display FPS
  18. director->setDisplayStats(true);
  19.  
  20. // set FPS. the default value is 1.0/60 if you don't call this
  21. director->setAnimationInterval(1.0 / 60);
  22.  
  23. // create a scene. it's an autorelease object
  24. auto scene = FlyPlane::createScene();
  25.  
  26. // run
  27. director->runWithScene(scene);
  28.  
  29. return true;
  30. }


@H_301_15@ 三、修改FlyPlane.h文件

  1. #include "cocos2d.h"
  2.  
  3. //可以加USING_NS_CC不用写cocos2d
  4. class FlyPlane : public cocos2d::Layer {
  5. public:
  6. CREATE_FUNC(FlyPlane);
  7. bool init();
  8. static cocos2d::Scene* createScene();
  9.  
  10. //定时器函数必须是void返回类型,必须有一个float类型的参数,刷新图片必用
  11. void update(float);
  12. };

四、修改FlyPlane.cpp文件
  1. #include "GameScene.h"
  2.  
  3. cocos2d::Scene* GameScene::createScene() {
  4. //1、auto是c++11的新特性,是自动根据变量的值确定变量的类型,类似var
  5. //2、大多数时候,cocos中的类想获取它的对象,不建议去new,而是调用它的create方法(oc语法导致)
  6. //调用cocos2d空间中scene类的静态create方法,用scene连接
  7. cocos2d::Scene* scene = cocos2d::Scene::create();
  8. //GameScene是一个层
  9. auto gameLayer = GameScene::create();
  10. //只有场景中的元素才能被渲染
  11. scene->addChild(gameLayer);
  12. return scene;
  13. }
  14.  
  15. bool GameScene::init() {
  16. cocos2d::Layer::init();
  17. //使用精灵集中的帧,需要两步:1.将【plist】读取到缓存中,2.通过帧名称创建精灵并显示
  18. cocos2d::SpriteFrameCache::getInstance()->
  19. addSpriteFramesWithFile("shoot_background.plist");
  20.  
  21. auto bg1 = cocos2d::Sprite::createWithSpriteFrameName("background.png");
  22. //this表示scene,即GameScene
  23. this->addChild(bg1,-1,1);
  24. //设置锚点
  25. bg1->setAnchorPoint(cocos2d::Point(0,0));
  26. //texture:纹理,通过精灵找到对应的纹理,并开启抗锯齿
  27. bg1->getTexture()->setAliasTexParameters();
  28.  
  29. auto bg2 = cocos2d::Sprite::createWithSpriteFrameName("background.png");
  30. this->addChild(bg2,2);
  31. bg2->setAnchorPoint(cocos2d::Point(0,0));
  32. bg2->getTexture()->setAliasTexParameters();
  33.  
  34.  
  35. //添加英雄战机
  36. cocos2d::SpriteFrameCache::getInstance()->
  37. addSpriteFramesWithFile("shoot.plist");
  38. auto hero = cocos2d::Sprite::createWithSpriteFrameName("hero1.png");
  39. this->addChild(hero,3,3);
  40. hero->setPositionX(bg1->getContentSize().width / 2);
  41. hero->setPositionY(100);
  42.  
  43. //定时器。scheduleUpdate每帧调用一次update函数
  44. scheduleUpdate();
  45.  
  46. auto touchListener = cocos2d::EventListenerTouchOneByOne::create();
  47. auto VISIBLE_SIZE = cocos2d::Director::getInstance()->getVisibleSize();
  48. touchListener->onTouchBegan = [=](cocos2d::Touch* touch,cocos2d::Event*) {
  49. this->m_vec = hero->getPosition() - touch->getLocation();
  50. bool isContain = hero->getBoundingBox().containsPoint(touch->getLocation());
  51. return isContain;
  52. };
  53.  
  54. float minX = hero->getContentSize().width/2;
  55. float maxX = VISIBLE_SIZE.width - minX;
  56. float minY = hero->getContentSize().height/2;
  57. float maxY = VISIBLE_SIZE.height - minY;
  58.  
  59. touchListener->onTouchMoved = [=](cocos2d::Touch* touch,cocos2d::Event*) {
  60. auto VISIBLE_SIZE = cocos2d::Director::getInstance()->getVisibleSize();
  61. auto desP = touch->getLocation() + this->m_vec;
  62. hero->setPosition(MAX(minX,MIN(desP.x,maxX)),MAX(minY,MIN(desP.y,maxY)));
  63. //hero->runAction(cocos2d::MoveTo::create(0.5f,touch->getLocation()));
  64. };
  65.  
  66. touchListener->onTouchEnded = [](cocos2d::Touch* touch,cocos2d::Event*){
  67.  
  68. };
  69. //
  70. hero->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(touchListener,hero);
  71. return true;
  72. }
  73.  
  74.  
  75. void GameScene::update(float dt) {
  76. //通过tag获取背景精灵
  77. auto bg1 = this->getChildByTag(1);
  78. auto bg2 = this->getChildByTag(2);
  79. //auto hero = this->getChildByTag(3);
  80. bg1->setPositionY(bg1->getPositionY() - 5);
  81. bg2->setPositionY(bg1->getPositionY() + bg1->getContentSize().height);
  82.  
  83. if(bg2->getPositionY() <= 0) { //bg1掉完了,将bg1的Y归0
  84. bg1->setPositionY(0);
  85. }
  86. }

运行发现背景图片已经可以连续的向下滚动了。


@H_301_15@


@H_301_15@

五、添加英雄战机@H_301_15@

1.在classes文件夹中添加公用数据头文件,新建一个头文件CommonData.h,添加代码@H_301_15@

  1. #define VISIBLE_SIZE cocos2d::Director::getInstance()->getVisibleSize()
如下:


@H_301_15@

在FlyPlane.cpp中添加文件@H_301_15@

  1. #include "CommonData.h"

修改bool FlyPlane::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);
  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,0));
  24. bg2->getTexture()->setAliasTexParameters();
  25. //添加英雄
  26. cocos2d::CCSpriteFrameCache::getInstance()->
  27. addSpriteFramesWithFile("shoot.plist");
  28. auto hero = cocos2d::Sprite::createWithSpriteFrameName("hero1.png");
  29. hero->setPosition(VISIBLE_SIZE.width / 2,100);
  30. this->addChild(hero,3);
  31. //定时器。scheduleUpdate每帧调用一次update函数
  32. scheduleUpdate();
  33.  
  34. return true;
  35. }


@H_301_15@ 运行,效果如下



@H_301_15@

现在,背景和英雄飞机就设置成功了。@H_301_15@


@H_301_15@

注:关于bool FlyPlane::init()函数何时会被调用的问题。@H_301_15@

1、先看到项目入口APPDelegete.cpp文件中的applicationDidFinishLaunching()函数,发现有这样一行代码@H_301_15@

  1. auto scene = FlyPlane::createScene();
这时就会调用FlyPlane的静态函数createScene()


@H_301_15@

2、研究FlyPlane的静态函数createScene(),又发现有这样一行代码
@H_301_15@

  1. auto layer = FlyPlane::create();
我们发现FlyPlane.h头文件中没有create()函数,那么为什么不报错呢?

这是因为我们的FlyPlane.h头文件中有个CREATE_FUNC(FlyPlane)函数,我们按F12进行查看发现CREATE_FUNC(FlyPlane)是个宏函数@H_301_15@

  1. #define CREATE_FUNC(__TYPE__) \ //__TYPE__表示占位符,这里表示FlyPlane
  2. static __TYPE__* create() \ //这里发现create()就是CREATE_FUNC(FlyPlane)
  3. { \
  4. __TYPE__ *pRet = new __TYPE__(); \ //FlyPlane *pRet = new FlyPlane();
  5. if (pRet && pRet->init()) \ //这里就调用了FlyPlane->init()
  6. { \
  7. pRet->autorelease(); \
  8. return pRet; \
  9. } \
  10. else \
  11. { \
  12. delete pRet; \
  13. pRet = NULL; \
  14. return NULL; \ //稳定安全的创建回收函数
  15. } \
  16. }


@H_301_15@

通过注释可以看出只要调用FlyPlane的create()静态函数,只要没有调用过init()函数,就会调用init()函数,这就是init()被调用方法。@H_301_15@

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