欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现消水果游戏代码分享

程序员文章站 2024-02-29 18:01:40
消水果游戏大家都玩过吧,今天小编给大家分享实现消水果游戏的代码,废话不多说了,具体代码如下所示: #include "ingamescene.h" #incl...

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

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