***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************
别踩白块——第二篇
全文摘要
> 监听
> 整个游戏的逻辑
> 游戏结束
> 计时
别踩白块到这里算是一个分号了,
游戏整体逻辑已经交代清除,
但是还不够完善,之后我将完善它,就是说一定还会有第三篇滴~
********************************************************************转载请注明出处:http://blog.csdn.net/lttree*******************************************************************
1.监听
别踩白块 这个游戏,需要我们去触摸黑色的块,避免触摸白色的块,所以 触摸事件 必须执行。
我们已经有了 黑白块和开始行的显示了,
在监听器之前,我们要加一些其他的东西,
我们判断触碰的时候,要遍历所有的块,之前提到过,我们把所有块都放在一个Vector中,所以我们需要一个方法,将这个Vector取出来:
// Block.cpp // 获取所有的块 Vector<Block*> * Block::getBlocks(){ return Block::blocks; }
然后就可以加一个监听器,并实现它的逻辑
// HelloWorldScene.cpp bool HelloWorld::init() { if ( !Layer::init() ) { return false; } // 获取屏幕大小 visibleSize= Director::getInstance()->getVisibleSize(); // 开始游戏 startGame(); // 添加监听器 auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan= [this](Touch* t,Event* e){ auto bs = Block::getBlocks(); Block *b; for (auto it = bs->begin();it!=bs->end();it++) { b = *it; //游戏逻辑的实现 // 如果点击 if( b->getLineIndex()==1 && b->getBoundingBox().containsPoint(t->getLocation()) ) { if (b->getColor()==Color3B::BLACK) { // 触摸到黑色块,就让它变成灰色 b->setColor(Color3B::GRAY); } else { // 未触摸到该行黑色块,就提示 游戏失败 MessageBox("GameOver","失败"); } } } return false; }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this); return true; }
好的,运行一下,就可以发现在第一行,我们可以实现游戏逻辑啦~
********************************************************************转载请注明出处:http://blog.csdn.net/lttree*******************************************************************
2.整个游戏的逻辑
之前实现了第一行的逻辑,就是只能点黑块,不能点白块,
对于整个游戏来说,我们需要在点击正确时,所有的整体向下移动一行,最上面一行产生新的一行。
这些东西,我们要做一个 moveDown函数来实现,在点击黑块,颜色变成灰色以后执行:
// HelloWorldScene.cpp // 向下移动一行 void HelloWorld::moveDown(){ // 产生新的一行 addNormalLine(4); auto bs = Block::getBlocks(); //遍历所有方块,让方块向下移动,最下面的一行消除 for (auto it = bs->begin();it!=bs->end();it++) { (*it)->moveDown(); } }
向下移动,同时也在 Block类内,继续定义
// Block.cpp void Block::moveDown() { Size visibleSize = Director::getInstance()->getVisibleSize(); this->lineIndex--; //时间用0.1秒,移动到指定的位置(X方向不变,Y方向) runAction(Sequence::create(MoveTo::create(0.1f,Point(getPositionX(),lineIndex*visibleSize.height/4)), CallFunc::create([this](){ if (lineIndex<0) { this->removeBlock(); } }),NULL)); }
场景moveDown函数执行位置也知道了
这里还有最重要的一点,当我们找到所触摸的点时候,就不需要继续执行下去了,所以要加一个 break,一旦找到所触摸的块,无论是黑、是白、是灰,都不需要继续继续向下查找下去,所以最后加一个break,跳出循环。
运行一下,整个游戏的逻辑已经实现了。
********************************************************************转载请注明出处:http://blog.csdn.net/lttree*******************************************************************
3.游戏结束
本文的别踩白块同网上其他的一样,都是限制步数的,
就是 走50步,然后比谁的时间最短。
之前已经实现了,下移一行这些东西,
所以,需要做的就是,记录行数,全局变量 lineCount,
然后,在到第50行的时候的操作,
如果 已经显示了最后一行(全绿色界面),就无需动作,
如果 还没显示最后一行,需要显示新动作。
总结下来就这几个改动:
moveDown函数:
// HelloWorldScene.cpp // 向下移动一行 void HelloWorld::moveDown(){ if( lineCount < 50 ) { // 产生新的一行 addNormalLine(4); } else if( !isEnd ) { addEndLine(); isEnd = true; } auto bs = Block::getBlocks(); //遍历所有方块,让方块向下移动,最下面的一行消除 for (auto it = bs->begin();it!=bs->end();it++) { (*it)->moveDown(); } }
init函数:
// HelloWorldScene.cpp bool HelloWorld::init() { if ( !Layer::init() ) { return false; } // 获取屏幕大小 visibleSize= Director::getInstance()->getVisibleSize(); // 开始游戏 startGame(); // 添加监听器 auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan= [this](Touch* t,Event* e){ auto bs = Block::getBlocks(); Block *b; for (auto it = bs->begin();it!=bs->end();it++) { b = *it; //游戏逻辑的实现 // 如果点击 if( b->getLineIndex()==1 && b->getBoundingBox().containsPoint(t->getLocation()) ) { if (b->getColor()==Color3B::BLACK) { // 触摸到黑色块,就让它变成灰色 b->setColor(Color3B::GRAY); this->moveDown(); } else if( b->getColor()==Color3B::GREEN) { this->moveDown(); } else { // 未触摸到该行黑色块,就提示 游戏失败 MessageBox("GameOver","失败"); } break; } } return false; }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this); return true; }
然后,不要忘了在 startGame函数中,对 isEnd 和 lineCount进行初始化哟。
总算可以开始 和 结束,像一个游戏啦。
********************************************************************转载请注明出处:http://blog.csdn.net/lttree*******************************************************************
4.计时
明确一点先,我们的 块是移动的,但时间是固定位置不变的。
代表什么? 代表着两个不是在同一层,
所以我们可以分层操作,不需要两层,只需要将块放在游戏层,而时间这个Label直接在底层就行了
像这样:
// HelloWorldScene.cpp init函数 // 添加游戏层 gameLayer = Node::create(); addChild(gameLayer); // 添加时间 timerLabel = Label::create(); timerLabel ->setTextColor(Color4B::BLUE); timerLabel->setSystemFontSize(48); timerLabel->setPosition(visibleSize.width/2,visibleSize.height-100); addChild(timerLabel);
然后,对于时间,三个函数,开始、停止 和 更新
void HelloWorld::startTimer() { if (!isTimerRunning) { scheduleUpdate(); //获取到了clock的时间 startTime = clock(); isTimerRunning = true; } } void HelloWorld::stopTimer() { if (isTimerRunning) { unscheduleUpdate(); isTimerRunning = false; } } void HelloWorld::update( float dt ) { //时间的偏差 long offset = clock()-startTime; //强转offset为double类型 timerLabel->setString(StringUtils::format("%g",((double)offset)/1000)); }
然后在,触碰判断那,设定什么时候可以 startTimer ,什么时候需要 stopTimer
// HelloWorldScene.cpp init函数 监听器部分 // 添加监听器 auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan= [this](Touch* t,Event* e){ auto bs = Block::getBlocks(); Block *b; for (auto it = bs->begin();it!=bs->end();it++) { b = *it; //游戏逻辑的实现 // 如果点击 if( b->getLineIndex()==1 && b->getBoundingBox().containsPoint(t->getLocation()) ) { if (b->getColor()==Color3B::BLACK) { if (!isTimerRunning) { this->startTimer(); } // 触摸到黑色块,就让它变成灰色 b->setColor(Color3B::GRAY); this->moveDown(); } else if( b->getColor()==Color3B::GREEN) { this->moveDown(); this->stopTimer(); } else { // 未触摸到该行黑色块,就提示 游戏失败 MessageBox("GameOver","失败"); } break; } } return false; };
Ok,现在我们就可以进行计时了。
至此,简单的 别踩白块 完毕。
只是简单地做了一下,别踩白块
但是,这就结束了吗? NO!!
我肯定会继续修饰一下它,敬请期待吧~
本文源码: > 这里 <
***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************
原文:http://blog.csdn.net/lttree/article/details/43712717