• cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第六步--金币&岩石加入而且管理


    说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程,用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记

    这一步基本思路也是借鉴了前辈重写的泰然教程,金币和岩石抽象出一个基类,可是总的细节设计和前辈的非常大的不同,后面写完,我认为事实上Runner也能够继承自那个基类,只是因为自己还有其它事。就没去尝试啦。

    那么这里我是这样设计的:基类Base ,主要就是 setSprite,和 getSprite,以及getConSize--这个主要是为了后面金币和岩石的物理刚体绑定,那么金币Coin里面就 initBody--初始物理刚体。createAnimate--创建金币的旋转动画。Rock里面就是一个initBody。。

    当时因为这里是自己设计的。想得比較乱,然后发现,事实上initBody 也能够抽象在基类里面。这里就没有改了。

    然后,有了Coin 和 Rock,它们的出现,隐藏。以及位置放置,我们就用一个BaseManager来完毕,那么这里我是学习了 笨木头的方法: 为了反复的 create 金币,每次金币走出屏幕外。或者被主角吃了,我们就让它不可见,然后在BaseManager里面用一个update函数。对于不可见的金币我们让它重现江湖。。

    OK上马:Base.h  & Base.cpp

    1. #ifndef __Base__H__  
    2. #define __Base__H__  
    3.   
    4. #include "cocos2d.h"  
    5.   
    6. class Base : public cocos2d::Node{  
    7. public:  
    8.     Base();  
    9.   
    10.     void setSprite(cocos2d::Sprite* sprite);  
    11.     cocos2d::Sprite* getSprite();  
    12.   
    13.     cocos2d::Size getConSize();  
    14.   
    15. private:  
    16.     cocos2d::Sprite* m_sprite;  
    17. };/**/  
    18.   
    19. #endif  

    [html] view plaincopy
    1. #include "Base.h"  
    2.   
    3. USING_NS_CC;  
    4.   
    5. Base::Base(){  
    6.     m_sprite = NULL;  
    7. }  
    8.   
    9. void Base::setSprite(Sprite* sprite){  
    10.     m_sprite = sprite;   
    11.     //要加入到子节点中 ,才干被显示出来  
    12.     this->addChild(m_sprite);  
    13. }  
    14.   
    15. Sprite* Base::getSprite(){  
    16.     return m_sprite;  
    17. }  
    18.   
    19. Size Base::getConSize(){  
    20.     return m_sprite->getContentSize();  
    21. }  
    金币 Coin.h & .cpp

    1. #ifndef __Coin__H__  
    2. #define __Coin__H__  
    3.   
    4. #include "Base.h"  
    5.   
    6. class Coin : public Base{  
    7. public:  
    8.     virtual bool init();  
    9.     CREATE_FUNC(Coin);  
    10.   
    11.     //金币动作  
    12.     cocos2d::Animate* createAnimate(cocos2d::SpriteFrameCache* frameCache);  
    13.     //物理刚体  
    14.     void initBody();  
    15.   
    16. private:   
    17. };/**/  
    18.   
    19. #endif  
    20. ------------------------.cpp---------------------------------  
    21. #include "Coin.h"  
    22.   
    23. USING_NS_CC;  
    24.   
    25. bool Coin::init(){  
    26.     if(!Node::init()){  
    27.         return false;  
    28.     }  
    29.   
    30.     //缓存池  
    31.     auto frameCache = SpriteFrameCache::getInstance();  
    32.     frameCache->addSpriteFramesWithFile("parkour.plist","parkour.png");  
    33.   
    34.     auto sprite = Sprite::createWithSpriteFrameName("coin0.png");  
    35.   
    36.     //绑定  
    37.     setSprite(sprite);  
    38.     //运行动作  
    39.     getSprite()->runAction(createAnimate(frameCache));  
    40.     //绑定刚体  
    41.     initBody();  
    42.   
    43.     return true;  
    44. }  
    45.   
    46. Animate* Coin::createAnimate(SpriteFrameCache* frameCache){  
    47.   
    48.   
    49.     SpriteFrame* frame = NULL;  
    50.     //数组不行 要用vector  
    51.     //auto frameArray = Array::create();  
    52.     //frameArray->retain();  
    53.     Vector<SpriteFrame*>frameArray;  
    54.   
    55.     // 用一个列表保存全部SpriteFrame对象   
    56.     for(int i = 0; i <= 7; i++) {  
    57.         /* 从SpriteFrame缓存池中获取CCSpriteFrame对象 */  
    58.         frame = frameCache->spriteFrameByName(String::createWithFormat("coin%d.png", i)->getCString());  
    59.         frameArray.pushBack(frame);  
    60.   
    61.     }   
    62.     /* 使用SpriteFrame列表创建动画对象 */  
    63.     auto animation = Animation::createWithSpriteFrames(frameArray);  
    64.   
    65.     animation->setLoops(-1);  
    66.   
    67.     animation->setDelayPerUnit(0.1f);  
    68.   
    69.     /* 将动画包装成一个动作 */  
    70.     auto action = Animate::create(animation);  
    71.   
    72.     return action;  
    73. }  
    74.   
    75. void Coin::initBody(){  
    76.     auto phyBody = PhysicsBody::createEdgeBox(getSprite()->getContentSize());  
    77.     phyBody->setCategoryBitmask(1);  
    78.     phyBody->setCollisionBitmask(1);  
    79.     phyBody->setContactTestBitmask(1);  
    80.       
    81.     this->setPhysicsBody(phyBody);  
    82. }  
    岩石Rock.h & .cpp

    1. <span style="font-size:14px;">#ifndef __Rock__H__  
    2. #define __Rock__H__  
    3.   
    4. #include "Base.h"  
    5. #include "cocos2d.h"  
    6.   
    7. class Rock : public Base{  
    8. public:  
    9.     virtual bool init();  
    10.     CREATE_FUNC(Rock);  
    11.   
    12.     void initBody();  
    13. };/**/  
    14.   
    15. #endif  
    16. -------------------------------------------  
    17. #include "Rock.h"  
    18.   
    19. USING_NS_CC;  
    20.   
    21. bool Rock::init(){  
    22.     if(!Node::init()){  
    23.         return false;  
    24.     }  
    25.   
    26.     auto frameCache = SpriteFrameCache::getInstance();  
    27.     frameCache->addSpriteFramesWithFile("parkour.plist","parkour.png");  
    28.   
    29.     auto sprite = Sprite::createWithSpriteFrameName("rock.png");  
    30.   
    31.     setSprite(sprite);  
    32.   
    33.     initBody();  
    34.   
    35.     return true;  
    36. }  
    37.   
    38. void Rock::initBody(){  
    39.     auto phyBody = PhysicsBody::createEdgeBox(getSprite()->getContentSize());  
    40.     phyBody->setCategoryBitmask(1);  
    41.     phyBody->setCollisionBitmask(1);  
    42.     phyBody->setContactTestBitmask(1);  
    43.       
    44.     this->setPhysicsBody(phyBody);  
    45. }</span><span style="font-size:18px;">  
    46. </span>  
    那么这里主要重点看 管理类BaseManager.h & .cpp

    1. #ifndef __BaseManager__H__  
    2. #define __BaseManager__H__  
    3.   
    4. #include "cocos2d.h"  
    5. #include "Coin.h"  
    6. #include "Rock.h"  
    7.   
    8.   
    9. #define coinNum 4  
    10. #define coinTag 2  //这里关于Tag 用于后面的碰撞检測  
    11. #define rockNum 2  
    12. #define rockTag 3  
    13.   
    14. class BaseManager : public cocos2d::Node{  
    15. public:  
    16.     CREATE_FUNC(BaseManager);  
    17.     virtual bool init();  
    18.     virtual void update(float dt);  
    19.   
    20. private:  
    21.     void createCoin();  
    22.     cocos2d::Array* m_coinArr;  
    23.   
    24.     void createRock();  
    25.     cocos2d::Array* m_rockArr;  
    26. };/**/  
    27.   
    28. #endif  
    29. --------------------------------------------------------  
    30. #include "BaseManager.h"  
    31.   
    32. #define ground_hight 59  
    33.   
    34. USING_NS_CC;  
    35.   
    36. bool BaseManager::init(){  
    37.     if(!Node::init()){  
    38.         return false;  
    39.     }  
    40.   
    41.     createCoin();  
    42.   
    43.     createRock();  
    44.   
    45.     this->scheduleUpdate();  
    46.   
    47.     return true;  
    48. }  
    49.   
    50. void BaseManager::createCoin(){  
    51.     m_coinArr = Array::create();  
    52.     m_coinArr->retain();  
    53.   
    54.     Coin* coin = NULL;  
    55.   
    56.     for(int i = 1; i <= coinNum; ++ i){  
    57.         coin = Coin::create();  
    58.   
    59.         coin->setVisible(false);  
    60.   
    61.         coin->setTag(coinTag);  
    62.   
    63.         //记得加入  
    64.         this->addChild(coin);  
    65.   
    66.         m_coinArr->addObject(coin);  
    67.     }/**/  
    68. }  
    69.   
    70. void BaseManager::createRock(){  
    71.     m_rockArr = Array::create();  
    72.     m_rockArr->retain();  
    73.   
    74.     Rock* rock = NULL;  
    75.   
    76.     float dis = 960;//两岩石的间距  
    77.   
    78.     for(int i = 1; i <= rockNum; ++ i){  
    79.         rock = Rock::create();  
    80.   
    81.         rock->setTag(rockTag);  
    82.   
    83.         rock->setPosition(dis,ground_hight+rock->getConSize().height/2);  
    84.         dis += 640;  
    85.   
    86.         //记得加入  
    87.         this->addChild(rock);  
    88.   
    89.         m_rockArr->addObject(rock);  
    90.     }/**/  
    91. }  
    92.   
    93. void BaseManager::update(float dt){  
    94.     Ref* obj = NULL;  
    95.     Coin* coin = NULL;  
    96.   
    97.     //须要重置金币的个数  
    98.     int setNum = 0;  
    99.     CCARRAY_FOREACH(m_coinArr,obj){  
    100.         coin = (Coin*)obj;  
    101.   
    102.         //不在屏幕  
    103.         if(coin->getPositionX() < -coin->getConSize().width/2){  
    104.             coin->setVisible(false);  
    105.         }  
    106.   
    107.         //要是不可见,要不就是不在屏幕里,要不就是被碰撞了  
    108.         if( !coin->isVisible() ){  
    109.             setNum ++;  
    110.         }  
    111.   
    112.         //让金币移动  
    113.         coin->setPositionX(coin->getPositionX()-2);  
    114.     }  
    115.   
    116.     //4个所有重置  
    117.     if(setNum == 4){  
    118.         int i = 0;  
    119.         float posX = 640+50;  
    120.         float posY = ground_hight + 15 + CCRANDOM_0_1()*60;  
    121.         CCARRAY_FOREACH(m_coinArr,obj){  
    122.             coin = (Coin*)obj;  
    123.             //不在屏幕  
    124.             if(coin->getPositionX() < -coin->getConSize().width/2){  
    125.                 coin->setVisible(false);  
    126.             }  
    127.             //要是不可见。要不就是不在屏幕里。要不就是被碰撞了  
    128.             if( !coin->isVisible() ){  
    129.                 //两个两个一起  
    130.                 if(i < 2){  
    131.                     posX += 30;//两个金币同一高度,间隔30  
    132.                 }else{  
    133.                     //又一次重置位置   
    134.                     i = -1;  
    135.                     posY = ground_hight + 15 + CCRANDOM_0_1()*60;  
    136.                     posX += 400;  
    137.                 }  
    138.                 i ++;//重置金币个数记录  
    139.                 //  
    140.                 coin->setVisible(true);  
    141.                 coin->setPosition(posX,posY);  
    142.             }  
    143.         }  
    144.     }  
    145.   
    146.     Ref* rockObj = NULL;  
    147.     Rock* rock = NULL;  
    148.   
    149.     CCARRAY_FOREACH(m_rockArr,rockObj){  
    150.         rock = (Rock*)rockObj;  
    151.   
    152.         if(rock->getPositionX() < -rock->getConSize().width/2){  
    153.             rock->setVisible(false);  
    154.         }  
    155.         if(rock->isVisible() == false){  
    156.             float posX = 1280;  
    157.             float posY = ground_hight + rock->getConSize().height/2;  
    158.             if(CCRANDOM_MINUS1_1() > 0){  
    159.                 posY += 50;  
    160.             }  
    161.             rock->setPosition(posX,posY);  
    162.             rock->setVisible(true);  
    163.         }  
    164.   
    165.         rock->setPositionX(rock->getPositionX()-2);  
    166.     }  
    167. }  
    代码中,我们主要看看 两个Create 函数,以及update函数。

    createCoin :我们先确定整个过程仅仅有4个金币,而且一開始都设置为 不可见,那么在update 函数中,我们对全部的金币遍历,假设是不可见,那么我们就让它可见,而且两个一起 间隔30 ,同一高度放置,然后 高度不一致。可能出现地面,可能须要主角跳起来才可以到,而createRock。我们整个屏幕就放两个就够了。这两个也有两个位置,一个在地面。一个在空中须要主角crouch或者Jump也可以。。。事实上这里的位置放置算法(应该算是有点算法的味道吧) 写得非常乱,这里就所有是我自己设计的。。

    。感觉金币岩石出现的非常没有 美观。

    只是也还算是能够执行。

    。。。。


    那么我们能够測试一下。在PlayScene中加入成员

    BaseManager* m_manager;

    然后在init函数中 create 增加 this的addChild中

    可是这里的话,我们建议把 Coin & Rock 两个类里面的 init 函数中的 initBody 先凝视掉,然后再測试。不然带着刚体,主角跑起来非常不顺利。測试例如以下:


    以下就要来利用物理碰撞检測了---全部的也就快结束啦


    个人愚昧观点,欢迎指正与讨论

  • 相关阅读:
    textarea 里设置 style="resize:none"
    linux 脚本
    RabbitMQ、Redis、ZeroMQ、ActiveMQ、Kafka/Jafka对比
    python安装过程
    linux下安装python3
    java实现定时任务 Schedule
    Spring 定时任务之 @Scheduled cron表达式
    docker部署
    设备连接服务器
    springboot实现fileUpLoad
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6885397.html
Copyright © 2020-2023  润新知