乐码库:一个极速、放心、纯净的下载站! 更新: 资源发布
  • 您的位置:首页 > 技术文档 > AndRoid > Android实现消水果游戏代码分享
  • 收藏本页
      Android实现消水果游戏代码分享
      发布时间:2016-12-21 08:08:19 关键词: 消水果游戏
      内容简介:本文给大家分享实现开心消水果游戏的核心代码,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友一起看看吧

    消水果游戏大家都玩过吧,今天小编给大家分享实现消水果游戏的代码,废话不多说了,具体代码如下所示:

     #include "InGameScene.h"
    #include "PauseLayer.h"
    #include "ScoreScene.h"
    #include "AppDelegate.h"
    extern "C"
    {
      void showAds()
      {
      }
      void hideAds()
      {
      }
    }
    using namespace cocos2d;
    using namespace CocosDenshion;
    bool InGameScene::isPaused = false;
    unsigned int InGameScene::level = 1;
    unsigned int InGameScene::background = 1;
    unsigned int InGameScene::bomb = 2;
    const unsigned int InGameScene::randomDrop[8] = {0, 5, 2, 7, 1, 4, 3, 6};
    const char *InGameScene::strMode[3] = {"Simple", "Normal", "Expert"};
    const unsigned int InGameScene::limitTime[3] = {60, 60, 60};
    const unsigned int InGameScene::baseScore[3] = {20, 50, 100};
    const unsigned int InGameScene::limitScore[3] = {6000, 10000, 12000};
    const unsigned int InGameScene::limitFireball[3] = {100, 70, 30};
    const unsigned int InGameScene::limitCrazy[3] = {8, 10, 6};
    void InGameScene::reset()
    {
      InGameScene::isPaused = false;
    }
    InGameScene::InGameScene()
      : m_nDiamondScale(1.0f)
      , m_nMagicCount(0)
      , m_pMagicProgress(NULL)
      , m_nTime(0)
      , m_nScore(0)
      , m_nTempScore(0)
      , m_nDiamondRow(0)
      , m_nDiamondLine(0)
      , m_bIsReadyGoEnd(false)
      , m_pPause(NULL)
      , m_pDiamondBatchNode(NULL)
      , m_pRemovedDiamond(NULL)
      , m_pScoreLable(NULL)
      , m_pTimerBar(NULL)
      , m_pMoveLable(NULL)
      , m_pTargetLable(NULL)
      , m_bFireballMode(false)
      , m_bError(false)
      , m_nTimeCount(0)
      , m_nCrazyCount(0)
      , m_bIsCrazyMode(false)
      , m_nDiamondCount(0)
      , m_pEffectDict(NULL)
      , m_startType(-1)
      , m_moveStatus(-1)
      , moves_number_(0)
    {
    }
    InGameScene::~InGameScene()
    {
      CC_SAFE_RELEASE_NULL(m_pPause);
      CC_SAFE_RELEASE_NULL(m_pMagicProgress);
      CC_SAFE_RELEASE_NULL(m_pMoveLable);
      CC_SAFE_RELEASE_NULL(m_pTargetLable);
      CC_SAFE_RELEASE_NULL(m_pTimerBar);
      CC_SAFE_RELEASE_NULL(m_pScoreLable);
      CC_SAFE_RELEASE_NULL(m_pDiamondBatchNode);
      CC_SAFE_RELEASE_NULL(m_pRemovedDiamond);
      CC_SAFE_RELEASE_NULL(m_pEffectDict);
    }
    void InGameScene::onEnter()
    {
      Image::setPVRImagesHavePremultipliedAlpha(true);
      this->setTouchEnabled(true);
      Layer::onEnter();
    }
    void InGameScene::onExit()
    {
      Layer::onExit();
    }
    Scene *InGameScene::scene()
    {
      Scene *scene = NULL;
      do
      {
        scene = Scene::create();
        CC_BREAK_IF(! scene);
        InGameScene *layer = InGameScene::create();
        CC_BREAK_IF(! layer);
        scene->addChild(layer);
      }
      while (0);
      return scene;
    }
    bool InGameScene::init()
    {
      bool bRet = false;
      do
      {
        CC_BREAK_IF(! Layer::init());
        auto listener = EventListenerTouchOneByOne::create();
        listener->setSwallowTouches(false);
        listener->onTouchBegan = CC_CALLBACK_2(InGameScene::onTouchBegan, this);
        listener->onTouchEnded = CC_CALLBACK_2(InGameScene::onTouchEnded, this);
        listener->onTouchMoved = CC_CALLBACK_2(InGameScene::onTouchMoved, this);
        _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
        hideAds();
        InGameScene::isPaused = false;
        m_nDiamondRowMax = 8;
        m_nDiamondLineMax = 9;
        m_nDiamondScale = 1.12f;
        InGameScene::level = UserDefault::getInstance()->getIntegerForKey("level");
        m_nDiamondCount = InGameScene::level + 3;
        if (m_nDiamondCount < 3 || m_nDiamondCount > 5)
        {
          break;
        }
        m_nTime = InGameScene::limitTime[InGameScene::level];
        m_nTime = 1200;
        Size winSize = Director::getInstance()->getWinSize();
        auto sp = Sprite::create("gui/df.png");
        addChild(sp, -3);
        sp->setPosition(Vec2(winSize.width / 2, winSize.height / 2));
        auto sp_top = Sprite::create("gui/top_bar.png");
        addChild(sp_top, 3);
        sp_top->setPosition(Vec2(winSize.width / 2, 1280 - 97));
        m_pRemovedDiamond = __Array::create();
        m_pRemovedDiamond->retain();
        SpriteFrameCache::getInstance()->addSpriteFramesWithFile("effects/effects-800x_port_mdpi.plist");
        m_pScoreLable = Label::createWithCharMap("gui/white_font.png", 25, 29, '0');
        m_pScoreLable->retain();
        m_pScoreLable->setString("0");
        m_pScoreLable->setPosition(Vec2(583, 1280-55));
        this->addChild(m_pScoreLable, 100);
        m_pMoveLable = Label::createWithCharMap("gui/white_font.png", 25, 29, '0');
        m_pMoveLable->retain();
        m_pMoveLable->setPosition(Vec2(583, 1280-140));
        m_pMoveLable->setString("50");
        addChild(m_pMoveLable,100);
        m_pTargetLable = Label::createWithCharMap("gui/white_font.png", 25, 29, '0');
        m_pTargetLable->retain();
        m_pTargetLable->setPosition(Vec2(116, 1280-58));
        m_pTargetLable->setString("1000");
        addChild(m_pTargetLable,100);
        //创建暂停按钮
        auto *pPauseItem = MenuItemImage::create("gui/game_stop.png", "gui/game_stop.png", this, menu_selector(InGameScene::menuPauseCallback));
        pPauseItem->setPosition(Vec2(46, 1280-142));
        Menu *pMenu = Menu::create(pPauseItem, NULL);
        CC_BREAK_IF(! pMenu);
        pMenu->setPosition(Vec2::ZERO);
        this->addChild(pMenu, 200);
    
        SpriteFrameCache::getInstance()->addSpriteFramesWithFile("gems/gemTexture-800x_port_mdpi.plist");
        m_pDiamondBatchNode = SpriteBatchNode::create("gems/gemTexture-800x_port_mdpi.png");
        m_pDiamondBatchNode->retain();
        this->addChild(m_pDiamondBatchNode);
        this->playReadyGo();
        this->addFirstDiamond();
        this->scheduleUpdate();
        m_pEffectDict = __Dictionary::create();
        m_pEffectDict->retain();
        drawBg();
        bRet = true;
      }
      while (0);
      return bRet;
    }
    void InGameScene::playReadyGo()
    {
      if (UserDefault::getInstance()->getBoolForKey("isEffectEnabled", false))
      {
        SimpleAudioEngine()->playEffect("sounds/readyGo.ogg");
      }
      LabelTTF *readyGo = LabelTTF::create("Ready", "fonts/Verdana Bold.ttf", 60.0f);
      readyGo->setPosition(Vec2(400, 750));
      this->addChild(readyGo);
      readyGo->setScale(0.1f);
      readyGo->runAction(Sequence::create(
                  CCScaleTo::create(1.1f, 1.0f),
                  DelayTime::create(.3f),
                  CallFuncN::create(this, callfuncN_selector(InGameScene::readyCallback)),
                  NULL));
    }
    void InGameScene::readyCallback(Node *pSender)
    {
      LabelTTF *p = (LabelTTF *)pSender;
      p->setFontSize(65.f);
      p->setString("Go!!!");
      p->runAction(Sequence::create(
               DelayTime::create(.7f),
               CallFuncN::create(this, callfuncN_selector(InGameScene::goCallback)),
               NULL));
    }
    void InGameScene::goCallback(Node *pSender)
    {
      this->removeChild(pSender);
    }
    void InGameScene::addFirstDiamond()
    {
      SpriteFrameCache::getInstance()->addSpriteFramesWithFile("gems/gemTexture-800x_port_mdpi.plist");
      this->schedule(schedule_selector(InGameScene::addDiamond), 1.2f / (m_nDiamondRowMax * m_nDiamondLineMax));
    }
    Vec2 InGameScene::getPositionByRowAndLine(int row, int line)
    {
      float x = CELL_WIDTH * row + OFFSET_X;
      float y = CELL_HEIGHT * line + OFFSET_Y;
      return Vec2(x, y);
    }
    void InGameScene::addDiamond(float delta)
    {
      int diamondType = rand() % 5;
      Diamond *pDiamond = Diamond::createWithSpriteFrameName(Diamond::TypeStr[diamondType]);
      pDiamond->setType(diamondType);
      pDiamond->setPosition(Vec2(CELL_WIDTH * randomDrop[m_nDiamondRow] + 50, 1280 + CELL_HEIGHT));
      pDiamond->setScale(0.9);
      m_pDiamondBatchNode->addChild(pDiamond);
      pDiamond->setMoving(true);
      pDiamond->runAction(Sequence::create(
                  MoveTo::create(.25f, Vec2(CELL_WIDTH * randomDrop[m_nDiamondRow] + OFFSET_X, CELL_HEIGHT * m_nDiamondLine + OFFSET_Y)),
                  CallFuncN::create(this, callfuncN_selector(InGameScene::addEndCallback)),
                  NULL));
      m_pDiamond[m_nDiamondLine][randomDrop[m_nDiamondRow]] = pDiamond;
      if (++m_nDiamondRow == m_nDiamondRowMax)
      {
        m_nDiamondRow = 0;
        ++m_nDiamondLine;
      }
      if (m_nDiamondLine == m_nDiamondLineMax)
      {
        m_bIsReadyGoEnd = true; //首次播放宝石掉落动画结束
        this->unschedule(schedule_selector(InGameScene::addDiamond)); //宝石添加动画结束
        if (! InGameScene::isPaused)
        {
    //      m_pTimerBar->runAction(MoveTo::create(float(InGameScene::limitTime[InGameScene::level]), Vec2(-380, 95)));
    //      this->schedule(schedule_selector(InGameScene::updateTime), 1.0f); //开始计时
        }
      }
    }
    void InGameScene::drawBg()
    {
      for(auto line = 0; line < m_nDiamondLineMax; line++)
      {
        for(auto row = 0; row < 7; row++)
        {
          auto sp1 = Sprite::create("gui/b1.png");
          auto sp2 = Sprite::create("gui/b2.png");
          if(line%2 == 0)
          {
            if(row%2 == 0)
            {
              sp1->setPosition(getPositionByRowAndLine(row, line));
              sp2->setVisible(false);
            }
            else
            {
              sp2->setPosition(getPositionByRowAndLine(row, line));
              sp1->setVisible(false);
            }
          }
          else
          {
            if(row%2 == 0)
            {
              sp2->setPosition(getPositionByRowAndLine(row, line));
              sp1->setVisible(false);
            }
            else
            {
              sp1->setPosition(getPositionByRowAndLine(row, line));
              sp2->setVisible(false);
            }
          }
          addChild(sp1, BG_ODER);
          addChild(sp2, BG_ODER);
        }
      }
    }
    #define PAN 0.000001
    void InGameScene::DrawLine()
    {
      auto line = Sprite::create("gui/line.png");
      line->setPosition(last_position);
      line->setAnchorPoint(Vec2(1, 0.5));
      addChild(line, -1);
      m_lineObjs.push_back(line);
      if (fabs(last_position.x - cur_position.x) < PAN) {
        if (last_position.y - cur_position.y > 1.0f)
        {
          // 向下
          line->setRotation(270);
        }
        else
        {
          line->setRotation(90);
        }
      }
      else if(fabs(last_position.y - cur_position.y) < PAN)
      {
        if (last_position.x - cur_position.x < 1.0f) {
          line->setRotation(180);
        }
      }
      else
      {
        if (last_position.x - cur_position.x < 1.0f)
        {
          if (last_position.y - cur_position.y < 1.0f)
          {
            line->setRotation(135);
          }
          else
          {
            line->setRotation(225);
          }
        }
        else
        {
          if (last_position.y - cur_position.y < 1.0f)
          {
            line->setRotation(45);
          }
          else
          {
            line->setRotation(315);
          }
        }
      }
    }
    bool InGameScene::isNearby(int line, int row, int _type)
    {
      if (line > 0 && m_pDiamond[line-1][row]->getType() == _type)
      {
        return true;
      }
      if (line < m_nDiamondLineMax -1 && m_pDiamond[line+1][row]->getType() == _type)
      {
        return true;
      }
      if (row > 0 && m_pDiamond[line][row-1]->getType() == _type)
      {
        return true;
      }
      if (row < m_nDiamondRowMax - 1&& m_pDiamond[line][row+1]->getType() == _type)
      {
        return true;
      }
      if (line >0 && row > 3 && m_pDiamond[line-1][row-4]->getType() == _type)
      {
        return true;
      }
      if (line > 0&& row > 1 && m_pDiamond[line-1][row-2]->getType() == _type)
      {
        return true;
      }
      if (line < m_nDiamondLineMax && row < m_nDiamondRowMax - 2 && m_pDiamond[line+1][row+2]->getType() == _type)
      {
        return true;
      }
      if (line < m_nDiamondLineMax && row < m_nDiamondRowMax - 4 && m_pDiamond[line+1][row+4]->getType() == _type)
      {
        return true;
      }
      return false;
    }
    void InGameScene::onTouchMoved(Touch *pTouch, Event *pEvent)
    {
      if (m_moveStatus==0)
      {
        return;
      }
      if(m_startType != -1)
      {
        return;
      }
      log("c");
      Vec2 location = pTouch->getLocationInView();
      location = Director::getInstance()->convertToGL(location);
      for (int line = 0; line < m_nDiamondLineMax; ++line)
      {
        for (int row = 0; row < m_nDiamondRowMax; ++row)
        {
          if(!m_pDiamond[line][row])
          {
            continue;
          }
          if ((m_pDiamond[line][row])->boundingBox().containsPoint(location))
          {
            // 还在原来的格子里
            if (m_pRemovedDiamond->containsObject(m_pDiamond[line][row]))
            {
              return;
            }
            ssize_t count = m_pRemovedDiamond->count();
            if(count > 0)
            {
              // 颜色不是一样的
              if (m_pDiamond[line][row]->getType() != m_startType)
              {
                log("-- line end -- line(%d),row(%d)",line,row);
                m_moveStatus = 0;
                return;
              }
    //          if (!isNearby(line, row, m_startType))
    //          {
    //           
    //            return;
    //          }
              cur_position = getPositionByRowAndLine(row, line);
              DrawLine();
              last_position = cur_position;
              m_pDiamond[line][row]->setScale(1.05);
            }
            else
            {
            }
            // 将自己加入到队列中去
            m_pDiamond[line][row]->setTag(line * m_nDiamondRowMax + row);
            m_pRemovedDiamond->addObject(m_pDiamond[line][row]);
          }
        }
      }
      log("c-end");
    }
    bool InGameScene::onTouchBegan(Touch *pTouch, Event *pEvent)
    {
      if (! m_bIsReadyGoEnd)
      {
        return true;
      }
      if(m_startType != -1)
      {
        return true;
      }
      log("a");
      m_lineObjs.clear();
      m_pRemovedDiamond->removeAllObjects();
      m_moveStatus = -1;
      Vec2 location = pTouch->getLocationInView();
      location = Director::getInstance()->convertToGL(location);
      log("b");
      for (int line = 0; line < m_nDiamondLineMax; ++line)
      {
        for (int row = 0; row < m_nDiamondRowMax; ++row)
        {
          if (m_pDiamond[line][row] && (! m_pDiamond[line][row]->getMoving()))
          {
            if ((m_pDiamond[line][row])->boundingBox().containsPoint(location))
            {
              m_startType = m_pDiamond[line][row]->getType();
              last_position = getPositionByRowAndLine(row, line);
              log("m_starType %d",m_startType);
              return true;
            }
          }
        }
      }
      log("a-end");
      return true;
    }
    void InGameScene::onTouchEnded(Touch *pTouch, Event *pEvent)
    {
      m_moveStatus = -1;
      m_startType = -1;
      log("d");
      if(!handleSelectedDiamond())
      {
        log("sdf");
        return;
      }
      for(auto sp : m_lineObjs)
      {
        sp->removeFromParent();
      }
      m_lineObjs.clear();
      removeSelectedDiamond();
      schedule(schedule_selector(InGameScene::addRemovedDiamond), 1/40);
      restoreOriginalDiamond();
      log("d--end");
    }
    void InGameScene::findSameDiamond(int type)
    {
      m_pRemovedDiamond->removeAllObjects();
      for (int line = 0; line < m_nDiamondLineMax; ++line)
      {
        for (int row = 0; row < m_nDiamondRowMax; ++row)
        {
          Diamond *diamond = m_pDiamond[line][row];
          if (diamond && (! diamond->getMoving()))
          {
            if (diamond->getType() == type)
            {
              if (! m_pRemovedDiamond->containsObject(diamond))
              {
                diamond->setTag(line * m_nDiamondRowMax + row); //用tag记录下可能被删除的宝石的位置
                m_pRemovedDiamond->addObject(diamond);
              }
            }
          }
        }
      }
    }
    //如果点击的宝石少于3个,则返回false,等于或多于3个则返回true
    bool InGameScene::handleSelectedDiamond()
    {
      auto count = m_pRemovedDiamond->count();
      if (count < 2)
      {
        m_nCrazyCount = 0;
        if (m_bIsCrazyMode)
        {
          m_bIsCrazyMode = false;
          this->removeFireModeFlame();
        }
        return false;
      }
      playJumpScore(count);
      return true;
    }
    //-------------播放连击动画---------------//
    void InGameScene::playCombAnimation(unsigned int combCount)
    {
      LabelTTF *comb = LabelTTF::create(__String::createWithFormat("Combo %d+", combCount)->getCString(), "fonts/Verdana Bold.ttf", 60.0f);
      comb->setPosition(Vec2(400, 750));
      comb->setColor(ccc3(0, 255, 255));
      this->addChild(comb);
      comb->setScale(0.1f);
      comb->runAction(Sequence::create(
                CCScaleTo::create(.5f, 1.0f),
                DelayTime::create(.2f),
                CallFuncN::create(this, callfuncN_selector(InGameScene::removeCombCallback)),
                NULL));
    }
    void InGameScene::removeCombCallback(Node *pSender)
    {
      this->removeChild(pSender);
    }
    //-------------播放连击动画-END--------------//
    void InGameScene::update(float delta)
    {
      ++m_nTimeCount; // 计数,大概60次是一秒的时间
      if (m_nTimeCount > 75) //未在限定时间内完成连击,连击失败
      {
        if (m_bIsCrazyMode)
        {
          m_bIsCrazyMode = false;
          this->removeFireModeFlame();
        }
      }
    //  if (m_nCrazyCount > InGameScene::limitCrazy[InGameScene::level])
    //  {
    //    m_bIsCrazyMode = true;
    //    m_nTimeCount = .0f;
    //    m_nCrazyCount = 0;
    //    this->playFireModeFlame();
    //  }
    }
    void InGameScene::displayErrorDiamond()
    {
      m_bError = true;
      Diamond *removed = NULL;
      Ref *pObj = NULL;
      CCARRAY_FOREACH(m_pRemovedDiamond, pObj)
      {
        removed = (Diamond *)pObj;
        CC_BREAK_IF(! removed);
        removed->setDisplayFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(
                       Diamond::TypeBwStr[removed->getType()]));
      }
    }
    void InGameScene::restoreOriginalDiamond()
    {
      if (m_bError)
      {
        m_bError = false;
        Diamond *removed = NULL;
        Ref *pObj = NULL;
        CCARRAY_FOREACH(m_pRemovedDiamond, pObj)
        {
          removed = (Diamond *)pObj;
          CC_BREAK_IF(! removed);
          removed->setDisplayFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(
                         Diamond::TypeStr[removed->getType()]));
        }
      }
    }
    //启动分数跳动增加的动画
    void InGameScene::playJumpScore(int count)
    {
      m_nTempScore = InGameScene::baseScore[InGameScene::level] * count + 2 * (count - 3); //2*(count-3)宝石超过3个的奖励分
      m_nScore += m_nTempScore;
      this->schedule(schedule_selector(InGameScene::playJumpScoreUpdate), 0.4f / 60);
    }
    //分数跳动增加的动画
    void InGameScene::playJumpScoreUpdate(float delta)
    {
      if (m_nTempScore < 0)
      {
        __String *strScore = __String::createWithFormat("%d", m_nScore);
        m_pScoreLable->setString(strScore->getCString());
        this->unschedule(schedule_selector(InGameScene::playJumpScoreUpdate));
        return;
      }
      __String *strScore = __String::createWithFormat("%d", m_nScore - m_nTempScore);
      m_pScoreLable->setString(strScore->getCString());
      m_nTempScore -= InGameScene::baseScore[InGameScene::level] / 5;
    }
    //播放删除宝石时的动画
    void InGameScene::playDiamondExplosion(const Vec2 pos)
    {
      Vector<SpriteFrame * > diamondExplosionNormalFrame;
      for (int i = 1; i < 10; ++i)
      {
        SpriteFrame *frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(__String::createWithFormat("gem_explosion_normal%d.png", i)->getCString());
        diamondExplosionNormalFrame.pushBack(frame);
      }
      Animation *diamondAnimation = Animation::createWithSpriteFrames(diamondExplosionNormalFrame, 0.05f);
      Sprite *explosion = Sprite::createWithSpriteFrameName("gem_explosion_normal1.png");
      explosion->setPosition(pos);
      this->addChild(explosion);
      //播放完消失时的动画
      explosion->runAction(Sequence::create(
                   Animate::create(diamondAnimation),
                   //播放完消失时的动画后,删除它
                   CallFuncN::create(this, callfuncN_selector(InGameScene::removeExplosionCallback)),
                   NULL));
    }
    //删除宝石消失时的动画
    void InGameScene::removeExplosionCallback(Node *pSender)
    {
      this->removeChild(pSender, true);
    }
    //--------------点击宝石后的查询、移除、填充等处理--START-------------//
    void InGameScene::findSelectedDiamond(int line, int row)
    {
      m_pRemovedDiamond->removeAllObjects();
      // 递归查询相邻颜色相同的宝石
      findSelectedDiamond(line, row, m_pDiamond[line][row]->getType());
    }
    //递归查出所有颜色一样且紧挨一起的宝石,并记录在m_pRemovedDiamond中
    void InGameScene::findSelectedDiamond(int line, int row, int type)
    {
      if (line < 0 || line == m_nDiamondLineMax || row < 0 || row == m_nDiamondRowMax)
      {
        return;
      }
      Diamond *diamond = m_pDiamond[line][row];
      if (diamond && (! diamond->getMoving()))
      {
        if (diamond->getType() == type)
        {
          if (! m_pRemovedDiamond->containsObject(diamond))
          {
            diamond->setTag(line * m_nDiamondRowMax + row); //用tag记录下可能被删除的宝石的位置
            m_pRemovedDiamond->addObject(diamond);
            findSelectedDiamond(line, row - 1, type); //递归左侧
            findSelectedDiamond(line, row + 1, type); //递归右侧
            findSelectedDiamond(line + 1, row, type); //递归上侧
            findSelectedDiamond(line - 1, row, type); //递归下侧
          }
        }
      }
    }
    void InGameScene::removeSelectedDiamond()
    {
      Diamond *removed = NULL;
      Ref *pObj = NULL;
      CCARRAY_FOREACH(m_pRemovedDiamond, pObj)
      {
        removed = (Diamond *)pObj;
        if (removed == NULL)
        {
          continue;
        }
        this->playDiamondExplosion(removed->getPosition());
        int tag = removed->getTag();
        int line = tag / m_nDiamondRowMax, row = tag % m_nDiamondRowMax;
        m_pDiamondBatchNode->removeChild(removed, true);
        m_pDiamond[line][row] = NULL;
      }
    }
    //补齐被删掉的宝石
    void InGameScene::addRemovedDiamond(float delta)
    {
      int toLine, toRow;
      for (toLine = 0; toLine < m_nDiamondLineMax; ++toLine)
      {
        for (toRow = 0; toRow < m_nDiamondRowMax; ++toRow)
        {
          if (m_pDiamond[toLine][toRow] == NULL) //被删除掉的宝石的位置,即要掉落的目的地
          {
            int fromLine;
            for (fromLine = toLine + 1; fromLine < m_nDiamondLineMax; ++fromLine)
            {
              //被删除宝石的上方第一个存在,并处于固定状态,即没有在移动中的宝石
              if (m_pDiamond[fromLine][toRow])
              {
                //播放宝石被添加时掉落的效果
                if (m_pDiamond[fromLine][toRow]->getMoving())
                {
                  m_pDiamond[fromLine][toRow]->stopAllActions();
                }
                m_pDiamond[fromLine][toRow]->setMoving(true);
                m_pDiamond[fromLine][toRow]->runAction(Sequence::create(
                    MoveTo::create(0.25f, Vec2(100 * toRow + 50, 100 * toLine + 220)),
                    CallFuncN::create(this, callfuncN_selector(InGameScene::addEndCallback)),
                    NULL));
                m_pDiamond[toLine][toRow] = m_pDiamond[fromLine][toRow];
                m_pDiamond[fromLine][toRow] = NULL;
                return;
              }
            }
            if (fromLine == m_nDiamondLineMax)
            {
              int diamondType = rand() % 5;
              Diamond *pDiamond = Diamond::createWithSpriteFrameName(Diamond::TypeStr[diamondType]);
              pDiamond->setType(diamondType);
              pDiamond->setScale(0.9 ); //宝石放大,减少宝石间的间隙,才会彼此紧挨着
              pDiamond->setPosition(Vec2(100 * toRow + 50, 1280 + 100));
              m_pDiamondBatchNode->addChild(pDiamond, 2);
              //播放宝石被添加时掉落的效果
              pDiamond->setMoving(true);
              pDiamond->runAction(Sequence::create(
                          MoveTo::create(.25f, Vec2(100 * toRow + 50, 100 * toLine + 220)),
                          CallFuncN::create(this, callfuncN_selector(InGameScene::addEndCallback)),
                          NULL));
              //记录每个宝石的指针
              m_pDiamond[toLine][toRow] = pDiamond;
            }
            return;
          }
        }
      }
      if ((toLine == m_nDiamondLineMax) && (toRow == m_nDiamondRowMax))
      {
        this->unschedule(schedule_selector(InGameScene::addRemovedDiamond));
        m_moveStatus = -1;
        if (m_bFireballMode)
        {
          m_bFireballMode = false;
        }
      }
    }
    //宝石添加时滑动效果结束时,即宝石达到目的地时,计数减一,全部到达目的地时计数为零
    void InGameScene::addEndCallback(Node *pSender)
    {
      ((Diamond *)pSender)->setMoving(false);
    }
    //--------------点击宝石后的查询、移除、填充等处理--END-------------//
    //-----------------游戏计时和处理相关方法--START---------------//
    //时间一秒秒慢慢减少的效果,并时间将结束时,播放响应效果
    void InGameScene::updateTime(float dt)
    {
      //m_pTimeLable->setString(__String::createWithFormat("%02d", --m_nTime)->getCString());
      switch (m_nTime)
      {
      case 9:
        if (UserDefault::getInstance()->getBoolForKey("isEffectEnabled", false))
        {
          SimpleAudioEngine()->playEffect("sounds/Countdown.ogg");
        }
        break;
      case 10:
        // m_pTimerBar->setDisplayFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("timerBar2.png"));
        break;
      case 5:
        // m_pTimerBar->setDisplayFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("timerBar3.png"));
        break;
      case 1: //时间到了,显示Time's Up
      {
        this->unschedule(schedule_selector(InGameScene::updateTime));
        LabelTTF *timeUp = LabelTTF::create("Time's Up", "fonts/Verdana Bold.ttf", 50.f);
        timeUp->setPosition(Vec2(400, 650));
        this->addChild(timeUp);
        timeUp->runAction(Sequence::create(
                   CCScaleTo::create(1.0f, 1.3f),
                   CCCallFunc::create(this, callfunc_selector(InGameScene::timeUpCallback)),
                   NULL));
      }
      break;
      }
      //随机时间产生炸弹
      if (rand() % 60 < 3)
      {
        this->changeDiamondToBomb();
      }
    }
    //时间到后,跳转到相应场景
    void InGameScene::timeUpCallback()
    {
      UserDefault::getInstance()->setIntegerForKey("LastScore", m_nScore);
      if (m_nScore >= (int)(InGameScene::limitScore[InGameScene::level]))
      {
        ++InGameScene::background; //胜利后可切到下一个场景
        if (InGameScene::background > 4)
        {
          InGameScene::background = 1;
        }
        UserDefault::getInstance()->setBoolForKey("isPass", true);
        // 判断是否超过了最高分
        __String *highScore = __String::createWithFormat("HighScore%d", InGameScene::level);
        if (m_nScore > UserDefault::getInstance()->getIntegerForKey(highScore->getCString(), -1))
        {
          InGameScene::background = 5;
          UserDefault::getInstance()->setIntegerForKey(highScore->getCString(), m_nScore);
          //Scene *pScene = LevelUpScene::scene();
          //Director::getInstance()->replaceScene(pScene);
          //return;
        }
      }
      else
      {
        UserDefault::getInstance()->setBoolForKey("isPass", false);
      }
      showAds(); //显示广告
      Scene *pScene = ScoreScene::scene();
      Director::getInstance()->replaceScene(pScene);
    }
    //-----------------游戏计时和处理相关方法--END---------------//
    void InGameScene::changeDiamondToBomb()
    {
      int row = -1, line = -1;
      do
      {
        row = RANDOM_RANGE(0, m_nDiamondRowMax - 0.01);
        line = RANDOM_RANGE(0, m_nDiamondLineMax - 0.01);
      }
      while (m_pDiamond[line][row] == NULL || m_pDiamond[line][row]->getBomb());
      m_pDiamond[line][row]->setDisplayFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(
          Diamond::BombTypeStr[m_pDiamond[line][row]->getType()]));
      m_pDiamond[line][row]->setBomb(true);
      m_pDiamond[line][row]->runAction(Sequence::create(
                         DelayTime::create(1.5f), //1.5秒后把炸弹的贴图换回为宝石钻石
                         CallFuncN::create(this, callfuncN_selector(InGameScene::restoreBombToDiamondCallback)),
                         NULL));
    }
    void InGameScene::restoreBombToDiamondCallback(Node *pSender)
    {
      Diamond *p = (Diamond *)pSender;
      if (p)
      {
        p->setDisplayFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(Diamond::TypeStr[p->getType()]));
        p->setBomb(false);
      }
    }
    //-----------累积火球特效进度--START---------------//
    void InGameScene::runStepFireball(unsigned int count, bool reset)
    {
    //  if (m_pMagicProgress)
    //  {
    //    if (reset) //重新计数
    //    {
    //      m_nMagicCount = 0;
    //      m_pMagicProgress->runAction(CCProgressTo::create(0.1f, 0));
    //      return;
    //    }
    //
    //    unsigned int limit = InGameScene::limitFireball[InGameScene::level];
    //
    //    if (count > (limit - m_nMagicCount))
    //    {
    //      m_pMagicProgress->runAction(Sequence::create(
    //                      CCProgressTo::create(0.3f, 100.0f),
    //                      CCCallFunc::create(this, callfunc_selector(InGameScene::addFireballCallback)),//随机放置Magic宝石
    //                      CCProgressTo::create(0.1f, 0),
    //                      NULL));
    //      m_nMagicCount = 0;
    //    }
    //    else
    //    {
    //      m_nMagicCount += count;
    //      float percent = 100 * m_nMagicCount / limit;
    //      m_pMagicProgress->runAction(CCProgressTo::create(10 * (count / limit), percent));
    //    }
    //  }
    }
    void InGameScene::addFireballCallback()
    {
      int row = -1, line = -1;
      do
      {
        row = RANDOM_RANGE(0, m_nDiamondRowMax - 0.01);
        line = RANDOM_RANGE(0, m_nDiamondLineMax - 0.01);
      }
      while (m_pDiamond[line][row] == NULL || m_pDiamond[line][row]->getFireball());
      //一颗钻石在火焰中燃烧的动画
      Vector<SpriteFrame * >fireBallFrame;
      for (int i = 1; i < 9; ++i)
      {
        __String *str = __String::createWithFormat("diamond_fireball%d.png", i);
        SpriteFrame *p = SpriteFrameCache::getInstance()->getSpriteFrameByName(str->getCString());
        fireBallFrame.pushBack(p);
      }
      Animation *fireBallAnimation = Animation::createWithSpriteFrames(fireBallFrame, 0.05f);
      Animate *fireBallAnimate = Animate::create(fireBallAnimation);
      m_pDiamond[line][row]->setFireball(true);
      m_pDiamond[line][row]->runAction(Sequence::create(
                         CCRepeat::create(fireBallAnimate, 4), //宝石燃烧播放次数,大概一秒多的时间后恢复
                         CallFuncN::create(this, callfuncN_selector(InGameScene::removeFireballCallback)),
                         NULL));
    }
    void InGameScene::removeFireballCallback(Node *pSender)
    {
      Diamond *p = (Diamond *)pSender;
      if (p)
      {
        p->setFireball(false);
        p->setDisplayFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(Diamond::TypeStr[p->getType()]));
      }
    }
    //-----------累积火球特效进度--END---------------//
    //-----------播放火球掉落特效,并删除对应一列宝石-START------------//
    void InGameScene::playFireballAnimation(int line, int row)
    {
      m_nFireballline = m_nDiamondRowMax;
      m_nFireballRow = row;
      if (UserDefault::getInstance()->getBoolForKey("isEffectEnabled", false))
      {
        SimpleAudioEngine()->playEffect("sounds/Special_Event_fireball.ogg");
      }
      this->schedule(schedule_selector(InGameScene::removeLineDiamond), 0.06f);
      this->playFireballAnimation(m_pDiamond[line][row]);
    }
    //火球特效中,删除火球对应的一列宝石
    void InGameScene::removeLineDiamond(float delta)
    {
      if (m_pDiamond[m_nFireballline][m_nFireballRow])
      {
        m_pDiamondBatchNode->removeChild(m_pDiamond[m_nFireballline][m_nFireballRow], true);
        m_pDiamond[m_nFireballline][m_nFireballRow] = NULL;
      }
      if (--m_nFireballline == -1)
      {
        this->unschedule(schedule_selector(InGameScene::removeLineDiamond));
      }
    }
    //火球特效中,播放火球特效
    void InGameScene::playFireballAnimation(Diamond *diamond)
    {
      SpriteFrameCache::getInstance()->addSpriteFramesWithFile("effects/fireball0-800x_port_mdpi.plist");
      SpriteFrameCache::getInstance()->addSpriteFramesWithFile("effects/fireball1-800x_port_mdpi.plist");
      Vector<SpriteFrame *> fireballFrame;
      for (int i = 1; i < 17; ++i)
      {
        __String *fileName = __String::createWithFormat("fireball_down%d.png", i);
        SpriteFrame *p = SpriteFrameCache::getInstance()->getSpriteFrameByName(fileName->getCString());
        fireballFrame.pushBack(p);
      }
      auto animation = Animation::createWithSpriteFrames(fireballFrame, 0.06f);
      auto *fireball = Sprite::createWithSpriteFrameName("fireball_down1.png");
      fireball->setPosition(Vec2(diamond->getPositionX() + 35, 580));
      this->addChild(fireball);
      fireball->runAction(Sequence::create(
                  Animate::create(animation),
                  CallFuncN::create(this, callfuncN_selector(InGameScene::addRemovedDiamondCallback)),
                  NULL));
    }
    //火球特效中,特效结束后清理工作
    void InGameScene::addRemovedDiamondCallback(Node *pSender)
    {
      this->removeChild(pSender);
      this->schedule(schedule_selector(InGameScene::addRemovedDiamond), 1 / 40);
    }
    //-----------播放火球掉落特效,并删除对应一列宝石-END------------//
    //------------暂停按钮功能------------------//
    void InGameScene::menuPauseCallback(Ref *pSender)
    {
      InGameScene::isPaused = true;
      showAds(); //暂停游戏时显示广告
      //暂停时间更新
      //m_pTimerBar->stopAllActions();
      //m_pTimeLable->stopAllActions();
      this->unscheduleUpdate();
      //暂停时间更新
      this->unschedule(schedule_selector(InGameScene::updateTime));
      //弹出暂停框
      m_pPause = PauseLayer::create();
      m_pPause->retain();
      this->addChild(m_pPause);
      //启动暂停时间的更新函数,等待回复
      this->schedule(schedule_selector(InGameScene::updatePaused), 1 / 60);
    }
    //在暂停页面时,此函数等待恢复标志,并恢复相应效果
    void InGameScene::updatePaused(float delta)
    {
      if (! InGameScene::isPaused)
      {
        hideAds(); //结束暂停时,隐藏广告
        this->unschedule(schedule_selector(InGameScene::updatePaused));
        this->removeChild(m_pPause);
        CC_SAFE_RELEASE_NULL(m_pPause);
        InGameScene::level = UserDefault::getInstance()->getIntegerForKey("level");
        m_nDiamondCount = InGameScene::level + 3;
        //m_pTimerBar->runAction(MoveTo::create(float(m_nTime), Vec2(-380, 95)));
        this->scheduleUpdate();
        this->schedule(schedule_selector(InGameScene::updateTime), 1.0f);
      }
    }
    //------------暂停按钮功能-END-----------------//
    //-------------播放四周燃烧的火焰特效---------------//
    void InGameScene::playFireModeFlame()
    {
      SpriteFrameCache::getInstance()->addSpriteFramesWithFile("effects/firemode-800x_port_mdpi.plist");
      //down
      Vector<SpriteFrame *> animationFrame1;
      char str[64] = {0};
      for (int i = 1; i < 7; ++i)
      {
        sprintf(str, "firemodeFlameDown%d.png", i);
        SpriteFrame *p = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
        animationFrame1.pushBack(p);
      }
      Animation *animation1 = Animation::createWithSpriteFrames(animationFrame1, 0.12f);
      Sprite *p1 = Sprite::createWithSpriteFrameName("emptyPixelFireMode.png");
      p1->setAnchorPoint(Vec2(0.5f, .0f));
      p1->setPosition(Vec2(400, 0));
      p1->setTag(2001);
      this->addChild(p1);
      p1->runAction(RepeatForever::create(Animate::create(animation1)));
      //right
      Vector<SpriteFrame *> animationFrame2;
      for (int i = 1; i < 7; ++i)
      {
        sprintf(str, "firemodeFlameSide%d.png", i);
        auto *p = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
        animationFrame2.pushBack(p);
      }
      Animation *animation2 = Animation::createWithSpriteFrames(animationFrame2, 0.12f);
      Sprite *p2 = Sprite::createWithSpriteFrameName("emptyPixelFireMode.png");
      p2->setAnchorPoint(Vec2(1.0f, 0.5f));
      p2->setPosition(Vec2(800, 640));
      p2->setTag(2002);
      this->addChild(p2);
      p2->runAction(RepeatForever::create(Animate::create(animation2)));
      //left
      Vector<SpriteFrame *> animationFrame21;
      for (int i = 1; i < 7; ++i)
      {
        sprintf(str, "firemodeFlameSide%d.png", i);
        auto p = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
        animationFrame21.pushBack(p);
      }
      Animation *animation21 = Animation::createWithSpriteFrames(animationFrame21, 0.12f);
      Sprite *p21 = Sprite::createWithSpriteFrameName("emptyPixelFireMode.png");
      p21->setFlipX(true);
      p21->setAnchorPoint(Vec2(.0f, 0.5f));
      p21->setPosition(Vec2(0, 640));
      p21->setTag(2003);
      this->addChild(p21);
      p21->runAction(RepeatForever::create(Animate::create(animation21)));
      //top
      Vector<SpriteFrame *> animationFrame3;
      for (int i = 1; i < 9; ++i)
      {
        sprintf(str, "firemodeFlameTop%d.png", i);
        SpriteFrame *p = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
        animationFrame3.pushBack(p);
      }
      Animation *animation3 = Animation::createWithSpriteFrames(animationFrame3, 0.12f);
      Sprite *p3 = Sprite::createWithSpriteFrameName("emptyPixelFireMode.png");
      p3->setAnchorPoint(Vec2(0.5f, 1.0f));
      p3->setPosition(Vec2(400, 1280));
      p3->setTag(2004);
      this->addChild(p3);
      p3->runAction(RepeatForever::create(Animate::create(animation3)));
      //播放火燃烧音效
      unsigned int id = SimpleAudioEngine()->playEffect("sounds/Speed_Mode_atmosphere.ogg", true);
      m_pEffectDict->setObject(__String::createWithFormat("%d", id), "sounds/Speed_Mode_atmosphere");
    }
    void InGameScene::removeFireModeFlame()
    {
      //停止火燃烧音效
      unsigned int id = m_pEffectDict->valueForKey("sounds/Speed_Mode_atmosphere")->uintValue();
      SimpleAudioEngine()->stopEffect(id);
      this->removeChildByTag(2001);
      this->removeChildByTag(2002);
      this->removeChildByTag(2003);
      this->removeChildByTag(2004);
    }
    //-------------播放四周燃烧的火焰特效-END--------------//
    //-------------在双倍火焰模式时,点击宝石显示的"+2"贴图-------------//
    void InGameScene::displayDoubleScore()
    {
      SpriteFrameCache::getInstance()->addSpriteFramesWithFile("gems/gemTexture-800x_port_mdpi.plist");
      Sprite *doubleScore = Sprite::createWithSpriteFrameName("time_bonus.png");
      doubleScore->setPosition(Vec2(400, 750));
      this->addChild(doubleScore);
      doubleScore->setScale(0.3f);
      doubleScore->runAction(Sequence::create(
                    CCScaleTo::create(.5f, 1.5f),
                    DelayTime::create(.6f),
                    CallFuncN::create(this, callfuncN_selector(InGameScene::removeDoubleScoreCallback)),
                    NULL));
    }
    void InGameScene::removeDoubleScoreCallback(Node *pSender)
    {
      this->removeChild(pSender);
    }
    //-------------在双倍火焰模式时,点击宝石显示的"+2"贴图-END------------//

      相关内容
      最新更新
      热门排行榜