首页 > 代码库 > Cocos2dx3.2 Crazy Tetris update 定时更新 游戏逻辑处理

Cocos2dx3.2 Crazy Tetris update 定时更新 游戏逻辑处理

现在,对于游戏的基本准备都已经做好,之后需要考虑的,就是游戏逻辑的处理,主要考虑一下几个方面:

判断方块是否已经落下停止,并下落新的方块;

方块落下后,判断是否符合消行条件,进行消行;

根据下落或者消行进行计分。

这些判断,需要定时处理,因此这里需要使用到默认更新的update

在初始化中,需要调用:

this->scheduleUpdate();

如果需要停止更新,可以调用:

this->unscheduleUpdate();

这样,就可以在void update(float delaty)函数中进行默认更新的处理。另外,还可以使用:

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)

同时,需要判断落下方块的位置,如果已经到达顶端,则game over

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分,每次消行,根据一次性消除的多少,计100200400800...分。

因此,在判断方块落下时,添加代码:

score += 10;

在消行成功时:

score = score + scoreBase * 100;

最终将更新的分数显示在得分栏:

char * scoreStringTemp = new char[256];
std::sprintf(&scoreStringTemp[0], "%d", score);
std::string scoreString = scoreStringTemp;
		
scoreLabel->setString(scoreString);

同时这里需要生成新的下落的方块:

//产生下一个方块
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)

Cocos2dx3.2 Crazy Tetris update 定时更新 游戏逻辑处理