cocos2dx实例开发之2D横版跑酷

前端之家收集整理的这篇文章主要介绍了cocos2dx实例开发之2D横版跑酷前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

从网上下了一点素材资源,外加自己ps一点资源,然后东拼西凑写了一个横版跑酷的小游戏

ps:csdn好不爽,无法传大点的gif,所以只好录了个短的gif,而且压缩之后凑合能看

预览



步骤

1 工程结构

开发环境
  • win8.1
  • vs2013
  • cocos2dx 3.2
代码目录

游戏组成结构


主要有以下几个场景

  • 预加载场景,用于loading等待
  • 菜单场景
  • 游戏主场景(背景、移动地图、角色、拾取物)
  • 选项界面
  • 关于界面

2 预加载场景

主要是用于图片资源,音频资源的异步预加载,然后在回调里面跳转到主菜单场景,并且添加了进度条提示
  1. void LoadingScene::loadingCallBack(Texture2D *texture)
  2. {
  3. loadedNum++;
  4. //此处的预加载帧动画指示用于实验性质
  5. switch(loadedNum)
  6. {
  7. case 1:
  8. //预加载帧缓存纹理
  9. SpriteFrameCache::getInstance()->addSpriteFramesWithFile("boy.plist",texture);
  10. loadProgress->setPercentage((float)loadedNum/totalNum*100);
  11. break;
  12. case 2:
  13. //预加载帧缓存纹理
  14. SpriteFrameCache::getInstance()->addSpriteFramesWithFile("girl.plist",texture);
  15. loadProgress->setPercentage((float)loadedNum/totalNum*100);
  16. break;
  17. default:
  18. break;
  19. }
  20.  
  21. if(loadedNum==totalNum)
  22. {
  23. //预加载帧动画
  24. auto boyAnimation=Animation::create();
  25. boyAnimation->setDelayPerUnit(0.1f);
  26. for(int i=1;i<=12;i++)
  27. {
  28. char str[100]={0};
  29. sprintf(str,"boy%d.png",i);
  30. boyAnimation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(str));
  31. }
  32. AnimationCache::getInstance()->addAnimation(boyAnimation,"boyAnimation");
  33.  
  34. //预加载帧动画
  35. auto girlAnimation=Animation::create();
  36. girlAnimation->setDelayPerUnit(0.2f);
  37. for(int i=1;i<=8;i++)
  38. girlAnimation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("girl"+std::to_string(i)+".png"));
  39. AnimationCache::getInstance()->addAnimation(girlAnimation,"girlAnimation");
  40.  
  41. ////预加载音乐和音效
  42. SimpleAudioEngine::getInstance()->preloadBackgroundMusic("spring_music.wav");
  43. SimpleAudioEngine::getInstance()->preloadBackgroundMusic("winter_music.mp3");
  44.  
  45. SimpleAudioEngine::getInstance()->preloadEffect("jump.wav");
  46. SimpleAudioEngine::getInstance()->preloadEffect("point.mp3");
  47. SimpleAudioEngine::getInstance()->preloadEffect("gameover.wav");
  48. //加载完毕跳转到游戏场景
  49. auto mainMenu=MainMenu::createScene();
  50. TransitionScene *transition=TransitionFade::create(1.0f,mainMenu);
  51. Director::getInstance()->replaceScene(transition);
  52. }
  53. }

3 主菜单场景

添加一个菜单和对应的回调函数,分别有开始游戏、选项、关于等菜单
  1. //添加菜单
  2. auto newGameItem=MenuItemImage::create("newgameA.png","newgameB.png",CC_CALLBACK_1(MainMenu::menuStartCallback,this));
  3. newGameItem->setPosition(Point(visibleOrigin.x+visibleSize.width/2,visibleOrigin.y+visibleSize.height/2));
  4. auto optionItem=MenuItemImage::create("option_btn.png","option_btn.png",CC_CALLBACK_1(MainMenu::menuOptionCallback,this));
  5. optionItem->setPosition(Point(visibleOrigin.x+visibleSize.width/2,visibleOrigin.y+visibleSize.height/2-60));
  6. auto aboutItem=MenuItemImage::create("aboutA.png","aboutB.png",CC_CALLBACK_1(MainMenu::menuAboutCallback,this));
  7. aboutItem->setPosition(Point(visibleOrigin.x+visibleSize.width/2,visibleOrigin.y+visibleSize.height/2-120));
  8.  
  9.  
  10. auto menu=Menu::create(newGameItem,optionItem,aboutItem,NULL);
  11. menu->setPosition(Point::ZERO);
  12. this->addChild(menu,1);

4 游戏主场景

common头文件
这个头文件里面存储了一些定义的全局变量,比如关卡、男女角色选取等
  1. //游戏关卡枚举
  2. enum Level
  3. {
  4. SPRING,WINTER
  5. };
  6.  
  7.  
  8. //游戏角色枚举
  9. enum PlayerType
  10. {
  11. BOY,GIRL
  12. };
  13.  
  14. //游戏角色状态
  15. enum PlayerState
  16. {
  17. RUN,SLIDE,JUMP
  18. };
  19.  
  20. //地图元素枚举
  21. enum BlockType
  22. {
  23. LAND,//砖块
  24. NPC,//怪物
  25. STAR,//星星
  26. TOOL,//工具
  27. NONE //空
  28. };
  29.  
  30. //场景间隔基本单位定为80,分辨率800*480,则排满是10*6个格子,便于作碰撞检测
  31. const float BLOCK_SIZE=80.0f;
  32. const float PICKUP_SIZE=40.0f;
  33. const float PLAYER_RADIUS=50.0f;
  34. const float GRAVITY=-1500.0f;
  35. const float PLAYER_SPEED=700.0f;
为了便于计算,将屏幕设计分辨率定位800*480,一个砖块或怪物的大小是80*80,一个拾取物的大小是40*40,这样计算坐标时只需要左整数倍数的偏移就可以了。
游戏里面设置了两种关卡,分别对应了春天和冬天的地图,春天的怪物是绿水灵,冬天的怪物是蓝蘑菇,(玩过冒险岛的都知道),同时还可以选择男、女两种角色。
都是用全局变量进行控制。


游戏角色player类
  1. class Player:public Node
  2. {
  3. public:
  4. virtual bool init() override;
  5. CREATE_FUNC(Player);
  6. public:
  7. void run(); //主角奔跑
  8. void jump(); //主角跳跃
  9. void slide(); //主角滑行
  10. PlayerState playerState; //角色状态
  11. private:
  12. Sprite *playerSprite; //奔跑的角色精灵
  13. Sprite *playerSpriteSlideJump; //滑行和起跳的角色精灵
  14. Animate *playerAnim;
  15. Texture2D *jumpTexture;
  16. Texture2D *slideTexture;
  17. };
游戏角色分男女,具有奔跑、跳跃、滑行三种状态
角色还有奔跑动画,同时还要为角色绑定刚体,需要受物理引擎作用
  1. playerSprite=Sprite::create(playerTextureName); //此处必须初始化一张角色纹理,否则后面无法切换纹理
  2. jumpTexture=Sprite::create(playerJumpTexureName)->getTexture(); //创建跳跃纹理
  3. slideTexture=Sprite::create(playerSlideTextureName)->getTexture(); //创建滑行纹理
  4.  
  5. playerAnim=Animate::create(playerAnimation);
  6. this->addChild(playerSprite);
  7.  
  8. auto playerBody=PhysicsBody::createBox(playerSprite->getContentSize()); //这里要用包围盒,如果用圆形的话会导致滚动
  9. playerBody->setDynamic(true);
  10. playerBody->setContactTestBitmask(1);
  11. playerBody->setGravityEnable(true);
  12. playerBody->getShape(0)->setRestitution(0.0f); //设置刚体回弹力
  13. this->setPhysicsBody(playerBody);

游戏移动地图类
主要是地图中的砖块和怪物等元素的无限滚屏移动
首先,在初始化里面,手动设置初始地图,放置砖块、怪物、拾取物等等
  1. //手动搭建地图,没有加入即时计算~
  2. //1层
  3. for(int i=0;i<10;i++)
  4. {
  5. if(i!=3&&i!=4&&i!=7&&i!=8)
  6. {
  7. //添加land
  8. auto block=Sprite::create(block_file);
  9. block->setPosition(BLOCK_SIZE/2+i*BLOCK_SIZE,BLOCK_SIZE/2+1*BLOCK_SIZE);
  10. this->addChild(block);
  11. block->setTag(LAND); //设置tag
  12. auto blockBody=PhysicsBody::createBox(block->getContentSize());
  13. blockBody->setDynamic(false);
  14. blockBody->setContactTestBitmask(1);
  15. blockBody->getShape(0)->setRestitution(0);
  16. block->setPhysicsBody(blockBody);
  17. }
  18. }
  19. //2层
  20. for(int i=0;i<10;i++)
  21. {
  22. if(i==2||i==5||i==6)
  23. {
  24. //添加怪物
  25. auto npc=Sprite::create(npc_file);
  26. npc->setTag(NPC);
  27. npc->setPosition(BLOCK_SIZE/2+i*BLOCK_SIZE,BLOCK_SIZE/2+2*BLOCK_SIZE);
  28. auto npcBody=PhysicsBody::createBox(npc->getContentSize());
  29. npcBody->setDynamic(false);
  30. npcBody->setContactTestBitmask(1);
  31. npcBody->getShape(0)->setRestitution(0);
  32. npc->setPhysicsBody(npcBody);
  33. this->addChild(npc);
  34. }
  35. if(i==3)
  36. {
  37. //添加land
  38. auto block=Sprite::create(block_file);
  39. block->setPosition(BLOCK_SIZE/2+i*BLOCK_SIZE,BLOCK_SIZE/2+1*BLOCK_SIZE);
  40. this->addChild(block);
  41. block->setTag(LAND); //设置tag
  42. auto blockBody=PhysicsBody::createBox(block->getContentSize());
  43. blockBody->setDynamic(false);
  44. blockBody->setContactTestBitmask(1);
  45. blockBody->getShape(0)->setRestitution(0);
  46. block->setPhysicsBody(blockBody);
  47. }
  48. }
  49. //3层
  50. for(int i=0;i<10;i++)
  51. {
  52. if(i!=0&&i!=3&&i!=4)
  53. {
  54. //添加星星
  55. auto star1=Sprite::create(star_file);
  56. star1->setTag(STAR);
  57. star1->setPosition(PICKUP_SIZE/2+i*BLOCK_SIZE,BLOCK_SIZE/2+3*BLOCK_SIZE);
  58. auto starBody1=PhysicsBody::createBox(star1->getContentSize());
  59. starBody1->setDynamic(false);
  60. starBody1->setContactTestBitmask(1);
  61. starBody1->getShape(0)->setRestitution(0.0f);
  62. star1->setPhysicsBody(starBody1);
  63. this->addChild(star1);
  64.  
  65. auto star2=Sprite::create(star_file);
  66. star2->setTag(STAR);
  67. star2->setPosition(PICKUP_SIZE/2*3+i*BLOCK_SIZE,BLOCK_SIZE/2+3*BLOCK_SIZE);
  68. auto starBody2=PhysicsBody::createBox(star2->getContentSize());
  69. starBody2->setDynamic(false);
  70. starBody2->setContactTestBitmask(1);
  71. starBody2->getShape(0)->setRestitution(0.0f);
  72. star2->setPhysicsBody(starBody2);
  73. this->addChild(star2);
  74.  
  75. }
  76.  
  77. }
  78. //4层
  79. for(int i=0;i<10;i++)
  80. {
  81. if(i==3||i==4)
  82. {
  83. //添加land
  84. auto block=Sprite::create(block_file);
  85. block->setPosition(BLOCK_SIZE/2+i*BLOCK_SIZE,BLOCK_SIZE/2+4*BLOCK_SIZE);
  86. this->addChild(block);
  87. block->setTag(LAND); //设置tag
  88. auto blockBody=PhysicsBody::createBox(block->getContentSize());
  89. blockBody->setDynamic(false);
  90. blockBody->setContactTestBitmask(1);
  91. blockBody->getShape(0)->setRestitution(0);
  92. block->setPhysicsBody(blockBody);
  93.  
  94. }
  95. if(i==8)
  96. {
  97. auto star1=Sprite::create(star_file);
  98. star1->setTag(STAR);
  99. star1->setPosition(PICKUP_SIZE/2+i*BLOCK_SIZE,BLOCK_SIZE/2+3*BLOCK_SIZE);
  100. auto starBody2=PhysicsBody::createBox(star2->getContentSize());
  101. starBody2->setDynamic(false);
  102. starBody2->setContactTestBitmask(1);
  103. starBody2->getShape(0)->setRestitution(0.0f);
  104. star2->setPhysicsBody(starBody2);
  105. this->addChild(star2);
  106. }
  107. if(i==6)
  108. {
  109. //添加道具
  110. auto tool=Sprite::create(tool_file);
  111. tool->setTag(TOOL);
  112. tool->setPosition(PICKUP_SIZE/2+i*BLOCK_SIZE,BLOCK_SIZE/2+3*BLOCK_SIZE);
  113. auto toolBody=PhysicsBody::createBox(tool->getContentSize());
  114. toolBody->setDynamic(false);
  115. toolBody->setContactTestBitmask(1);
  116. toolBody->getShape(0)->setRestitution(0.0f);
  117. tool->setPhysicsBody(toolBody);
  118. this->addChild(tool);
  119. }
  120. }
每个物体都绑定了刚体,便于在物理世界做碰撞检测
然后需要启动无限滚屏
  1. //启动调度器,地图滚屏
  2. this->schedule(schedule_selector(GameMap::mapUpdate),0.01f);
目前所采用的策略是党某个node消失在左侧是,重新设置其坐标到有边缘从右往左移动,不过,更好的方法是动态的随机生成地图结点,但是算法较复杂。
  1. void GameMap::mapUpdate(float dt)
  2. {
  3. for(auto &node:this->getChildren())
  4. {
  5. node->setPositionX(node->getPositionX()-3.0f);
  6. if(node->getPositionX()<=-node->getContentSize().width/2)
  7. node->setPositionX(node->getPositionX()+BLOCK_SIZE/2+10*BLOCK_SIZE);
  8. }
  9.  
  10. }

游戏主场景类
这里有游戏最重要的逻辑代码

一开始需要初始化物理引擎
  1. auto *scene=Scene::createWithPhysics();
  2. scene->getPhysicsWorld()->setGravity(Vec2(0,GRAVITY));

添加背景滚屏,这是底层背景,移动速度比地图移动速度慢,这样有层次感,有景深感觉,让画面更加动感
  1. backGround1=Sprite::create(backGroundFile);
  2. backGround1->setAnchorPoint(Point::ZERO);
  3. backGround1->setPosition(Point::ZERO);
  4. this->addChild(backGround1,0);
  5. backGround2=Sprite::create(backGroundFile);
  6. backGround2->setAnchorPoint(Point::ZERO);
  7. backGround2->setPosition(Point::ZERO);
  8. this->addChild(backGround2,0);
  1. void GameScene::backGroundUpdate(float dt)
  2. {
  3. backGround1->setPositionX(backGround1->getPositionX()-1.0f);
  4. backGround2->setPositionX(backGround1->getPositionX()+backGround1->getContentSize().width);
  5. if(backGround2->getPositionX()<=0.0f)
  6. backGround1->setPositionX(0.0f);
  7. }

添加角色
  1. //添加player
  2. player=Player::create();
  3. player->setPosition(Point(visibleOrigin.x+2*BLOCK_SIZE,visibleOrigin.y+4*BLOCK_SIZE));
  4. this->addChild(player,1);

添加地图
  1. //设置地图,默认锚点在左下角
  2. gameMap=GameMap::create();
  3. gameMap->setPosition(visibleOrigin.x,visibleOrigin.y);
  4. this->addChild(gameMap,1);

添加两个控制按钮
  1. //添加滑行和跳跃按钮的事件
  2. score=0; //初始化分数
  3.  
  4. slideBtn=Sprite::create("slideButton.png");
  5. auto slideBtnTexture1=Sprite::create("slideButton.png")->getTexture();
  6. auto slideBtnTexture2=Sprite::create("slideButtonPress.png")->getTexture();
  7. slideBtnTextures.pushBack(slideBtnTexture1);
  8. slideBtnTextures.pushBack(slideBtnTexture2);
  9. slideBtn->setScale(0.5);
  10. slideBtn->setPosition(Point(visibleOrigin.x+100,visibleOrigin.y+50));
  11. this->addChild(slideBtn,2);
  12.  
  13. jumpBtn=Sprite::create("jumpButton.png");
  14. auto jumpBtnTexture1=Sprite::create("jumpButton.png")->getTexture();
  15. auto jumpBtnTexture2=Sprite::create("jumpButtonPress.png")->getTexture();
  16. jumpBtnTextures.pushBack(jumpBtnTexture1);
  17. jumpBtnTextures.pushBack(jumpBtnTexture2);
  18. jumpBtn->setScale(0.5);
  19. jumpBtn->setPosition(Point(visibleOrigin.x+visibleSize.width-100,visibleOrigin.y+50));
  20. this->addChild(jumpBtn,2);

触摸检测,用于控制按钮
滑行时动态更换纹理
跳跃时给角色一个向上的速度,暂停动画,更换纹理
要注意的是,一开始只能二段跳,接了道具之后可以三段跳
  1. bool GameScene::onTouchBegan(Touch *touch,Event *event)
  2. {
  3. auto touchPoint=touch->getLocation();
  4. //检测是否触摸在按钮区域
  5. if(slideBtn->getBoundingBox().containsPoint(touchPoint))
  6. {
  7. slideBtn->setTexture(slideBtnTextures.at(1));
  8. player->slide();
  9. }
  10.  
  11. if(jumpTimes<jumpTotal&&jumpBtn->getBoundingBox().containsPoint(touchPoint))
  12. {
  13. if(isSound)
  14. SimpleAudioEngine::getInstance()->playEffect("jump.wav"); //播放跳跃音效
  15. jumpBtn->setTexture(jumpBtnTextures.at(1));
  16. player->jump();
  17. jumpTimes++;
  18. }
  19. return true;
  20. }
  21.  
  22. void GameScene::onTouchEnded(Touch *touch,Event *event)
  23. {
  24. auto touchPoint=touch->getLocation();
  25. //判断是释放时是否在按钮区域
  26. if(slideBtn->getBoundingBox().containsPoint(touchPoint))
  27. {
  28. slideBtn->setTexture(slideBtnTextures.at(0));
  29. player->run();
  30. }
  31.  
  32. if(jumpBtn->getBoundingBox().containsPoint(touchPoint))
  33. {
  34. jumpBtn->setTexture(jumpBtnTextures.at(0));
  35. }
  36.  
  37. }

碰撞检测
  1. bool GameScene::onContactBegin(const PhysicsContact &contact)
  2. {
  3. jumpTimes=0; //落回地面就将已跳跃次数清零
  4.  
  5. //获得被碰撞物体,getShapeA getShapeB要尝试一下
  6. auto target=contact.getShapeA()->getBody()->getNode();
  7. if(target->getTag()==STAR)
  8. {
  9. //碰到星星就涨分,星星消失
  10. gameMap->moveNode(target);
  11. addscore(100); //拾取星星得100
  12. }
  13. else if(target->getTag()==NPC&&target->getPositionY()+target->getContentSize().height/2<player->getPositionY()) //此处要用else if,只有当角色在怪物头上才能踩中
  14. {
  15. gameMap->moveNode(target);
  16. addscore(150); //踩怪得150
  17. }
  18. else if(target->getTag()==NPC&&target->getPositionY()+target->getContentSize().height/2>=player->getPositionY()) //如果角色正面遇到怪物就挂了
  19. gameOver();
  20. else if(target->getTag()==TOOL)
  21. {
  22. jumpTotal=3;
  23. auto toolIcon=Sprite::create("accelerate_state.png");
  24. toolIcon->setPosition(Point(visibleOrigin.x+180,visibleOrigin.y+50));
  25. this->addChild(toolIcon,2);
  26. target->removeFromParent(); //道具只出现一次,从parent里面删除
  27. addscore(300); //道具300
  28. }
  29.  
  30. //落回地面恢复跑步状态
  31. if(player->playerState==JUMP)
  32. player->run();
  33.  
  34. return true;
  35. }

碰撞检测的逻辑主要是
  • 判断碰撞的是砖块则继续奔跑
  • 判断碰撞的是怪物,并且是踩在投上,则消除怪物,得分
  • 判断碰撞的是拾取物,则消除拾取物,得分,如果是道具的话则获得三段跳的能力
  • 判断碰撞是正面遇到怪物,则游戏结束

游戏结束的逻辑
  • 正面遇到怪物
  • 落到屏幕底下
  1. void GameScene::gameOver()
  2. {
  3. //游戏结束停止所有的调度器
  4. gameMap->unscheduleAllSelectors();
  5. this->unscheduleAllSelectors();
  6. //播放游戏结束声音
  7. if(isSound)
  8. SimpleAudioEngine::getInstance()->playEffect("gameover.wav");
  9.  
  10. //游戏结束出现菜单
  11. visibleSize=Director::getInstance()->getVisibleSize();
  12. visibleOrigin=Director::getInstance()->getVisibleOrigin();
  13. auto gameOverPanel=Node::create();
  14. auto overLabel=Sprite::create("gameover.png");
  15. overLabel->setPosition(visibleOrigin.x+visibleSize.width/2,visibleOrigin.y+visibleSize.height/2+100);
  16. gameOverPanel->addChild(overLabel);
  17.  
  18. auto backItem=MenuItemImage::create("back_to_menu.png","back_to_menu_press.png",[](Object *sender)
  19. {
  20. //用lambda表达式作为菜单函数回调
  21. auto mainMenu=MainMenu::createScene();
  22. TransitionScene *transition=TransitionFade::create(1.0f,mainMenu);
  23. Director::getInstance()->replaceScene(transition);
  24. });
  25. auto backMenu=Menu::createWithItem(backItem);
  26. backMenu->setPosition(visibleOrigin.x+visibleSize.width/2,visibleOrigin.y+visibleSize.height/2-50);
  27.  
  28. gameOverPanel->addChild(backMenu);
  29.  
  30. gameOverPanel->setPositionY(visibleOrigin.y+visibleSize.height);
  31. this->addChild(gameOverPanel,3);
  32. //滑入gameover logo,注意node的锚点在左下角
  33. gameOverPanel->runAction(MoveTo::create(0.5f,Vec2(visibleOrigin.x,visibleOrigin.y)));
  34.  
  35. }

其他逻辑
都放到update这个函数里面进行

角色被阻挡后赶到原来的位置

  1. //当角色被挡道之后跟上原来的位置
  2. float step=2.0f;
  3. if(player->getPositionX()<2*BLOCK_SIZE)
  4. player->setPositionX(player->getPositionX()+step);
  5. if(player->getPositionX()>2*BLOCK_SIZE)
  6. player->setPositionX(player->getPositionX()-step);

加分
  1. void GameScene::addscore(float number)
  2. {
  3. if(isSound)
  4. SimpleAudioEngine::getInstance()->playEffect("point.mp3"); //播放得分音效
  5. score+=number;
  6. scoreLabel->setString(String::createWithFormat("score: %d",score)->_string);
  7. }

5 设置场景

设置游戏关卡、游戏角色和声音,这里懒得加xml配置文件存储。
  1. //春天
  2. auto springItem=MenuItemImage::create("spring_icon.png","spring_icon_press.png",[](Object *sender)
  3. {
  4. //修改关卡
  5. level=SPRING;
  6. textLevel->setString("level: Spring");
  7. });
  8.  
  9. springItem->setPosition(visibleOrigin.x+visibleSize.width/4+35,visibleOrigin.y+visibleSize.height/4*3);
  10. //冬天
  11. auto winterItem=MenuItemImage::create("winter_icon.png","winter_icon_press.png",[](Object *sender)
  12. {
  13. //修改关卡
  14. level=WINTER;
  15. textLevel->setString("level: Winter");
  16. });
  17. winterItem->setPosition(visibleOrigin.x+visibleSize.width/4*3-35,visibleOrigin.y+visibleSize.height/4*3);
  18. //男生
  19. auto boyItem=MenuItemImage::create("boy1.png","boy_jump.png",[](Object *sender)
  20. {
  21. //修改角色
  22. playerType=BOY;
  23. textPlayer->setString("player: Boy");
  24. });
  25. boyItem->setPosition(visibleOrigin.x+visibleSize.width/2,visibleOrigin.y+visibleSize.height/2-100);
  26. //女生
  27. auto girlItem=MenuItemImage::create("girl1.png","girl_jump.png",[](Object *sender)
  28. {
  29. //修改角色
  30. playerType=GIRL;
  31. textPlayer->setString("player: Girl");
  32. });
  33. girlItem->setPosition(visibleOrigin.x+visibleSize.width/2+200,visibleOrigin.y+visibleSize.height/2-100);
  34.  
  35. //声音开关
  36. auto soundItem=MenuItemImage::create("sound_on.png","sound_off.png",[](Object *sender)
  37. {
  38. //修改声音
  39. isSound=!isSound;
  40. textSound->setString(isSound?"sound: On":"sound: Off");
  41. });
  42. soundItem->setPosition(visibleOrigin.x+soundItem->getContentSize().width/2,visibleOrigin.y+soundItem->getContentSize().height/2);
  43.  
  44.  
  45. auto menu=Menu::create(backItem,springItem,winterItem,boyItem,girlItem,soundItem,NULL);
  46. menu->setPosition(Point::ZERO);
  47.  
  48. this->addChild(menu);
通过全局变量与其他场景交互


6 关于场景

  1. //添加动态背景
  2. auto backGround=Sprite::create("about.jpg");
  3. backGround->setPosition(visibleOrigin.x+visibleSize.width/2,visibleOrigin.y+visibleSize.height/2);
  4. auto repeatanim=MoveBy::create(3.0f,Vec2(0,50));
  5. backGround->runAction(RepeatForever::create(Sequence::create(repeatanim,repeatanim->reverse(),NULL)));
  6. this->addChild(backGround,0);
  7.  
  8. //添加关于告示
  9. auto aboutLabel=Sprite::create("aboutLabel.png");
  10. aboutLabel->setPosition(visibleOrigin.x+visibleSize.width/2,visibleOrigin.y+visibleSize.height/2);
  11. this->addChild(aboutLabel,1);
  12. auto text=LabelBMFont::create("author:tashaxing\nE-mail:tashaxing@163.com\n\nWish you have fun!","bitmapFontChinese.fnt");
  13. text->setPosition(visibleOrigin.x+visibleSize.width/2,visibleOrigin.y+visibleSize.height/2);
  14. this->addChild(text,2);
一些简介


效果

















整个demo也做了蛮久的,很多图片和图标,配色都是我自己ps的,算是策划、美术和程序一人承担了。

源码下载
csdn: 跑酷游戏
github: parkour

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