void Scheduler::addGrain(const Grain& g, int maxgrains) { int toMark = std::max(int(m_grains.size() - maxgrains), 0); int nth = 0; for (auto it = m_grains.begin(); it != m_grains.end() && nth < toMark; ++it) { ++nth; it->markRemove(); } m_grains.push_back(g); }
void GameLayer::markRemove(Monster *Monter) { if (Monter->getIsNeedRemove()) { return; } if (Monter->getIgnoreCheck()) { return; } // mark self Monter->setIsNeedRemove(true); // check for type and mark for certical neighbour if (Monter->getDisplayMode() == DISPLAY_MODE_VERTICAL) { for (int row = 0; row < m_height; row++) { Monster *tmp = m_matrix[row * m_width + Monter->getCol()]; if (!tmp || tmp == Monter) { continue; } if (tmp->getDisplayMode() == DISPLAY_MODE_NORMAL) { tmp->setIsNeedRemove(true); } else { markRemove(tmp); } } // check for type and mark for horizontal neighbour } else if (Monter->getDisplayMode() == DISPLAY_MODE_HORIZONTAL) { for (int col = 0; col < m_width; col++) { Monster *tmp = m_matrix[Monter->getRow() * m_width + col]; if (!tmp || tmp == Monter) { continue; } if (tmp->getDisplayMode() == DISPLAY_MODE_NORMAL) { tmp->setIsNeedRemove(true); } else { markRemove(tmp); } } } }
void PlayLayer::markRemove(SushiSprite *sushi) { if (sushi->getIsNeedRemove()) { return; } if (sushi->getIgnoreCheck()) { return; } // Set true sushi->setIsNeedRemove(true); // Các sushi loại sọc dọc if (sushi->getDisplayMode() == DISPLAY_MODE_VERTICAL) { for (int row = 0; row < m_height; row++) { SushiSprite *tmp = m_matrix[row * m_width + sushi->getCol()]; if (!tmp || tmp == sushi) { continue; //Bỏ qua loại sọc dọc } if (tmp->getDisplayMode() == DISPLAY_MODE_NORMAL) { tmp->setIsNeedRemove(true); // Đánh dấu loại Sushi thường } else { markRemove(tmp); // Đệ quy, } } // Các sushi loại sọc ngang, tương tự } else if (sushi->getDisplayMode() == DISPLAY_MODE_HORIZONTAL) { for (int col = 0; col < m_width; col++) { SushiSprite *tmp = m_matrix[sushi->getRow() * m_width + col]; if (!tmp || tmp == sushi) { continue; } if (tmp->getDisplayMode() == DISPLAY_MODE_NORMAL) { tmp->setIsNeedRemove(true); } else { markRemove(tmp); } } } }
void PlayLayer::checkAndRemoveChain() { SushiSprite *sushi; // Thiết lập cờ IgnoreCheck = false for (int i = 0; i < m_height * m_width; i++) { sushi = m_matrix[i]; if (!sushi) { continue; } sushi->setIgnoreCheck(false); } // 2. Kiểm lại for (int i = 0; i < m_height * m_width; i++) { sushi = m_matrix[i]; if (!sushi) { continue; } if (sushi->getIsNeedRemove()) { continue; // Bỏ qua Sushi đã gắn cờ "cần loại bỏ" } if (sushi->getIgnoreCheck()) { continue; // Bỏ qua Sushi đã gắn cờ "bỏ qua kiểm tra" } // Đếm cuỗi std::list<SushiSprite *> colChainList; getColChain(sushi, colChainList); std::list<SushiSprite *> rowChainList; getRowChain(sushi, rowChainList); std::list<SushiSprite *> &longerList = colChainList.size() > rowChainList.size() ? colChainList : rowChainList; if (longerList.size() < 3) { continue;// Bỏ qua } std::list<SushiSprite *>::iterator itList; bool isSetedIgnoreCheck = false; for (itList = longerList.begin(); itList != longerList.end(); itList++) { sushi = (SushiSprite *)*itList; if (!sushi) { continue; } if (longerList.size() > 3) { // Sushi đặc biệt khi chuỗi có 4 hoặc 5 Sushi if (sushi == m_srcSushi || sushi == m_destSushi) { isSetedIgnoreCheck = true; sushi->setIgnoreCheck(true); sushi->setIsNeedRemove(false); // Tùy theo hướng di chuyển mà tạo ra loại Sushi sọc dọc hay ngang sushi->setDisplayMode(m_movingVertical ? DISPLAY_MODE_VERTICAL : DISPLAY_MODE_HORIZONTAL); continue; } } markRemove(sushi); // Đánh dấu cần loại bỏ sushi } // Chuỗi đặc biệt, khi Sushi rơi, sinh ra tự nhiên if (!isSetedIgnoreCheck && longerList.size() > 3) { sushi->setIgnoreCheck(true); sushi->setIsNeedRemove(false); sushi->setDisplayMode(m_movingVertical ? DISPLAY_MODE_VERTICAL : DISPLAY_MODE_HORIZONTAL); } } // 3.Loại bỏ removeSushi(); }
void BallMap::checkAndRemoveChain() { BallSprite *ball; // 1. reset ingnore flag for (int i = 0; i < m_size.height * m_size.width; i++) { ball = m_matrix[i]; if (!ball) { continue; } ball->setIgnoreCheck(false); } // 2. check chain std::list<BallSprite *> longerList; for (int i = 0; i < m_size.height * m_size.width; i++) { ball = m_matrix[i]; if (!ball) { continue; } if (ball->getIsNeedRemove()) { continue;// 已标记过的跳过检查 } if (ball->getIgnoreCheck()) { // continue;// 新变化的特殊寿司,不消除 } // start count chain std::list<BallSprite *> colChainList; getColChain(ball, colChainList); if (colChainList.size() >= 3) { longerList.merge(colChainList); } std::list<BallSprite *> rowChainList; getRowChain(ball, rowChainList); if (rowChainList.size() >= 3) { longerList.merge(rowChainList); } if (longerList.size() < 3) { m_isNeedCheckSelf = false; TwoBallPos towBall = this->selfCheckHaveMore(); if (isPointEqual(towBall.srcPos, towBall.destPos)) { this->removeAllBall(true); } continue;// 小于3个不消除 } std::list<BallSprite *>::iterator itList; // longerList.sort(); //sort the list // longerList.erase( unique( longerList.begin(), longerList.end() ), longerList.end());//Remove duplicate list values for (itList = longerList.begin(); itList != longerList.end(); itList++) { ball = dynamic_cast<BallSprite*>(*itList); if (!ball) { continue; } markRemove(ball); } // 如何是自由掉落产生的4消, 取最后一个变化为特殊寿司 if (longerList.size() > 3) { ball->setIgnoreCheck(true); ball->setIsNeedRemove(false); ball->setDisplayMode(DISPLAY_MODE_FOUR); } } if (longerList.size() >= 3) { m_readyRemoveList = longerList; } // 3.消除标记了的寿司 removeBall(); }
/* bool BallMap::ccTouchBegan(CCTouch *touch, CCEvent *unused) { m_srcBall = NULL; m_destBall = NULL; if (m_isTouchEnable) { auto location = touch->getLocation(); m_srcBall = BallOfPoint(&location); } return m_isTouchEnable; } void BallMap::ccTouchMoved(CCTouch *touch, CCEvent *unused) { if (!m_srcBall || !m_isTouchEnable) { return; } int row = m_srcBall->getRow(); int col = m_srcBall->getCol(); auto location = touch->getLocation(); auto halfBallWidth = m_srcBall->getContentSize().width / 2; auto halfBallHeight = m_srcBall->getContentSize().height / 2; auto upRect = CCRect(m_srcBall->getPositionX() - halfBallWidth, m_srcBall->getPositionY() + halfBallHeight, m_srcBall->getContentSize().width, m_srcBall->getContentSize().height); if (upRect.containsPoint(location)) { row++; if (row < m_height) { m_destBall = m_matrix[row * m_width + col]; } m_movingVertical = true; swapBallAndCheck(); return; } auto downRect = CCRect(m_srcBall->getPositionX() - halfBallWidth, m_srcBall->getPositionY() - (halfBallHeight * 3), m_srcBall->getContentSize().width, m_srcBall->getContentSize().height); if (downRect.containsPoint(location)) { row--; if (row >= 0) { m_destBall = m_matrix[row * m_width + col]; } m_movingVertical = true; swapBallAndCheck(); return; } auto leftRect = CCRect(m_srcBall->getPositionX() - (halfBallWidth * 3), m_srcBall->getPositionY() - halfBallHeight, m_srcBall->getContentSize().width, m_srcBall->getContentSize().height); if (leftRect.containsPoint(location)) { col--; if (col >= 0) { m_destBall = m_matrix[row * m_width + col]; } m_movingVertical = false; swapBallAndCheck(); return; } auto rightRect = CCRect(m_srcBall->getPositionX() + halfBallWidth, m_srcBall->getPositionY() - halfBallHeight, m_srcBall->getContentSize().width, m_srcBall->getContentSize().height); if (rightRect.containsPoint(location)) { col++; if (col < m_width) { m_destBall = m_matrix[row * m_width + col]; } m_movingVertical = false; swapBallAndCheck(); return; } // not a useful movement } void BallMap::swapBallAndCheck() { m_isAnimationing = true; m_isTouchEnable = false; if (!m_srcBall || !m_destBall) { m_movingVertical = true; return; } CCPoint posOfSrc = m_srcBall->getPosition(); CCPoint posOfDest = m_destBall->getPosition(); float time = 0.2; // 1.swap in matrix this->swapBall(m_srcBall, m_destBall); // 2.check for remove able std::list<BallSprite *> colChainListOfFirst; getColChain(m_srcBall, colChainListOfFirst); std::list<BallSprite *> rowChainListOfFirst; getRowChain(m_srcBall, rowChainListOfFirst); std::list<BallSprite *> colChainListOfSecond; getColChain(m_destBall, colChainListOfSecond); std::list<BallSprite *> rowChainListOfSecond; getRowChain(m_destBall, rowChainListOfSecond); if (colChainListOfFirst.size() >= 3 || rowChainListOfFirst.size() >= 3 || colChainListOfSecond.size() >= 3 || rowChainListOfSecond.size() >= 3) { // just swap m_srcBall->runAction(CCMoveTo::create(time, posOfDest)); m_destBall->runAction(CCMoveTo::create(time, posOfSrc)); return; } // 3.no chain, swap back this->swapBall(m_srcBall, m_destBall); m_srcBall->runAction(CCSequence::create( CCMoveTo::create(time, posOfDest), CCMoveTo::create(time, posOfSrc), NULL)); m_destBall->runAction(CCSequence::create( CCMoveTo::create(time, posOfSrc), CCMoveTo::create(time, posOfDest), NULL)); } */ bool BallMap::swapBall(BallSprite* src, BallSprite* dest) { m_srcBall = src; m_destBall = dest; m_matrix[m_srcBall->getRow() * (int)m_size.width + m_srcBall->getCol()] = m_destBall; m_matrix[m_destBall->getRow() * (int)m_size.width + m_destBall->getCol()] = m_srcBall; int tmpRow = m_srcBall->getRow(); int tmpCol = m_srcBall->getCol(); m_srcBall->setRow(m_destBall->getRow()); m_srcBall->setCol(m_destBall->getCol()); m_destBall->setRow(tmpRow); m_destBall->setCol(tmpCol); // 2.check for remove able std::list<BallSprite *> colChainListOfFirst; this->getColChain(m_srcBall, colChainListOfFirst); std::list<BallSprite *> rowChainListOfFirst; this->getRowChain(m_srcBall, rowChainListOfFirst); std::list<BallSprite *> colChainListOfSecond; this->getColChain(m_destBall, colChainListOfSecond); std::list<BallSprite *> rowChainListOfSecond; this->getRowChain(m_destBall, rowChainListOfSecond); if (colChainListOfFirst.size() >= 3 || rowChainListOfFirst.size() >= 3 || colChainListOfSecond.size() >= 3 || rowChainListOfSecond.size() >= 3) { // just swap BallSprite* ball = NULL; std::list<BallSprite*> longerList; std::list<BallSprite*> newList; if (colChainListOfFirst.size()>=3) { longerList.merge(colChainListOfFirst); } if (rowChainListOfFirst.size()>=3) { longerList.merge(rowChainListOfFirst); } // 4消产生特殊元素 if (longerList.size() > 3) { m_srcBall->setIgnoreCheck(true); m_srcBall->setIsNeedRemove(false); m_srcBall->setDisplayMode(DISPLAY_MODE_FOUR); } if (colChainListOfSecond.size()>=3) { longerList.merge(colChainListOfSecond); newList.merge(colChainListOfSecond); } if (rowChainListOfSecond.size()>=3) { longerList.merge(rowChainListOfSecond); newList.merge(rowChainListOfSecond); } // 4消产生特殊元素 if (newList.size() > 3) { m_destBall->setIgnoreCheck(true); m_destBall->setIsNeedRemove(false); m_destBall->setDisplayMode(DISPLAY_MODE_FOUR); } for (std::list<BallSprite *>::iterator itList = longerList.begin(); itList != longerList.end(); itList++) { ball = dynamic_cast<BallSprite*>(*itList); if (!ball) { continue; } markRemove(ball); } // 3.消除标记了的寿司 if (longerList.size() >=3 ) { m_readyRemoveList = longerList; } ball->runAction(CCSequence::create(CCDelayTime::create(0.2f), CCCallFunc::create(this, callfunc_selector(BallMap::removeBall)), NULL)); return true; } m_matrix[m_srcBall->getRow() * (int)m_size.width + m_srcBall->getCol()] = m_destBall; m_matrix[m_destBall->getRow() * (int)m_size.width + m_destBall->getCol()] = m_srcBall; tmpRow = m_srcBall->getRow(); tmpCol = m_srcBall->getCol(); m_srcBall->setRow(m_destBall->getRow()); m_srcBall->setCol(m_destBall->getCol()); m_destBall->setRow(tmpRow); m_destBall->setCol(tmpCol); return false; }
void GameLayer::checkAndRemoveChain() { Monster *monster; // 1. reset ingnore flag for (int i = 0; i < m_height * m_width; i++) { monster = m_matrix[i]; if (!monster) { continue; } monster->setIgnoreCheck(false); } // 2. check chain for (int i = 0; i < m_height * m_width; i++) { monster = m_matrix[i]; if (!monster) { continue; } if (monster->getIsNeedRemove()) { continue;// 已标记过的跳过检查 } if (monster->getIgnoreCheck()) { continue;// 新变化的特殊monster,不消除 } // start count chain std::list<Monster *> colChainList; getColChain(monster, colChainList); std::list<Monster *> rowChainList; getRowChain(monster, rowChainList); std::list<Monster *> &longerList = colChainList.size() > rowChainList.size() ? colChainList : rowChainList; if (longerList.size() < 3) { continue;// 小于3个不消除 } countRemoveMonster = longerList.size(); std::list<Monster *>::iterator itList; bool isSetedIgnoreCheck = false; for (itList = longerList.begin(); itList != longerList.end(); itList++) { monster = (Monster *)*itList; if (!monster) { continue; } if (longerList.size() > 3) { if (monster == m_srcMonster || monster == m_destMonster) { isSetedIgnoreCheck = true; monster->setIgnoreCheck(true); //4消特殊元素先关闭 monster->setIsNeedRemove(true); //monster->setDisplayMode(m_movingVertical ? DISPLAY_MODE_VERTICAL : DISPLAY_MODE_HORIZONTAL); continue; } } markRemove(monster); } // 如何是自由掉落产生的4消, 取最后一个变化为特殊怪物 if (!isSetedIgnoreCheck && longerList.size() > 3) { monster->setIgnoreCheck(true); //4消特殊元素先关闭 monster->setIsNeedRemove(true); //monster->setDisplayMode(m_movingVertical ? DISPLAY_MODE_VERTICAL : DISPLAY_MODE_HORIZONTAL); } } // 3.消除标记了的怪物 removeMonster(); // 4.计算消除的分数 //计算消除得分 calculateScore(countRemoveMonster); }