Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android實現消水果游戲代碼分享

Android實現消水果游戲代碼分享

編輯:關於Android編程

消水果游戲大家都玩過吧,今天小編給大家分享實現消水果游戲的代碼,廢話不多說了,具體代碼如下所示:

 #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------------//

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved