现在,对于游戏的基本准备都已经做好,之后需要考虑的,就是游戏逻辑的处理,主要考虑一下几个方面:
1判断方块是否已经落下停止,并下落新的方块;
2方块落下后,判断是否符合消行条件,进行消行;
3根据下落或者消行进行计分。
这些判断,需要定时处理,因此这里需要使用到默认更新的update。
在初始化中,需要调用:
- this->scheduleUpdate();
如果需要停止更新,可以调用:
- this->unscheduleUpdate();
这样,就可以在voidupdate(floatdelaty)函数中进行默认更新的处理。另外,还可以使用:
- void schedule(cocos2d::SEL_SCHEDULE(my_update_func));
- void schedule(cocos2d::SEL_SCHEDULE(my_update_func),float interval);
- void schedule(cocos2d::SEL_SCHEDULE(my_update_func),float interval,unsigned int repeat,float delaty);
这三个重载函数可以调用自己定义的更新函数my_update_func,并且可以设置一些定时信息。
同样的,如果要取消可以使用:
- this->unschedule(cocos2d::SEL_SCHEDULE(my_update_func));
- this->scheduleOnce(cocos2d::SEL_SCHEDULE(my_update_func),float delaty);
开启update后,我们就可以在函数中进行我们的逻辑处理。
首先,是关于如何判断方块已经落下,我这里是判断其在连续的几次update中,y轴变化很微小,即判断其已经落下:
- if(std::fabs(currentBlock->getPositionY() - lastPositionY) <= 0.5f && times >= 80)
同时,需要判断落下方块的位置,如果已经到达顶端,则gameover:
- if(currentBlock->getPositionX() >= visibleSize.width/2 - 50 && currentBlock->getPositionX() <= visibleSize.width/2 + 50 && currentBlock->getPositionY() >=visibleSize.height/2 + 220)
- {
- auto newScene = GameOver::createScene(score);
- Director::getInstance()->replaceScene(CCTransitionFade::create(1.5,newScene));
- }
然后,是判断是否达到消行条件,如果达到消行条件,就应当进行消行处理:
- float yStart = visibleSize.height/2 - 250;
- for(int i=0; i<20; i++)
- {
- float area = 0;
- for(int j=0; j<blockSet->size(); j++)
- {
- BaseBlock * sprite = blockSet->at(j);
- area += sprite->calculaArea(yStart + 25*i,yStart + 25*(i+1));
- }
- if(area >= 6000)
- {
- Vector<BaseBlock *> * tempBlock = new Vector<BaseBlock *>();
- for(int k=0; k<blockSet->size(); k++)
- {
- BaseBlock * sprite = blockSet->at(k);
- Vector<BaseBlock *> * vecShapes = sprite->doubleLineCutting(yStart + 25*i,yStart + 25*(i+1));
- if(vecShapes != NULL)
- {
- if(vecShapes->size() == 1)
- {
- blockSet->erase(k);
- k--;
- this->removeChild(sprite);
- }
- else
- {
- blockSet->erase(k);
- k--;
- this->addChild(vecShapes->at(0),2);
- tempBlock->pushBack(vecShapes->at(0));
- this->addChild(vecShapes->at(1),2);
- tempBlock->pushBack(vecShapes->at(1));
- this->removeChild(sprite);
- }
- }
- }
- for(int k=0; k<tempBlock->size(); k++)
- {
- blockSet->pushBack(tempBlock->at(k));
- }
- if(scoreBase == 0) scoreBase = 1;
- else scoreBase *= 2;
- }
- }
最后,就是关于如何计分。我这里计分方式是,每次下落+10分,每次消行,根据一次性消除的多少,计100、200、400、800...分。
- score += 10;
在消行成功时:
最终将更新的分数显示在得分栏:
同时这里需要生成新的下落的方块:
- //产生下一个方块
- void GameView::buildNextBlock()
- {
- //TODO
- Size visibleSize = Director::getInstance()->getVisibleSize();
- Vec2 origin = Director::getInstance()->getVisibleOrigin();
- if(nextBlock == NULL)
- {
- currentBlock = randomBuildBlock();
- }
- else
- {
- currentBlock = nextBlock;
- }
- currentBlock->setPosition(origin.x + visibleSize.width/2,origin.y + visibleSize.height/2 + 220);
- currentBlock->getPhysicsBody()->setEnable(true);
- nextBlock = randomBuildBlock();
- nextBlock->setPosition(origin.x + 415,visibleSize.height/2 + 200);
- nextBlock->getPhysicsBody()->setEnable(false);
- }
关于制作游戏相关其他博客的目录,我放在 利用Cocos2dx3.2制作重力版俄罗斯方块(Crazy Tetris)