游戏写到这里,大家一定发现了些bug吧,我不知道你们发没发现,我在写的时候一直都有俩个小bug没有解决,为了让游戏完整一些,在移植android系统之前,就解决掉他们吧!第一个bug就是初始化游戏的时候,添加俩个随机的卡片,这俩个卡片的位置是从位置管理器中获得的,但是第一个卡片添加进去以后没有把这个坐标从坐标管理器中移除,导致了第二个卡片的位置和第一个重合,所以先来消除这个bug吧。我们把随机的添加俩个卡片放到一个单独的函数中去做,Chess的init函数去调用就行了。

void Chess::addRandomCube()
{
	CCSprite * randSprite_1 = this->m_cubeManager->addCubeToChess();
	//添加到棋盘中
	m_chess->addChild(randSprite_1);
	//这里修复一个小小的bug,在初始化设置卡片坐标的时候,坐标位置没有从位置管理器中移除掉,这里移除一下
	//下个卡片的位置就不会和上边的这个重合了,removePoint这个函数原来是私有的,需要在cubeManage中改为共有的
	CCPoint point = randSprite_1->getPosition();
	point = m_dealPoint.convertToLogicalPosition(point);
	this->m_cubeManager->removePoint(point);

	//使用同样的方法添加另一个2的格子
	CCSprite * randSprite_2 = this->m_cubeManager->addCubeToChess();
	m_chess->addChild(randSprite_2);
}

添加完了第一个卡片以后,把他的坐标从坐标管理器中移除,removePoint函数在cubeManager类中应该是公有的,这个函数的调用是俩个地方,一个是chess的初始化函数中,一个是数据的重置函数中。

void Chess::resetData(CCObject * obj)
{
	CCObject * object;
	//将卡片管理器中的卡片全部取出来然后remove掉
	CCARRAY_FOREACH(m_cubeManager->getCubeArray(),object)
	{
		CCSprite * cube = (CCSprite *)object;
		cube->removeFromParentAndCleanup(true);
	}
	//重置分数
	MyUILayer::sharedMyUILayer()->resetScore();
	MyUILayer::sharedMyUILayer()->setScore(0);

	//将卡片管理器中的卡片全部移除
	this->m_cubeManager->getCubeArray()->removeAllObjects();

	//重置坐标管理器中的坐标
	this->m_cubeManager->resetPoint();

	//在棋盘中添加俩个2的格子
	this->addRandomCube();
}

在数据的重置中,多了一个函数resetPoint,如果我们一直点击重新开始游戏的按钮但是坐标不重置的话可用的坐标就会越来越少,而实际上卡片就只是占用了俩个坐标位置,所以要重置下坐标,函数如下。不明白的看我的演示你就知道说的什么意思了。

//重置坐标管理器中的坐标
	void resetPoint(){m_pointManager->initPointArray();};

小塔1024——消除bug移植android 小塔1024——消除bug移植android
好了,接下来消除另一个bug吧!当玩家最后游戏结束的时候我们还没有处理,所以这里处理一下,弹出一个层,添加些分数,按钮之类的。那么怎么判断玩家游戏结束了呢,当那个随机出现的2没有可以出现的位置的时候就代表游戏结束了,好了,在chess中改改代码吧!

//事件监听的调用函数
void Chess::addCube(CCObject * obj)
{
	//这里是对玩家游戏结束的判断
	if(obj == NULL)
	{
		GameOver * gameOver = GameOver::create();
		this->getParent()->addChild(gameOver);
		return;
	}

	CCSprite * sprite = (CCSprite *)obj;
	this->m_chess->addChild(sprite);

	//添加卡片消除的声音
	int tag = sprite->getTag();
	//计算以2为底的对数,然后根据类型播放声音
	int type = (int)(log((float)tag)/log((float)2));
	SimpleAudioEngine::sharedEngine()->playEffect(m_audio->getEffect((EFFECT_TYPE)(type-1)));

	//添加抖动的效果
	CCJumpTo * jump = CCJumpTo::create(0.2f,sprite->getPosition(),30.0f,1);
	sprite->runAction(jump);
}

接下来就是GameOver类的实现了,代码比较简单,都是原来的知识!

#ifndef _GAME_OVER_H_
#define _GAME_OVER_H_
#include "cocos2d.h"
#include "MyUILayer.h"
#include "StartScene.h"

using namespace cocos2d;

//继承自CCLayerColor,做一下遮盖的效果
class GameOver : public CCLayerColor
{
public:
	bool init();
	CREATE_FUNC(GameOver);
	//触摸相关代码
	void registerWithTouchDispatcher();
	bool ccTouchBegan(CCTouch * touch,CCEvent * evt);
	//菜单的回调函数
	void retry(CCObject * obj);
	void home(CCObject * obj);
private:
	CCSize m_size;
};

#endif
#include "GameOver.h"

bool GameOver::init()
{
	if(!CCLayerColor::initWithColor(ccc4(100,100,100,200)))
	{
		return false;
	}

	m_size = CCDirector::sharedDirector()->getWinSize();

	//添加一些图片精灵
	CCSprite * background = CCSprite::create("over_bg.png");
	background->setPosition(ccp(m_size.width/2,m_size.height*0.6));
	this->addChild(background);

	CCSize size = background->getContentSize();

	CCSprite * sprite = CCSprite::create("over_best.png");
	sprite->setPosition(ccp(size.width/2,size.height*0.7));
	background->addChild(sprite);

	//添加文本信息
	CCLabelBMFont * text = CCLabelBMFont::create("GAME OVER","Bpreplay.fnt");
	text->setPosition(ccp(size.width/2,size.height*1.1));
	background->addChild(text);

	//获得当前的得分
	int score = MyUILayer::sharedMyUILayer()->getScore();
	CCString * score_str = CCString::createWithFormat("%d",score);
	CCLabelBMFont * score_text = CCLabelBMFont::create(score_str->getCString(),"Bpreplay.fnt");
	score_text->setPosition(ccp(size.width/2,size.height/2));
	background->addChild(score_text);

	//获得最高分
	int highscore = CCUserDefault::sharedUserDefault()->getIntegerForKey("0");
	CCString * highscore_str = CCString::createWithFormat("%d",highscore);
	CCLabelBMFont * highscore_text = CCLabelBMFont::create(highscore_str->getCString(),"Bpreplay.fnt");
	highscore_text->setPosition(ccp(size.width*0.58,size.height*0.15));
	background->addChild(highscore_text);

	//添加俩个菜单
	CCMenuItemImage * item1 = CCMenuItemImage::create("retry.png","retry.png",this,menu_selector(GameOver::retry));
	CCMenuItemImage * item2 = CCMenuItemImage::create("quit.png","quit.png",this,menu_selector(GameOver::home));
	CCMenu * menu = CCMenu::create(item1,item2,NULL);
	menu->alignItemsHorizontallyWithPadding(50);
	menu->setPosition(ccp(m_size.width/2,m_size.height*0.4));
	this->addChild(menu);

	//开启触摸,屏蔽下层的触摸
	this->setTouchEnabled(true);

	return true;
}

void GameOver::registerWithTouchDispatcher()
{
	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-128,true);
}

bool GameOver::ccTouchBegan(CCTouch * touch,CCEvent * evt)
{
	//直接吞噬掉触摸
	return true;
}

//以下俩个函数是对用户的响应,这里应该保存一下得分情况的,但是那个数据保存的类我没有单独做成一个类
//哎,后悔了啊,那就让这个bug永远bug吧
void GameOver::retry(CCObject * obj)
{
	this->removeFromParentAndCleanup(true);
	//发送重置数据的消息
	CCNotificationCenter::sharedNotificationCenter()->postNotification(MESSAGE_TYPE_RESET_DATA,NULL);
}

void GameOver::home(CCObject * obj)
{
	//返回到开始场景
	CCDirector::sharedDirector()->replaceScene(StartScene::scene());
}

小塔1024——消除bug移植android